use of com.evolveum.midpoint.schema.processor.ResourceAttributeContainer in project midpoint by Evolveum.
the class ConsistencyTest method test800Reconciliation.
// This should run last. It starts a task that may interfere with other tests
@Test
public void test800Reconciliation() throws Exception {
final String TEST_NAME = "test800Reconciliation";
TestUtil.displayTestTile(this, TEST_NAME);
openDJController.assumeRunning();
final OperationResult result = new OperationResult(ConsistencyTest.class.getName() + "." + TEST_NAME);
// TODO: remove this if the previous test is enabled
// openDJController.start();
// rename eobject dirrectly on resource before the recon start ..it tests the rename + recon situation (MID-1594)
// precondition
assertTrue(EmbeddedUtils.isRunning());
UserType userJack = repositoryService.getObject(UserType.class, USER_JACK_OID, null, result).asObjectable();
display("Jack before", userJack);
LOGGER.info("start running task");
// WHEN
repoAddObjectFromFile(TASK_OPENDJ_RECONCILIATION_FILENAME, result);
verbose = true;
long started = System.currentTimeMillis();
waitForTaskNextRunAssertSuccess(TASK_OPENDJ_RECONCILIATION_OID, false, 120000);
LOGGER.info("Reconciliation task run took {} seconds", (System.currentTimeMillis() - started) / 1000L);
// THEN
// STOP the task. We don't need it any more. Even if it's non-recurrent its safer to delete it
taskManager.deleteTask(TASK_OPENDJ_RECONCILIATION_OID, result);
// check if the account was added after reconciliation
UserType userE = repositoryService.getObject(UserType.class, USER_E_OID, null, result).asObjectable();
String accountOid = assertUserOneAccountRef(USER_E_OID);
ShadowType eAccount = checkNormalizedShadowWithAttributes(accountOid, "e", "Jackkk", "e", "e", true, null, result);
assertAttribute(eAccount, "employeeNumber", "emp4321");
ResourceAttributeContainer attributeContainer = ShadowUtil.getAttributesContainer(eAccount);
Collection<ResourceAttribute<?>> identifiers = attributeContainer.getPrimaryIdentifiers();
assertNotNull(identifiers);
assertFalse(identifiers.isEmpty());
assertEquals(1, identifiers.size());
// check if the account was modified during reconciliation process
String jackAccountOid = assertUserOneAccountRef(USER_JACK_OID);
ShadowType modifiedAccount = checkNormalizedShadowBasic(jackAccountOid, "jack", true, SelectorOptions.createCollection(GetOperationOptions.createDoNotDiscovery()), null, result);
assertAttribute(modifiedAccount, "givenName", "Jackkk");
assertAttribute(modifiedAccount, "employeeNumber", "emp4321");
// check if the account was deleted during the reconciliation process
try {
modelService.getObject(ShadowType.class, ACCOUNT_DENIELS_OID, null, null, result);
fail("Expected ObjectNotFoundException but haven't got one.");
} catch (Exception ex) {
if (!(ex instanceof ObjectNotFoundException)) {
fail("Expected ObjectNotFoundException but got " + ex);
}
}
String elaineAccountOid = assertUserOneAccountRef(USER_ELAINE_OID);
modifiedAccount = checkNormalizedShadowBasic(elaineAccountOid, "elaine", true, SelectorOptions.createCollection(GetOperationOptions.createDoNotDiscovery()), null, result);
assertAttribute(modifiedAccount, getOpenDjSecondaryIdentifierQName(), "uid=elaine,ou=people,dc=example,dc=com");
accountOid = assertUserOneAccountRef(USER_JACK2_OID);
ShadowType jack2Shadow = checkNormalizedShadowBasic(accountOid, "jack2", true, SelectorOptions.createCollection(GetOperationOptions.createDoNotDiscovery()), null, result);
assertAttribute(jack2Shadow, "givenName", "jackNew2a");
assertAttribute(jack2Shadow, "cn", "jackNew2a");
}
use of com.evolveum.midpoint.schema.processor.ResourceAttributeContainer in project midpoint by Evolveum.
the class ConsistencyTest method test801TestReconciliationRename.
@Test
public void test801TestReconciliationRename() throws Exception {
final String TEST_NAME = "test801TestReconciliationRename";
TestUtil.displayTestTile(this, TEST_NAME);
openDJController.assumeRunning();
Task task = createTask(TEST_NAME);
final OperationResult result = task.getResult();
LOGGER.info("starting rename");
openDJController.executeRenameChange(LDIF_MODIFY_RENAME_FILENAME);
LOGGER.info("rename ended");
// Entry res = openDJController.searchByUid("e");
// LOGGER.info("E OBJECT AFTER RENAME " + res.toString());
LOGGER.info("start running task");
// WHEN
long started = System.currentTimeMillis();
repoAddObjectFromFile(TASK_OPENDJ_RECONCILIATION_FILENAME, result);
waitForTaskFinish(TASK_OPENDJ_RECONCILIATION_OID, false, 120000);
LOGGER.info("Reconciliation task run took {} seconds", (System.currentTimeMillis() - started) / 1000L);
// THEN
// STOP the task. We don't need it any more. Even if it's non-recurrent its safer to delete it
taskManager.deleteTask(TASK_OPENDJ_RECONCILIATION_OID, result);
// check if the account was added after reconciliation
UserType userE = repositoryService.getObject(UserType.class, USER_E_OID, null, result).asObjectable();
String accountOid = assertUserOneAccountRef(USER_E_OID);
ShadowType eAccount = checkNormalizedShadowWithAttributes(accountOid, "e123", "Jackkk", "e", "e", true, null, result);
assertAttribute(eAccount, "employeeNumber", "emp4321");
ResourceAttributeContainer attributeContainer = ShadowUtil.getAttributesContainer(eAccount);
Collection<ResourceAttribute<?>> identifiers = attributeContainer.getPrimaryIdentifiers();
assertNotNull(identifiers);
assertFalse(identifiers.isEmpty());
assertEquals(1, identifiers.size());
ResourceAttribute icfNameAttr = attributeContainer.findAttribute(getOpenDjSecondaryIdentifierQName());
assertEquals("Wrong secondary indetifier.", "uid=e123,ou=people,dc=example,dc=com", icfNameAttr.getRealValue());
assertEquals("Wrong shadow name. ", "uid=e123,ou=people,dc=example,dc=com", eAccount.getName().getOrig());
PrismObject<ShadowType> repoShadow = repositoryService.getObject(ShadowType.class, accountOid, null, result);
provisioningService.applyDefinition(repoShadow, task, result);
ResourceAttributeContainer repoAttributeContainer = ShadowUtil.getAttributesContainer(repoShadow);
ResourceAttribute repoIcfNameAttr = repoAttributeContainer.findAttribute(getOpenDjSecondaryIdentifierQName());
assertEquals("Wrong secondary indetifier.", "uid=e123,ou=people,dc=example,dc=com", repoIcfNameAttr.getRealValue());
assertEquals("Wrong shadow name. ", "uid=e123,ou=people,dc=example,dc=com", repoShadow.asObjectable().getName().getOrig());
}
use of com.evolveum.midpoint.schema.processor.ResourceAttributeContainer in project midpoint by Evolveum.
the class AbstractModelIntegrationTest method createAccount.
protected PrismObject<ShadowType> createAccount(PrismObject<ResourceType> resource, String name, boolean enabled) throws SchemaException {
PrismObject<ShadowType> shadow = getShadowDefinition().instantiate();
ShadowType shadowType = shadow.asObjectable();
ObjectReferenceType resourceRef = new ObjectReferenceType();
resourceRef.setOid(resource.getOid());
shadowType.setResourceRef(resourceRef);
RefinedResourceSchema refinedSchema = RefinedResourceSchemaImpl.getRefinedSchema(resource);
RefinedObjectClassDefinition objectClassDefinition = refinedSchema.getDefaultRefinedDefinition(ShadowKindType.ACCOUNT);
shadowType.setObjectClass(objectClassDefinition.getTypeName());
shadowType.setKind(ShadowKindType.ACCOUNT);
ResourceAttributeContainer attrCont = ShadowUtil.getOrCreateAttributesContainer(shadow, objectClassDefinition);
RefinedAttributeDefinition idSecondaryDef = objectClassDefinition.getSecondaryIdentifiers().iterator().next();
ResourceAttribute icfsNameAttr = idSecondaryDef.instantiate();
icfsNameAttr.setRealValue(name);
attrCont.add(icfsNameAttr);
ActivationType activation = new ActivationType();
shadowType.setActivation(activation);
if (enabled) {
activation.setAdministrativeStatus(ActivationStatusType.ENABLED);
} else {
activation.setAdministrativeStatus(ActivationStatusType.DISABLED);
}
return shadow;
}
use of com.evolveum.midpoint.schema.processor.ResourceAttributeContainer in project midpoint by Evolveum.
the class EntitlementConverter method collectEntitlementAsObjectOperation.
private <TV, TA> PrismObject<ShadowType> collectEntitlementAsObjectOperation(ProvisioningContext subjectCtx, Map<ResourceObjectDiscriminator, ResourceObjectOperations> roMap, PrismContainerValue<ShadowAssociationType> associationCVal, PrismObject<ShadowType> subjectShadowBefore, PrismObject<ShadowType> subjectShadowAfter, ModificationType modificationType, OperationResult result) throws SchemaException, ObjectNotFoundException, CommunicationException, SecurityViolationException, ConfigurationException, ExpressionEvaluationException {
ResourceType resource = subjectCtx.getResource();
ShadowAssociationType associationType = associationCVal.asContainerable();
QName associationName = associationType.getName();
if (associationName == null) {
throw new SchemaException("No name in entitlement association " + associationCVal);
}
RefinedAssociationDefinition assocDefType = subjectCtx.getObjectClassDefinition().findAssociationDefinition(associationName);
if (assocDefType == null) {
throw new SchemaException("No entitlement association with name " + assocDefType + " in schema of " + resource);
}
ResourceObjectAssociationDirectionType direction = assocDefType.getResourceObjectAssociationType().getDirection();
if (direction != ResourceObjectAssociationDirectionType.OBJECT_TO_SUBJECT) {
// Process just this one direction. The other direction was processed before
return subjectShadowAfter;
}
Collection<String> entitlementIntents = assocDefType.getIntents();
if (entitlementIntents == null || entitlementIntents.isEmpty()) {
throw new SchemaException("No entitlement intent specified in association " + associationCVal + " in " + resource);
}
ShadowKindType entitlementKind = assocDefType.getKind();
if (entitlementKind == null) {
entitlementKind = ShadowKindType.ENTITLEMENT;
}
for (String entitlementIntent : entitlementIntents) {
ProvisioningContext entitlementCtx = subjectCtx.spawn(entitlementKind, entitlementIntent);
RefinedObjectClassDefinition entitlementOcDef = entitlementCtx.getObjectClassDefinition();
if (entitlementOcDef == null) {
throw new SchemaException("No definition of entitlement intent(s) '" + entitlementIntents + "' specified in association " + associationCVal + " in " + resource);
}
QName assocAttrName = assocDefType.getResourceObjectAssociationType().getAssociationAttribute();
if (assocAttrName == null) {
throw new SchemaException("No association attribute defined in entitlement association in " + resource);
}
RefinedAttributeDefinition assocAttrDef = entitlementOcDef.findAttributeDefinition(assocAttrName);
if (assocAttrDef == null) {
throw new SchemaException("Association attribute '" + assocAttrName + "'defined in entitlement association was not found in entitlement intent(s) '" + entitlementIntents + "' in schema for " + resource);
}
ResourceAttributeContainer identifiersContainer = ShadowUtil.getAttributesContainer(associationCVal, ShadowAssociationType.F_IDENTIFIERS);
Collection<ResourceAttribute<?>> entitlementIdentifiersFromAssociation = identifiersContainer.getAttributes();
ResourceObjectDiscriminator disc = new ResourceObjectDiscriminator(entitlementOcDef.getTypeName(), entitlementIdentifiersFromAssociation);
ResourceObjectOperations operations = roMap.get(disc);
if (operations == null) {
operations = new ResourceObjectOperations();
operations.setResourceObjectContext(entitlementCtx);
roMap.put(disc, operations);
}
QName valueAttrName = assocDefType.getResourceObjectAssociationType().getValueAttribute();
if (valueAttrName == null) {
throw new SchemaException("No value attribute defined in entitlement association in " + resource);
}
// Which shadow would we use - shadowBefore or shadowAfter?
//
// If the operation is ADD or REPLACE, we use current version of the shadow (shadowAfter), because we want
// to ensure that we add most-recent data to the subject.
//
// If the operation is DELETE, we have two possibilities:
// - if the resource provides referential integrity, the subject has already
// new data (because the object operation was already carried out), so we use shadowAfter
// - if the resource does not provide referential integrity, the subject has OLD data
// so we use shadowBefore
PrismObject<ShadowType> subjectShadow;
if (modificationType != ModificationType.DELETE) {
subjectShadow = subjectShadowAfter;
} else {
if (assocDefType.requiresExplicitReferentialIntegrity()) {
// we must ensure the referential integrity
subjectShadow = subjectShadowBefore;
} else {
// i.e. resource has ref integrity assured by itself
subjectShadow = subjectShadowAfter;
}
}
ResourceAttribute<TV> valueAttr = ShadowUtil.getAttribute(subjectShadow, valueAttrName);
if (valueAttr == null) {
if (!ShadowUtil.isFullShadow(subjectShadow)) {
Collection<ResourceAttribute<?>> subjectIdentifiers = ShadowUtil.getAllIdentifiers(subjectShadow);
LOGGER.trace("Fetching {} ({})", subjectShadow, subjectIdentifiers);
subjectShadow = resourceObjectReferenceResolver.fetchResourceObject(subjectCtx, subjectIdentifiers, null, result);
subjectShadowAfter = subjectShadow;
valueAttr = ShadowUtil.getAttribute(subjectShadow, valueAttrName);
}
if (valueAttr == null) {
LOGGER.error("No value attribute {} in shadow\n{}", valueAttrName, subjectShadow.debugDump());
// TODO: check schema and try to fetch full shadow if necessary
throw new SchemaException("No value attribute " + valueAttrName + " in " + subjectShadow);
}
}
PropertyDelta<TA> attributeDelta = null;
for (Operation operation : operations.getOperations()) {
if (operation instanceof PropertyModificationOperation) {
PropertyModificationOperation propOp = (PropertyModificationOperation) operation;
if (propOp.getPropertyDelta().getElementName().equals(assocAttrName)) {
attributeDelta = propOp.getPropertyDelta();
}
}
}
if (attributeDelta == null) {
attributeDelta = assocAttrDef.createEmptyDelta(new ItemPath(ShadowType.F_ATTRIBUTES, assocAttrName));
}
PrismProperty<TA> changedAssocAttr = PrismUtil.convertProperty(valueAttr, assocAttrDef);
if (modificationType == ModificationType.ADD) {
attributeDelta.addValuesToAdd(changedAssocAttr.getClonedValues());
} else if (modificationType == ModificationType.DELETE) {
attributeDelta.addValuesToDelete(changedAssocAttr.getClonedValues());
} else if (modificationType == ModificationType.REPLACE) {
// TODO: check if already exists
attributeDelta.setValuesToReplace(changedAssocAttr.getClonedValues());
}
if (ResourceTypeUtil.isAvoidDuplicateValues(resource)) {
PrismObject<ShadowType> currentObjectShadow = operations.getCurrentShadow();
if (currentObjectShadow == null) {
LOGGER.trace("Fetching entitlement shadow {} to avoid value duplication (intent={})", entitlementIdentifiersFromAssociation, entitlementIntent);
currentObjectShadow = resourceObjectReferenceResolver.fetchResourceObject(entitlementCtx, entitlementIdentifiersFromAssociation, null, result);
operations.setCurrentShadow(currentObjectShadow);
}
// TODO it seems that duplicate values are checked twice: once here and the second time in ResourceObjectConverter.executeModify
// TODO check that and fix if necessary
PropertyDelta<TA> attributeDeltaAfterNarrow = ProvisioningUtil.narrowPropertyDelta(attributeDelta, currentObjectShadow, assocDefType.getMatchingRule(), matchingRuleRegistry);
if (LOGGER.isTraceEnabled() && (attributeDeltaAfterNarrow == null || attributeDeltaAfterNarrow.isEmpty())) {
LOGGER.trace("Not collecting entitlement object operations ({}) association {}: attribute delta is empty after narrow, orig delta: {}", modificationType, associationName.getLocalPart(), attributeDelta);
}
attributeDelta = attributeDeltaAfterNarrow;
}
if (attributeDelta != null && !attributeDelta.isEmpty()) {
PropertyModificationOperation attributeModification = new PropertyModificationOperation(attributeDelta);
attributeModification.setMatchingRuleQName(assocDefType.getMatchingRule());
LOGGER.trace("Collecting entitlement object operations ({}) association {}: {}", modificationType, associationName.getLocalPart(), attributeModification);
operations.add(attributeModification);
}
}
return subjectShadowAfter;
}
use of com.evolveum.midpoint.schema.processor.ResourceAttributeContainer in project midpoint by Evolveum.
the class EntitlementConverter method collectEntitlementToAttrDelta.
/**
* Collects entitlement changes from the shadow to entitlement section into attribute operations.
* Collects a single value.
* NOTE: only collects SUBJECT_TO_ENTITLEMENT entitlement direction.
*/
private <T> void collectEntitlementToAttrDelta(ProvisioningContext ctx, Map<QName, PropertyModificationOperation> operationMap, PrismContainerValue<ShadowAssociationType> associationCVal, ModificationType modificationType) throws SchemaException, ConfigurationException, ObjectNotFoundException, CommunicationException, ExpressionEvaluationException {
RefinedObjectClassDefinition objectClassDefinition = ctx.getObjectClassDefinition();
ShadowAssociationType associationType = associationCVal.asContainerable();
QName associationName = associationType.getName();
if (associationName == null) {
throw new SchemaException("No name in entitlement association " + associationCVal);
}
RefinedAssociationDefinition assocDefType = objectClassDefinition.findAssociationDefinition(associationName);
if (assocDefType == null) {
throw new SchemaException("No association with name " + associationName + " in " + objectClassDefinition + " in schema of " + ctx.getResource());
}
ResourceObjectAssociationDirectionType direction = assocDefType.getResourceObjectAssociationType().getDirection();
if (direction != ResourceObjectAssociationDirectionType.SUBJECT_TO_OBJECT) {
// therefore will be processed later
return;
}
QName assocAttrName = assocDefType.getResourceObjectAssociationType().getAssociationAttribute();
if (assocAttrName == null) {
throw new SchemaException("No association attribute definied in entitlement association '" + associationName + "' in " + ctx.getResource());
}
RefinedAttributeDefinition assocAttrDef = objectClassDefinition.findAttributeDefinition(assocAttrName);
if (assocAttrDef == null) {
throw new SchemaException("Association attribute '" + assocAttrName + "'definied in entitlement association '" + associationName + "' was not found in schema for " + ctx.getResource());
}
PropertyModificationOperation attributeOperation = operationMap.get(assocAttrName);
if (attributeOperation == null) {
attributeOperation = new PropertyModificationOperation(assocAttrDef.createEmptyDelta(new ItemPath(ShadowType.F_ATTRIBUTES, assocAttrName)));
attributeOperation.setMatchingRuleQName(assocDefType.getMatchingRule());
operationMap.put(assocAttrName, attributeOperation);
}
QName valueAttrName = assocDefType.getResourceObjectAssociationType().getValueAttribute();
if (valueAttrName == null) {
throw new SchemaException("No value attribute defined in entitlement association '" + associationName + "' in " + ctx.getResource());
}
ResourceAttributeContainer identifiersContainer = ShadowUtil.getAttributesContainer(associationCVal, ShadowAssociationType.F_IDENTIFIERS);
PrismProperty<T> valueAttr = identifiersContainer.findProperty(valueAttrName);
if (valueAttr == null) {
throw new SchemaException("No value attribute " + valueAttrName + " present in entitlement association '" + associationName + "' in shadow for " + ctx.getResource());
}
if (modificationType == ModificationType.ADD) {
attributeOperation.getPropertyDelta().addValuesToAdd(valueAttr.getClonedValues());
} else if (modificationType == ModificationType.DELETE) {
attributeOperation.getPropertyDelta().addValuesToDelete(valueAttr.getClonedValues());
} else if (modificationType == ModificationType.REPLACE) {
// TODO: check if already exists
attributeOperation.getPropertyDelta().setValuesToReplace(valueAttr.getClonedValues());
}
}
Aggregations