use of org.identityconnectors.framework.common.objects.Name in project syncope by apache.
the class AbstractPropagationTaskExecutor method execute.
protected TaskExec execute(final PropagationTaskTO taskTO, final PropagationReporter reporter) {
PropagationTask task = entityFactory.newEntity(PropagationTask.class);
task.setResource(resourceDAO.find(taskTO.getResource()));
task.setObjectClassName(taskTO.getObjectClassName());
task.setAnyTypeKind(taskTO.getAnyTypeKind());
task.setAnyType(taskTO.getAnyType());
task.setEntityKey(taskTO.getEntityKey());
task.setOperation(taskTO.getOperation());
task.setConnObjectKey(taskTO.getConnObjectKey());
task.setOldConnObjectKey(taskTO.getOldConnObjectKey());
Set<Attribute> attributes = new HashSet<>();
if (StringUtils.isNotBlank(taskTO.getAttributes())) {
attributes.addAll(Arrays.asList(POJOHelper.deserialize(taskTO.getAttributes(), Attribute[].class)));
}
task.setAttributes(attributes);
List<PropagationActions> actions = getPropagationActions(task.getResource());
String resource = task.getResource().getKey();
Date start = new Date();
TaskExec execution = entityFactory.newEntity(TaskExec.class);
execution.setStatus(PropagationTaskExecStatus.CREATED.name());
String taskExecutionMessage = null;
String failureReason = null;
// Flag to state whether any propagation has been attempted
AtomicReference<Boolean> propagationAttempted = new AtomicReference<>(false);
ConnectorObject beforeObj = null;
ConnectorObject afterObj = null;
Provision provision = null;
OrgUnit orgUnit = null;
Uid uid = null;
Connector connector = null;
Result result;
try {
provision = task.getResource().getProvision(new ObjectClass(task.getObjectClassName())).orElse(null);
orgUnit = task.getResource().getOrgUnit();
connector = connFactory.getConnector(task.getResource());
// Try to read remote object BEFORE any actual operation
beforeObj = provision == null && orgUnit == null ? null : orgUnit == null ? getRemoteObject(task, connector, provision, false) : getRemoteObject(task, connector, orgUnit, false);
for (PropagationActions action : actions) {
action.before(task, beforeObj);
}
switch(task.getOperation()) {
case CREATE:
case UPDATE:
uid = createOrUpdate(task, beforeObj, connector, propagationAttempted);
break;
case DELETE:
uid = delete(task, beforeObj, connector, propagationAttempted);
break;
default:
}
execution.setStatus(propagationAttempted.get() ? PropagationTaskExecStatus.SUCCESS.name() : PropagationTaskExecStatus.NOT_ATTEMPTED.name());
LOG.debug("Successfully propagated to {}", task.getResource());
result = Result.SUCCESS;
} catch (Exception e) {
result = Result.FAILURE;
LOG.error("Exception during provision on resource " + resource, e);
if (e instanceof ConnectorException && e.getCause() != null) {
taskExecutionMessage = e.getCause().getMessage();
if (e.getCause().getMessage() == null) {
failureReason = e.getMessage();
} else {
failureReason = e.getMessage() + "\n\n Cause: " + e.getCause().getMessage().split("\n")[0];
}
} else {
taskExecutionMessage = ExceptionUtils2.getFullStackTrace(e);
if (e.getCause() == null) {
failureReason = e.getMessage();
} else {
failureReason = e.getMessage() + "\n\n Cause: " + e.getCause().getMessage().split("\n")[0];
}
}
try {
execution.setStatus(PropagationTaskExecStatus.FAILURE.name());
} catch (Exception wft) {
LOG.error("While executing KO action on {}", execution, wft);
}
propagationAttempted.set(true);
actions.forEach(action -> {
action.onError(task, execution, e);
});
} finally {
// Try to read remote object AFTER any actual operation
if (connector != null) {
if (uid != null) {
task.setConnObjectKey(uid.getUidValue());
}
try {
afterObj = provision == null && orgUnit == null ? null : orgUnit == null ? getRemoteObject(task, connector, provision, true) : getRemoteObject(task, connector, orgUnit, true);
} catch (Exception ignore) {
// ignore exception
LOG.error("Error retrieving after object", ignore);
}
}
if (task.getOperation() != ResourceOperation.DELETE && afterObj == null && uid != null) {
afterObj = new ConnectorObjectBuilder().setObjectClass(new ObjectClass(task.getObjectClassName())).setUid(uid).setName(AttributeUtil.getNameFromAttributes(task.getAttributes())).build();
}
execution.setStart(start);
execution.setMessage(taskExecutionMessage);
execution.setEnd(new Date());
LOG.debug("Execution finished: {}", execution);
if (hasToBeregistered(task, execution)) {
LOG.debug("Execution to be stored: {}", execution);
execution.setTask(task);
task.add(execution);
taskDAO.save(task);
// needed to generate a value for the execution key
taskDAO.flush();
}
if (reporter != null) {
reporter.onSuccessOrNonPriorityResourceFailures(taskTO, PropagationTaskExecStatus.valueOf(execution.getStatus()), failureReason, beforeObj, afterObj);
}
}
for (PropagationActions action : actions) {
action.after(task, execution, afterObj);
}
// SYNCOPE-1136
String anyTypeKind = task.getAnyTypeKind() == null ? "realm" : task.getAnyTypeKind().name().toLowerCase();
String operation = task.getOperation().name().toLowerCase();
boolean notificationsAvailable = notificationManager.notificationsAvailable(AuditElements.EventCategoryType.PROPAGATION, anyTypeKind, resource, operation);
boolean auditRequested = auditManager.auditRequested(AuditElements.EventCategoryType.PROPAGATION, anyTypeKind, resource, operation);
if (notificationsAvailable || auditRequested) {
ExecTO execTO = taskDataBinder.getExecTO(execution);
notificationManager.createTasks(AuditElements.EventCategoryType.PROPAGATION, anyTypeKind, resource, operation, result, beforeObj, new Object[] { execTO, afterObj }, taskTO);
auditManager.audit(AuditElements.EventCategoryType.PROPAGATION, anyTypeKind, resource, operation, result, beforeObj, new Object[] { execTO, afterObj }, taskTO);
}
return execution;
}
use of org.identityconnectors.framework.common.objects.Name in project syncope by apache.
the class AbstractPropagationTaskExecutor method createOrUpdate.
protected Uid createOrUpdate(final PropagationTask task, final ConnectorObject beforeObj, final Connector connector, final AtomicReference<Boolean> propagationAttempted) {
// set of attributes to be propagated
Set<Attribute> attributes = new HashSet<>(task.getAttributes());
// check if there is any missing or null / empty mandatory attribute
Set<Object> mandatoryAttrNames = new HashSet<>();
Attribute mandatoryMissing = AttributeUtil.find(MANDATORY_MISSING_ATTR_NAME, task.getAttributes());
if (mandatoryMissing != null) {
attributes.remove(mandatoryMissing);
if (beforeObj == null) {
mandatoryAttrNames.addAll(mandatoryMissing.getValue());
}
}
Attribute mandatoryNullOrEmpty = AttributeUtil.find(MANDATORY_NULL_OR_EMPTY_ATTR_NAME, task.getAttributes());
if (mandatoryNullOrEmpty != null) {
attributes.remove(mandatoryNullOrEmpty);
mandatoryAttrNames.addAll(mandatoryNullOrEmpty.getValue());
}
if (!mandatoryAttrNames.isEmpty()) {
throw new IllegalArgumentException("Not attempted because there are mandatory attributes without value(s): " + mandatoryAttrNames);
}
Uid result;
if (beforeObj == null) {
LOG.debug("Create {} on {}", attributes, task.getResource().getKey());
result = connector.create(new ObjectClass(task.getObjectClassName()), attributes, null, propagationAttempted);
} else {
// 1. check if rename is really required
Name newName = AttributeUtil.getNameFromAttributes(attributes);
LOG.debug("Rename required with value {}", newName);
if (newName != null && newName.equals(beforeObj.getName()) && !newName.getNameValue().equals(beforeObj.getUid().getUidValue())) {
LOG.debug("Remote object name unchanged");
attributes.remove(newName);
}
// 2. check wether anything is actually needing to be propagated, i.e. if there is attribute
// difference between beforeObj - just read above from the connector - and the values to be propagated
Map<String, Attribute> originalAttrMap = beforeObj.getAttributes().stream().collect(Collectors.toMap(attr -> attr.getName().toUpperCase(), attr -> attr));
Map<String, Attribute> updateAttrMap = attributes.stream().collect(Collectors.toMap(attr -> attr.getName().toUpperCase(), attr -> attr));
// Only compare attribute from beforeObj that are also being updated
Set<String> skipAttrNames = originalAttrMap.keySet();
skipAttrNames.removeAll(updateAttrMap.keySet());
new HashSet<>(skipAttrNames).forEach(attrName -> {
originalAttrMap.remove(attrName);
});
Set<Attribute> originalAttrs = new HashSet<>(originalAttrMap.values());
if (originalAttrs.equals(attributes)) {
LOG.debug("Don't need to propagate anything: {} is equal to {}", originalAttrs, attributes);
result = AttributeUtil.getUidAttribute(attributes);
} else {
LOG.debug("Attributes that would be updated {}", attributes);
Set<Attribute> strictlyModified = new HashSet<>();
attributes.stream().filter(attr -> (!originalAttrs.contains(attr))).forEachOrdered(attr -> {
strictlyModified.add(attr);
});
// 3. provision entry
LOG.debug("Update {} on {}", strictlyModified, task.getResource().getKey());
result = connector.update(beforeObj.getObjectClass(), new Uid(beforeObj.getUid().getUidValue()), strictlyModified, null, propagationAttempted);
}
}
return result;
}
use of org.identityconnectors.framework.common.objects.Name in project syncope by apache.
the class AttributeDeserializer method deserialize.
@Override
public Attribute deserialize(final JsonParser jp, final DeserializationContext ctx) throws IOException {
ObjectNode tree = jp.readValueAsTree();
String name = tree.get("name").asText();
List<Object> values = new ArrayList<>();
for (JsonNode node : tree.get("value")) {
if (node.isNull()) {
values.add(null);
} else if (node.isObject()) {
values.add(((ObjectNode) node).traverse(jp.getCodec()).readValueAs(GuardedString.class));
} else if (node.isBoolean()) {
values.add(node.asBoolean());
} else if (node.isDouble()) {
values.add(node.asDouble());
} else if (node.isLong()) {
values.add(node.asLong());
} else if (node.isInt()) {
values.add(node.asInt());
} else {
String text = node.asText();
if (text.startsWith(AttributeSerializer.BYTE_ARRAY_PREFIX) && text.endsWith(AttributeSerializer.BYTE_ARRAY_SUFFIX)) {
values.add(Base64.getDecoder().decode(StringUtils.substringBetween(text, AttributeSerializer.BYTE_ARRAY_PREFIX, AttributeSerializer.BYTE_ARRAY_SUFFIX)));
} else {
values.add(text);
}
}
}
return Uid.NAME.equals(name) ? new Uid(values.isEmpty() || values.get(0) == null ? null : values.get(0).toString()) : Name.NAME.equals(name) ? new Name(values.isEmpty() || values.get(0) == null ? null : values.get(0).toString()) : AttributeBuilder.build(name, values);
}
use of org.identityconnectors.framework.common.objects.Name in project CzechIdMng by bcvsolutions.
the class DefaultVsSystemService method updateFormDefinition.
/**
* Create/Update form definition and attributes
*
* @param key
* @param type
* @param system
* @param virtualConfiguration
* @return
*/
private IdmFormDefinitionDto updateFormDefinition(String key, String type, SysSystemDto system, BasicVirtualConfiguration virtualConfiguration) {
IdmFormDefinitionDto definition = this.formService.getDefinition(type, key);
List<IdmFormAttributeDto> newFormAttributes = new ArrayList<>();
for (String virtualAttribute : virtualConfiguration.getAttributes()) {
IdmFormAttributeDto formAttribute = formAttributeService.findAttribute(type, key, virtualAttribute);
if (formAttribute == null) {
formAttribute = createFromAttribute(virtualAttribute);
formAttribute.setFormDefinition(definition == null ? null : definition.getId());
newFormAttributes.add(formAttribute);
}
}
String definitionName = MessageFormat.format("Virtual system for [{0}]", system.getName());
if (definition == null) {
IdmFormDefinitionDto createdDefinition = this.formService.createDefinition(type, key, VirtualSystemModuleDescriptor.MODULE_ID, newFormAttributes);
createdDefinition.setName(definitionName);
createdDefinition.setUnmodifiable(true);
return this.formService.saveDefinition(createdDefinition);
} else {
// update form definition name, if needed
if (!definition.getName().equals(definitionName)) {
definition.setName(definitionName);
definition = formService.saveDefinition(definition);
}
newFormAttributes.forEach(formAttribute -> {
this.formService.saveAttribute(formAttribute);
});
// delete VS form attributes which are not defined in the connector attribute list
IdmFormDefinitionDto connectorFormDefinition = systemService.getConnectorFormDefinition(system);
Set<String> vsAttributeNames = formService.getValues(system, connectorFormDefinition, ATTRIBUTES_PROPERTY).stream().map(IdmFormValueDto::getStringValue).collect(Collectors.toSet());
if (!vsAttributeNames.isEmpty()) {
formService.getAttributes(definition).stream().filter(attr -> !vsAttributeNames.contains(attr.getCode())).forEach(attr -> formService.deleteAttribute(attr));
}
return definition;
}
}
use of org.identityconnectors.framework.common.objects.Name in project syncope by apache.
the class AzurePropagationActions method setName.
private void setName(final PropagationTask task, final String attributeName) {
Set<Attribute> attributes = new HashSet<>(task.getAttributes());
if (AttributeUtil.find(attributeName, attributes) == null) {
LOG.warn("Can't find {} attribute to set as __NAME__ attribute value, skipping...", attributeName);
return;
}
Name name = AttributeUtil.getNameFromAttributes(attributes);
if (name != null) {
attributes.remove(name);
}
attributes.add(new Name(AttributeUtil.find(attributeName, attributes).getValue().get(0).toString()));
task.setAttributes(attributes);
}
Aggregations