in core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ResourceDataBinderImpl.java [119:363]
public ExternalResource update(final ExternalResource resource, final ResourceTO resourceTO) {
resource.setKey(resourceTO.getKey());
if (resourceTO.getConnector() != null) {
ConnInstance connector = connInstanceDAO.findById(resourceTO.getConnector()).
orElseThrow(() -> new NotFoundException("ConnInstance " + resourceTO.getConnector()));
resource.setConnector(connector);
if (!connector.getResources().contains(resource)) {
connector.add(resource);
}
}
resource.setEnforceMandatoryCondition(resourceTO.isEnforceMandatoryCondition());
resource.setPropagationPriority(resourceTO.getPropagationPriority());
// 1. add or update all (valid) provisions from TO
resourceTO.getProvisions().forEach(provisionTO -> {
AnyType anyType = anyTypeDAO.findById(provisionTO.getAnyType()).orElse(null);
if (anyType == null) {
LOG.debug("Invalid {} specified {}, ignoring...",
AnyType.class.getSimpleName(), provisionTO.getAnyType());
} else {
Provision provision = resource.getProvisionByAnyType(anyType.getKey()).orElseGet(() -> {
Provision p = new Provision();
p.setAnyType(anyType.getKey());
resource.getProvisions().add(p);
return p;
});
if (provisionTO.getObjectClass() == null) {
SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidProvision);
sce.getElements().add("Null " + ObjectClass.class.getSimpleName());
throw sce;
}
provision.setObjectClass(provisionTO.getObjectClass());
// add all classes contained in the TO
for (String name : provisionTO.getAuxClasses()) {
AnyTypeClass anyTypeClass = anyTypeClassDAO.findById(name).orElse(null);
if (anyTypeClass == null || provision.getAuxClasses().contains(name)) {
LOG.warn("Ignoring invalid or already present {}: {}",
AnyTypeClass.class.getSimpleName(), name);
} else {
provision.getAuxClasses().add(anyTypeClass.getKey());
}
}
// remove all classes not contained in the TO
provision.getAuxClasses().
removeIf(anyTypeClass -> !provisionTO.getAuxClasses().contains(anyTypeClass));
provision.setIgnoreCaseMatch(provisionTO.isIgnoreCaseMatch());
if (StringUtils.isBlank(provisionTO.getUidOnCreate())) {
provision.setUidOnCreate(null);
} else {
PlainSchema uidOnCreate = plainSchemaDAO.findById(provisionTO.getUidOnCreate()).orElse(null);
if (uidOnCreate == null) {
LOG.warn("Ignoring invalid schema for uidOnCreate: {}", provisionTO.getUidOnCreate());
provision.setUidOnCreate(null);
} else {
provision.setUidOnCreate(uidOnCreate.getKey());
}
}
if (provisionTO.getMapping() == null) {
provision.setMapping(null);
} else {
Mapping mapping = provision.getMapping();
if (mapping == null) {
mapping = new Mapping();
provision.setMapping(mapping);
} else {
mapping.getItems().clear();
}
AnyTypeClassTO allowedSchemas = new AnyTypeClassTO();
Stream.concat(
anyType.getClasses().stream(),
provision.getAuxClasses().stream().map(anyTypeClassDAO::findById).
flatMap(Optional::stream)).forEach(anyTypeClass -> {
allowedSchemas.getPlainSchemas().addAll(anyTypeClass.getPlainSchemas().stream().
map(PlainSchema::getKey).toList());
allowedSchemas.getDerSchemas().addAll(anyTypeClass.getDerSchemas().stream().
map(DerSchema::getKey).toList());
});
populateMapping(
resource,
provisionTO.getMapping(),
mapping,
anyType.getKind(),
allowedSchemas);
}
}
});
// 2. remove all provisions not contained in the TO
for (Iterator<Provision> itor = resource.getProvisions().iterator(); itor.hasNext();) {
Provision provision = itor.next();
if (resourceTO.getProvision(provision.getAnyType()).isEmpty()) {
itor.remove();
}
}
// 3. orgUnit
if (resourceTO.getOrgUnit() == null && resource.getOrgUnit() != null) {
resource.setOrgUnit(null);
} else if (resourceTO.getOrgUnit() != null) {
OrgUnit orgUnitTO = resourceTO.getOrgUnit();
OrgUnit orgUnit = Optional.ofNullable(resource.getOrgUnit()).orElseGet(OrgUnit::new);
if (orgUnitTO.getObjectClass() == null) {
SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidOrgUnit);
sce.getElements().add("Null " + ObjectClass.class.getSimpleName());
throw sce;
}
orgUnit.setObjectClass(orgUnitTO.getObjectClass());
orgUnit.setIgnoreCaseMatch(orgUnitTO.isIgnoreCaseMatch());
if (orgUnitTO.getConnObjectLink() == null) {
SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidOrgUnit);
sce.getElements().add("Null connObjectLink");
throw sce;
}
orgUnit.setConnObjectLink(orgUnitTO.getConnObjectLink());
SyncopeClientCompositeException scce = SyncopeClientException.buildComposite();
SyncopeClientException invalidMapping = SyncopeClientException.build(
ClientExceptionType.InvalidMapping);
SyncopeClientException requiredValuesMissing = SyncopeClientException.build(
ClientExceptionType.RequiredValuesMissing);
orgUnit.getItems().clear();
for (Item itemTO : orgUnitTO.getItems()) {
if (itemTO == null) {
LOG.error("Null {}", Item.class.getSimpleName());
invalidMapping.getElements().add("Null " + Item.class.getSimpleName());
} else if (itemTO.getIntAttrName() == null) {
requiredValuesMissing.getElements().add("intAttrName");
scce.addException(requiredValuesMissing);
} else {
if (!"name".equals(itemTO.getIntAttrName()) && !"fullpath".equals(itemTO.getIntAttrName())) {
LOG.error("Only 'name' and 'fullpath' are supported for Realms");
invalidMapping.getElements().add("Only 'name' and 'fullpath' are supported for Realms");
} else {
// no mandatory condition implies mandatory condition false
if (!JexlUtils.isExpressionValid(itemTO.getMandatoryCondition() == null
? "false" : itemTO.getMandatoryCondition())) {
SyncopeClientException invalidMandatoryCondition = SyncopeClientException.build(
ClientExceptionType.InvalidValues);
invalidMandatoryCondition.getElements().add(itemTO.getMandatoryCondition());
scce.addException(invalidMandatoryCondition);
}
Item item = new Item();
item.setIntAttrName(itemTO.getIntAttrName());
item.setExtAttrName(itemTO.getExtAttrName());
item.setPurpose(itemTO.getPurpose());
item.setMandatoryCondition(itemTO.getMandatoryCondition());
item.setConnObjectKey(itemTO.isConnObjectKey());
item.setPassword(itemTO.isPassword());
item.setPropagationJEXLTransformer(itemTO.getPropagationJEXLTransformer());
item.setPullJEXLTransformer(itemTO.getPullJEXLTransformer());
itemTO.getTransformers().forEach(key -> implementationDAO.findById(key).ifPresentOrElse(
transformer -> item.getTransformers().add(transformer.getKey()),
() -> LOG.debug("Invalid {} {}, ignoring...",
Implementation.class.getSimpleName(), key)));
// remove all implementations not contained in the TO
item.getTransformers().
removeIf(implementation -> !itemTO.getTransformers().contains(implementation));
if (item.isConnObjectKey()) {
orgUnit.setConnObjectKeyItem(item);
} else {
orgUnit.add(item);
}
}
}
}
if (!invalidMapping.getElements().isEmpty()) {
scce.addException(invalidMapping);
}
if (scce.hasExceptions()) {
throw scce;
}
resource.setOrgUnit(orgUnit);
}
resource.setCreateTraceLevel(resourceTO.getCreateTraceLevel());
resource.setUpdateTraceLevel(resourceTO.getUpdateTraceLevel());
resource.setDeleteTraceLevel(resourceTO.getDeleteTraceLevel());
resource.setProvisioningTraceLevel(resourceTO.getProvisioningTraceLevel());
resource.setPasswordPolicy(resourceTO.getPasswordPolicy() == null
? null : policyDAO.findById(resourceTO.getPasswordPolicy(), PasswordPolicy.class).orElse(null));
resource.setAccountPolicy(resourceTO.getAccountPolicy() == null
? null : policyDAO.findById(resourceTO.getAccountPolicy(), AccountPolicy.class).orElse(null));
if (resource.getPropagationPolicy() != null
&& !resource.getPropagationPolicy().getKey().equals(resourceTO.getPropagationPolicy())) {
propagationTaskExecutor.expireRetryTemplate(resource.getKey());
}
resource.setPropagationPolicy(resourceTO.getPropagationPolicy() == null
? null : policyDAO.findById(resourceTO.getPropagationPolicy(), PropagationPolicy.class).orElse(null));
resource.setInboundPolicy(resourceTO.getInboundPolicy() == null
? null : policyDAO.findById(resourceTO.getInboundPolicy(), InboundPolicy.class).orElse(null));
resource.setPushPolicy(resourceTO.getPushPolicy() == null
? null : policyDAO.findById(resourceTO.getPushPolicy(), PushPolicy.class).orElse(null));
if (resourceTO.getProvisionSorter() == null) {
resource.setProvisionSorter(null);
} else {
implementationDAO.findById(resourceTO.getProvisionSorter()).ifPresentOrElse(
resource::setProvisionSorter,
() -> LOG.debug("Invalid {} {}, ignoring...",
Implementation.class.getSimpleName(), resourceTO.getProvisionSorter()));
}
resource.setConfOverride(
Optional.ofNullable(resourceTO.getConfOverride()).orElseGet(Optional::empty));
resource.setCapabilitiesOverride(
Optional.ofNullable(resourceTO.getCapabilitiesOverride()).orElseGet(Optional::empty));
resourceTO.getPropagationActions().forEach(key -> implementationDAO.findById(key).ifPresentOrElse(
resource::add,
() -> LOG.debug("Invalid {} {}, ignoring...", Implementation.class.getSimpleName(), key)));
// remove all implementations not contained in the TO
resource.getPropagationActions().
removeIf(propActions -> !resourceTO.getPropagationActions().contains(propActions.getKey()));
return resource;
}