use of com.evolveum.midpoint.common.refinery.RefinedObjectClassDefinition in project midpoint by Evolveum.
the class ShadowManager method updateShadow.
/**
* Updates repository shadow based on shadow from resource. Handles rename cases,
* change of auxiliary object classes, etc.
* @returns repository shadow as it should look like after the update
*/
@SuppressWarnings("unchecked")
public PrismObject<ShadowType> updateShadow(ProvisioningContext ctx, PrismObject<ShadowType> currentResourceShadow, PrismObject<ShadowType> oldRepoShadow, OperationResult parentResult) throws SchemaException, ObjectNotFoundException, ObjectAlreadyExistsException, ConfigurationException, CommunicationException, ExpressionEvaluationException {
RefinedObjectClassDefinition ocDef = ctx.computeCompositeObjectClassDefinition(currentResourceShadow);
ObjectDelta<ShadowType> shadowDelta = oldRepoShadow.createModifyDelta();
PrismContainer<Containerable> currentResourceAttributesContainer = currentResourceShadow.findContainer(ShadowType.F_ATTRIBUTES);
PrismContainer<Containerable> oldRepoAttributesContainer = oldRepoShadow.findContainer(ShadowType.F_ATTRIBUTES);
ShadowType oldRepoShadowType = oldRepoShadow.asObjectable();
ShadowType currentResourceShadowType = currentResourceShadow.asObjectable();
if (oldRepoShadowType.isExists() != currentResourceShadowType.isExists()) {
// Resource object obviously exists when we have got here
shadowDelta.addModificationReplaceProperty(ShadowType.F_EXISTS, currentResourceShadowType.isExists());
}
CachingStategyType cachingStrategy = ProvisioningUtil.getCachingStrategy(ctx);
for (Item<?, ?> currentResourceItem : currentResourceAttributesContainer.getValue().getItems()) {
if (currentResourceItem instanceof PrismProperty<?>) {
PrismProperty<?> currentResourceAttrProperty = (PrismProperty<?>) currentResourceItem;
RefinedAttributeDefinition<Object> attrDef = ocDef.findAttributeDefinition(currentResourceAttrProperty.getElementName());
if (ProvisioningUtil.shouldStoreAtributeInShadow(ocDef, attrDef.getName(), cachingStrategy)) {
MatchingRule matchingRule = matchingRuleRegistry.getMatchingRule(attrDef.getMatchingRuleQName(), attrDef.getTypeName());
PrismProperty<Object> oldRepoAttributeProperty = oldRepoAttributesContainer.findProperty(currentResourceAttrProperty.getElementName());
if (oldRepoAttributeProperty == null) {
PropertyDelta<?> attrAddDelta = currentResourceAttrProperty.createDelta();
for (PrismPropertyValue pval : currentResourceAttrProperty.getValues()) {
Object normalizedRealValue;
if (matchingRule == null) {
normalizedRealValue = pval.getValue();
} else {
normalizedRealValue = matchingRule.normalize(pval.getValue());
}
attrAddDelta.addValueToAdd(new PrismPropertyValue(normalizedRealValue));
LOGGER.trace("CURRENT ATTR:\n{}\nATTR DELTA:\n{}", currentResourceAttrProperty.debugDump(1), attrAddDelta.debugDump(1));
}
shadowDelta.addModification(attrAddDelta);
} else {
if (attrDef.isSingleValue()) {
Object currentResourceRealValue = currentResourceAttrProperty.getRealValue();
Object currentResourceNormalizedRealValue;
if (matchingRule == null) {
currentResourceNormalizedRealValue = currentResourceRealValue;
} else {
currentResourceNormalizedRealValue = matchingRule.normalize(currentResourceRealValue);
}
if (!currentResourceNormalizedRealValue.equals(oldRepoAttributeProperty.getRealValue())) {
LOGGER.trace("CURRENT ATTR:\n{}\ncurrentResourceNormalizedRealValue: {}", currentResourceAttrProperty.debugDump(1), currentResourceNormalizedRealValue);
shadowDelta.addModificationReplaceProperty(currentResourceAttrProperty.getPath(), currentResourceNormalizedRealValue);
}
} else {
PrismProperty<Object> normalizedCurrentResourceAttrProperty = (PrismProperty<Object>) currentResourceAttrProperty.clone();
if (matchingRule != null) {
for (PrismPropertyValue pval : normalizedCurrentResourceAttrProperty.getValues()) {
Object normalizedRealValue = matchingRule.normalize(pval.getValue());
pval.setValue(normalizedRealValue);
}
}
PropertyDelta<Object> attrDiff = oldRepoAttributeProperty.diff(normalizedCurrentResourceAttrProperty);
LOGGER.trace("DIFF:\n{}\n-\n{}\n=:\n{}", oldRepoAttributeProperty == null ? null : oldRepoAttributeProperty.debugDump(1), normalizedCurrentResourceAttrProperty == null ? null : normalizedCurrentResourceAttrProperty.debugDump(1), attrDiff == null ? null : attrDiff.debugDump(1));
if (attrDiff != null && !attrDiff.isEmpty()) {
attrDiff.setParentPath(new ItemPath(ShadowType.F_ATTRIBUTES));
shadowDelta.addModification(attrDiff);
}
}
}
}
}
}
for (Item<?, ?> oldRepoItem : oldRepoAttributesContainer.getValue().getItems()) {
if (oldRepoItem instanceof PrismProperty<?>) {
PrismProperty<?> oldRepoAttrProperty = (PrismProperty<?>) oldRepoItem;
RefinedAttributeDefinition<Object> attrDef = ocDef.findAttributeDefinition(oldRepoAttrProperty.getElementName());
PrismProperty<Object> currentAttribute = currentResourceAttributesContainer.findProperty(oldRepoAttrProperty.getElementName());
if (attrDef == null || !ProvisioningUtil.shouldStoreAtributeInShadow(ocDef, attrDef.getName(), cachingStrategy) || currentAttribute == null) {
// No definition for this property it should not be there or no current value: remove it from the shadow
PropertyDelta<?> oldRepoAttrPropDelta = oldRepoAttrProperty.createDelta();
oldRepoAttrPropDelta.addValuesToDelete((Collection) PrismPropertyValue.cloneCollection(oldRepoAttrProperty.getValues()));
shadowDelta.addModification(oldRepoAttrPropDelta);
}
}
}
PolyString currentShadowName = ShadowUtil.determineShadowName(currentResourceShadow);
PolyString oldRepoShadowName = oldRepoShadow.getName();
if (!currentShadowName.equalsOriginalValue(oldRepoShadowName)) {
PropertyDelta<?> shadowNameDelta = PropertyDelta.createModificationReplaceProperty(ShadowType.F_NAME, oldRepoShadow.getDefinition(), currentShadowName);
shadowDelta.addModification(shadowNameDelta);
}
PropertyDelta<QName> auxOcDelta = (PropertyDelta) PrismProperty.diff(oldRepoShadow.findProperty(ShadowType.F_AUXILIARY_OBJECT_CLASS), currentResourceShadow.findProperty(ShadowType.F_AUXILIARY_OBJECT_CLASS));
if (auxOcDelta != null) {
shadowDelta.addModification(auxOcDelta);
}
if (cachingStrategy == CachingStategyType.NONE) {
if (oldRepoShadowType.getCachingMetadata() != null) {
shadowDelta.addModificationReplaceProperty(ShadowType.F_CACHING_METADATA);
}
} else if (cachingStrategy == CachingStategyType.PASSIVE) {
compareUpdateProperty(shadowDelta, SchemaConstants.PATH_ACTIVATION_ADMINISTRATIVE_STATUS, currentResourceShadow, oldRepoShadow);
compareUpdateProperty(shadowDelta, SchemaConstants.PATH_ACTIVATION_VALID_FROM, currentResourceShadow, oldRepoShadow);
compareUpdateProperty(shadowDelta, SchemaConstants.PATH_ACTIVATION_VALID_TO, currentResourceShadow, oldRepoShadow);
compareUpdateProperty(shadowDelta, SchemaConstants.PATH_ACTIVATION_LOCKOUT_STATUS, currentResourceShadow, oldRepoShadow);
CachingMetadataType cachingMetadata = new CachingMetadataType();
cachingMetadata.setRetrievalTimestamp(clock.currentTimeXMLGregorianCalendar());
shadowDelta.addModificationReplaceProperty(ShadowType.F_CACHING_METADATA, cachingMetadata);
} else {
throw new ConfigurationException("Unknown caching strategy " + cachingStrategy);
}
if (!shadowDelta.isEmpty()) {
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Updating repo shadow {} with delta:\n{}", oldRepoShadow, shadowDelta.debugDump(1));
}
ConstraintsChecker.onShadowModifyOperation(shadowDelta.getModifications());
try {
repositoryService.modifyObject(ShadowType.class, oldRepoShadow.getOid(), shadowDelta.getModifications(), parentResult);
} catch (ObjectAlreadyExistsException e) {
// This should not happen for shadows
throw new SystemException(e.getMessage(), e);
}
PrismObject<ShadowType> newRepoShadow = oldRepoShadow.clone();
shadowDelta.applyTo(newRepoShadow);
return newRepoShadow;
} else {
LOGGER.trace("No need to update repo shadow {} (empty delta)", oldRepoShadow);
return oldRepoShadow;
}
}
use of com.evolveum.midpoint.common.refinery.RefinedObjectClassDefinition in project midpoint by Evolveum.
the class ShadowManager method fixShadow.
/**
* Re-reads the shadow, re-evaluates the identifiers and stored values, updates them if necessary. Returns
* fixed shadow.
*/
public PrismObject<ShadowType> fixShadow(ProvisioningContext ctx, PrismObject<ShadowType> origRepoShadow, OperationResult parentResult) throws ObjectNotFoundException, SchemaException, ConfigurationException, CommunicationException, ExpressionEvaluationException {
PrismObject<ShadowType> currentRepoShadow = repositoryService.getObject(ShadowType.class, origRepoShadow.getOid(), null, parentResult);
ProvisioningContext shadowCtx = ctx.spawn(currentRepoShadow);
RefinedObjectClassDefinition ocDef = shadowCtx.getObjectClassDefinition();
PrismContainer<Containerable> attributesContainer = currentRepoShadow.findContainer(ShadowType.F_ATTRIBUTES);
if (attributesContainer != null && attributesContainer.getValue() != null) {
ObjectDelta<ShadowType> shadowDelta = currentRepoShadow.createModifyDelta();
for (Item<?, ?> item : attributesContainer.getValue().getItems()) {
if (item instanceof PrismProperty<?>) {
PrismProperty<?> attrProperty = (PrismProperty<?>) item;
RefinedAttributeDefinition<Object> attrDef = ocDef.findAttributeDefinition(attrProperty.getElementName());
if (attrDef == null) {
// No definition for this property, it should not be in the shadow
PropertyDelta<?> oldRepoAttrPropDelta = attrProperty.createDelta();
oldRepoAttrPropDelta.addValuesToDelete((Collection) PrismPropertyValue.cloneCollection(attrProperty.getValues()));
shadowDelta.addModification(oldRepoAttrPropDelta);
} else {
MatchingRule matchingRule = matchingRuleRegistry.getMatchingRule(attrDef.getMatchingRuleQName(), attrDef.getTypeName());
List<PrismPropertyValue> valuesToAdd = null;
List<PrismPropertyValue> valuesToDelete = null;
for (PrismPropertyValue attrVal : attrProperty.getValues()) {
Object currentRealValue = attrVal.getValue();
Object normalizedRealValue = matchingRule.normalize(currentRealValue);
if (!normalizedRealValue.equals(currentRealValue)) {
if (attrDef.isSingleValue()) {
shadowDelta.addModificationReplaceProperty(attrProperty.getPath(), normalizedRealValue);
break;
} else {
if (valuesToAdd == null) {
valuesToAdd = new ArrayList<>();
}
valuesToAdd.add(new PrismPropertyValue(normalizedRealValue));
if (valuesToDelete == null) {
valuesToDelete = new ArrayList<>();
}
valuesToDelete.add(new PrismPropertyValue(currentRealValue));
}
}
}
PropertyDelta attrDelta = attrProperty.createDelta(attrProperty.getPath());
if (valuesToAdd != null) {
attrDelta.addValuesToAdd(valuesToAdd);
}
if (valuesToDelete != null) {
attrDelta.addValuesToDelete(valuesToDelete);
}
shadowDelta.addModification(attrDelta);
}
}
}
if (!shadowDelta.isEmpty()) {
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Fixing shadow {} with delta:\n{}", origRepoShadow, shadowDelta.debugDump());
}
try {
repositoryService.modifyObject(ShadowType.class, origRepoShadow.getOid(), shadowDelta.getModifications(), parentResult);
} catch (ObjectAlreadyExistsException e) {
// This should not happen for shadows
throw new SystemException(e.getMessage(), e);
}
shadowDelta.applyTo(currentRepoShadow);
} else {
LOGGER.trace("No need to fixing shadow {} (empty delta)", origRepoShadow);
}
} else {
LOGGER.trace("No need to fixing shadow {} (no atttributes)", origRepoShadow);
}
return currentRepoShadow;
}
use of com.evolveum.midpoint.common.refinery.RefinedObjectClassDefinition in project midpoint by Evolveum.
the class ResourceObjectReferenceResolver method resolvePrimaryIdentifiers.
/**
* Resolve primary identifier from a collection of identifiers that may contain only secondary identifiers.
*/
private ResourceObjectIdentification resolvePrimaryIdentifiers(ProvisioningContext ctx, ResourceObjectIdentification identification, OperationResult result) throws ObjectNotFoundException, SchemaException, CommunicationException, ConfigurationException, SecurityViolationException, ExpressionEvaluationException {
if (identification == null) {
return identification;
}
if (identification.hasPrimaryIdentifiers()) {
return identification;
}
Collection<ResourceAttribute<?>> secondaryIdentifiers = (Collection<ResourceAttribute<?>>) identification.getSecondaryIdentifiers();
PrismObject<ShadowType> repoShadow = shadowManager.lookupShadowBySecondaryIdentifiers(ctx, secondaryIdentifiers, result);
if (repoShadow == null) {
// TODO: we should attempt resource search here
throw new ObjectNotFoundException("No repository shadow for " + secondaryIdentifiers + ", cannot resolve identifiers");
}
PrismContainer<Containerable> attributesContainer = repoShadow.findContainer(ShadowType.F_ATTRIBUTES);
if (attributesContainer == null) {
throw new SchemaException("No attributes in " + repoShadow + ", cannot resolve identifiers " + secondaryIdentifiers);
}
RefinedObjectClassDefinition ocDef = ctx.getObjectClassDefinition();
Collection primaryIdentifiers = new ArrayList<>();
for (PrismProperty<?> property : attributesContainer.getValue().getProperties()) {
if (ocDef.isPrimaryIdentifier(property.getElementName())) {
RefinedAttributeDefinition<?> attrDef = ocDef.findAttributeDefinition(property.getElementName());
ResourceAttribute<?> primaryIdentifier = new ResourceAttribute<>(property.getElementName(), attrDef, prismContext);
primaryIdentifier.setRealValue(property.getRealValue());
primaryIdentifiers.add(primaryIdentifier);
}
}
LOGGER.trace("Resolved {} to primary identifiers {} (object class {})", identification, primaryIdentifiers, ocDef);
return new ResourceObjectIdentification(identification.getObjectClassDefinition(), primaryIdentifiers, identification.getSecondaryIdentifiers());
}
use of com.evolveum.midpoint.common.refinery.RefinedObjectClassDefinition in project midpoint by Evolveum.
the class AbstractBasicDummyTest method test023RefinedSchema.
@Test
public void test023RefinedSchema() throws Exception {
final String TEST_NAME = "test023RefinedSchema";
TestUtil.displayTestTile(TEST_NAME);
// GIVEN
// WHEN
RefinedResourceSchema refinedSchema = RefinedResourceSchemaImpl.getRefinedSchema(resourceType, prismContext);
display("Refined schema", refinedSchema);
// Check whether it is reusing the existing schema and not parsing it
// all over again
// Not equals() but == ... we want to really know if exactly the same
// object instance is returned
assertTrue("Broken caching", refinedSchema == RefinedResourceSchemaImpl.getRefinedSchema(resourceType, prismContext));
RefinedObjectClassDefinition accountDef = refinedSchema.getDefaultRefinedDefinition(ShadowKindType.ACCOUNT);
assertNotNull("Account definition is missing", accountDef);
assertNotNull("Null identifiers in account", accountDef.getPrimaryIdentifiers());
assertFalse("Empty identifiers in account", accountDef.getPrimaryIdentifiers().isEmpty());
assertNotNull("Null secondary identifiers in account", accountDef.getSecondaryIdentifiers());
assertFalse("Empty secondary identifiers in account", accountDef.getSecondaryIdentifiers().isEmpty());
assertNotNull("No naming attribute in account", accountDef.getNamingAttribute());
assertFalse("No nativeObjectClass in account", StringUtils.isEmpty(accountDef.getNativeObjectClass()));
assertEquals("Unexpected kind in account definition", ShadowKindType.ACCOUNT, accountDef.getKind());
assertTrue("Account definition in not default", accountDef.isDefaultInAKind());
assertEquals("Wrong intent in account definition", SchemaConstants.INTENT_DEFAULT, accountDef.getIntent());
assertFalse("Account definition is deprecated", accountDef.isDeprecated());
assertFalse("Account definition in auxiliary", accountDef.isAuxiliary());
RefinedAttributeDefinition<String> uidDef = accountDef.findAttributeDefinition(SchemaConstants.ICFS_UID);
assertEquals(1, uidDef.getMaxOccurs());
assertEquals(0, uidDef.getMinOccurs());
assertFalse("No UID display name", StringUtils.isBlank(uidDef.getDisplayName()));
assertFalse("UID has create", uidDef.canAdd());
assertFalse("UID has update", uidDef.canModify());
assertTrue("No UID read", uidDef.canRead());
assertTrue("UID definition not in identifiers", accountDef.getPrimaryIdentifiers().contains(uidDef));
RefinedAttributeDefinition<String> nameDef = accountDef.findAttributeDefinition(SchemaConstants.ICFS_NAME);
assertEquals(1, nameDef.getMaxOccurs());
assertEquals(1, nameDef.getMinOccurs());
assertFalse("No NAME displayName", StringUtils.isBlank(nameDef.getDisplayName()));
assertTrue("No NAME create", nameDef.canAdd());
assertTrue("No NAME update", nameDef.canModify());
assertTrue("No NAME read", nameDef.canRead());
assertTrue("NAME definition not in identifiers", accountDef.getSecondaryIdentifiers().contains(nameDef));
// MID-3144
assertEquals("Wrong NAME displayOrder", (Integer) 110, nameDef.getDisplayOrder());
assertEquals("Wrong NAME displayName", "Username", nameDef.getDisplayName());
RefinedAttributeDefinition<String> fullnameDef = accountDef.findAttributeDefinition("fullname");
assertNotNull("No definition for fullname", fullnameDef);
assertEquals(1, fullnameDef.getMaxOccurs());
assertEquals(1, fullnameDef.getMinOccurs());
assertTrue("No fullname create", fullnameDef.canAdd());
assertTrue("No fullname update", fullnameDef.canModify());
assertTrue("No fullname read", fullnameDef.canRead());
// MID-3144
if (fullnameDef.getDisplayOrder() == null || fullnameDef.getDisplayOrder() < 100 || fullnameDef.getDisplayOrder() > 400) {
AssertJUnit.fail("Wrong fullname displayOrder: " + fullnameDef.getDisplayOrder());
}
assertEquals("Wrong fullname displayName", null, fullnameDef.getDisplayName());
assertNull("The _PASSSWORD_ attribute sneaked into schema", accountDef.findAttributeDefinition(new QName(SchemaConstants.NS_ICF_SCHEMA, "password")));
rememberRefinedResourceSchema(refinedSchema);
assertSteadyResource();
}
use of com.evolveum.midpoint.common.refinery.RefinedObjectClassDefinition in project midpoint by Evolveum.
the class ProjectionValuesProcessor method willResetIterationCounter.
private boolean willResetIterationCounter(LensProjectionContext projectionContext) throws SchemaException {
ObjectDelta<ShadowType> accountDelta = projectionContext.getDelta();
if (accountDelta == null) {
return false;
}
RefinedObjectClassDefinition oOcDef = projectionContext.getCompositeObjectClassDefinition();
for (RefinedAttributeDefinition identifierDef : oOcDef.getPrimaryIdentifiers()) {
ItemPath identifierPath = new ItemPath(ShadowType.F_ATTRIBUTES, identifierDef.getName());
if (accountDelta.findPropertyDelta(identifierPath) != null) {
return true;
}
}
for (RefinedAttributeDefinition identifierDef : oOcDef.getSecondaryIdentifiers()) {
ItemPath identifierPath = new ItemPath(ShadowType.F_ATTRIBUTES, identifierDef.getName());
if (accountDelta.findPropertyDelta(identifierPath) != null) {
return true;
}
}
return false;
}
Aggregations