use of com.evolveum.midpoint.schema.processor.ResourceAttribute 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.ResourceAttribute in project midpoint by Evolveum.
the class TestDummy method test502ModifyProtectedAccountShadowAttributes.
/**
* Attribute modification should fail.
*/
@Test
public void test502ModifyProtectedAccountShadowAttributes() throws Exception {
final String TEST_NAME = "test502ModifyProtectedAccountShadowAttributes";
TestUtil.displayTestTile(TEST_NAME);
// GIVEN
Task task = createTask(TEST_NAME);
OperationResult result = task.getResult();
syncServiceMock.reset();
Collection<? extends ItemDelta> modifications = new ArrayList<ItemDelta>(1);
ResourceSchema resourceSchema = RefinedResourceSchemaImpl.getResourceSchema(resource, prismContext);
ObjectClassComplexTypeDefinition defaultAccountDefinition = resourceSchema.findDefaultObjectClassDefinition(ShadowKindType.ACCOUNT);
ResourceAttributeDefinition fullnameAttrDef = defaultAccountDefinition.findAttributeDefinition("fullname");
ResourceAttribute fullnameAttr = fullnameAttrDef.instantiate();
PropertyDelta fullnameDelta = fullnameAttr.createDelta(new ItemPath(ShadowType.F_ATTRIBUTES, fullnameAttrDef.getName()));
fullnameDelta.setValueToReplace(new PrismPropertyValue<String>("Good Daemon"));
((Collection) modifications).add(fullnameDelta);
// WHEN
try {
provisioningService.modifyObject(ShadowType.class, ACCOUNT_DAEMON_OID, modifications, null, null, task, result);
AssertJUnit.fail("Expected security exception while modifying 'daemon' account");
} catch (SecurityViolationException e) {
// This is expected
display("Expected exception", e);
}
result.computeStatus();
display("modifyObject result (expected failure)", result);
TestUtil.assertFailure(result);
syncServiceMock.assertNotifyFailureOnly();
// checkConsistency();
assertSteadyResource();
}
use of com.evolveum.midpoint.schema.processor.ResourceAttribute in project midpoint by Evolveum.
the class TestDummyCaching method test107AGetModifiedAccountFromCacheMax.
/**
* Make a native modification to an account and read it from the cache. Make sure that
* cached data are returned and there is no read from the resource.
* MID-3481
*/
@Test
@Override
public void test107AGetModifiedAccountFromCacheMax() throws Exception {
final String TEST_NAME = "test107AGetModifiedAccountFromCacheMax";
TestUtil.displayTestTile(TEST_NAME);
// GIVEN
OperationResult result = new OperationResult(TestDummy.class.getName() + "." + TEST_NAME);
rememberShadowFetchOperationCount();
DummyAccount accountWill = getDummyAccountAssert(transformNameFromResource(ACCOUNT_WILL_USERNAME), willIcfUid);
accountWill.replaceAttributeValue(DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_TITLE_NAME, "Nice Pirate");
accountWill.replaceAttributeValue(DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_SHIP_NAME, "Interceptor");
accountWill.setEnabled(true);
Collection<SelectorOptions<GetOperationOptions>> options = SelectorOptions.createCollection(GetOperationOptions.createMaxStaleness());
XMLGregorianCalendar startTs = clock.currentTimeXMLGregorianCalendar();
// WHEN
TestUtil.displayWhen(TEST_NAME);
PrismObject<ShadowType> shadow = provisioningService.getObject(ShadowType.class, ACCOUNT_WILL_OID, options, null, result);
// THEN
TestUtil.displayThen(TEST_NAME);
result.computeStatus();
display("getObject result", result);
TestUtil.assertSuccess(result);
assertShadowFetchOperationCountIncrement(0);
XMLGregorianCalendar endTs = clock.currentTimeXMLGregorianCalendar();
display("Retrieved account shadow", shadow);
assertNotNull("No dummy account", shadow);
assertAttribute(shadow, DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_TITLE_NAME, "Pirate");
assertAttribute(shadow, DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_SHIP_NAME, "Black Pearl");
assertAttribute(shadow, DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_WEAPON_NAME, "sword", "love");
assertAttribute(shadow, DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_LOOT_NAME, 42);
Collection<ResourceAttribute<?>> attributes = ShadowUtil.getAttributes(shadow);
assertEquals("Unexpected number of attributes", 7, attributes.size());
PrismObject<ShadowType> shadowRepo = repositoryService.getObject(ShadowType.class, ACCOUNT_WILL_OID, null, result);
checkRepoAccountShadowWillBasic(shadowRepo, null, startTs, null);
assertRepoShadowCachedAttributeValue(shadowRepo, DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_TITLE_NAME, "Pirate");
assertRepoShadowCachedAttributeValue(shadowRepo, DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_SHIP_NAME, "Black Pearl");
assertRepoShadowCachedAttributeValue(shadowRepo, DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_WEAPON_NAME, "sword", "love");
assertRepoShadowCachedAttributeValue(shadowRepo, DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_LOOT_NAME, 42);
assertRepoShadowCacheActivation(shadowRepo, ActivationStatusType.DISABLED);
checkConsistency(shadow);
assertCachingMetadata(shadow, true, null, startTs);
assertShadowFetchOperationCountIncrement(0);
assertSteadyResource();
}
use of com.evolveum.midpoint.schema.processor.ResourceAttribute in project midpoint by Evolveum.
the class TestDummy method test802LiveSyncModifyBlackbeard.
@Test
public void test802LiveSyncModifyBlackbeard() throws Exception {
final String TEST_NAME = "test802LiveSyncModifyBlackbeard";
TestUtil.displayTestTile(TEST_NAME);
// GIVEN
OperationResult result = new OperationResult(TestDummy.class.getName() + "." + TEST_NAME);
syncServiceMock.reset();
DummyAccount dummyAccount = getDummyAccountAssert(BLACKBEARD_USERNAME, blackbeardIcfUid);
dummyAccount.replaceAttributeValue("fullname", "Captain Blackbeard");
display("Resource before sync", dummyResource.debugDump());
ResourceShadowDiscriminator coords = new ResourceShadowDiscriminator(RESOURCE_DUMMY_OID, ProvisioningTestUtil.getDefaultAccountObjectClass(resourceType));
// WHEN
TestUtil.displayWhen(TEST_NAME);
provisioningService.synchronize(coords, syncTokenTask, result);
// THEN
result.computeStatus();
display("Synchronization result", result);
TestUtil.assertSuccess("Synchronization result is not OK", result);
syncServiceMock.assertNotifyChange();
ResourceObjectShadowChangeDescription lastChange = syncServiceMock.getLastChange();
display("The change", lastChange);
PrismObject<? extends ShadowType> oldShadow = lastChange.getOldShadow();
assertSyncOldShadow(oldShadow, getBlackbeardRepoIcfName());
assertNull("Delta present when not expecting it", lastChange.getObjectDelta());
PrismObject<ShadowType> currentShadow = lastChange.getCurrentShadow();
assertNotNull("Current shadow missing", lastChange.getCurrentShadow());
assertTrue("Wrong type of current shadow: " + currentShadow.getClass().getName(), currentShadow.canRepresent(ShadowType.class));
ResourceAttributeContainer attributesContainer = ShadowUtil.getAttributesContainer(currentShadow);
assertNotNull("No attributes container in current shadow", attributesContainer);
Collection<ResourceAttribute<?>> attributes = attributesContainer.getAttributes();
assertFalse("Attributes container is empty", attributes.isEmpty());
assertAttribute(currentShadow, DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_FULLNAME_NAME, "Captain Blackbeard");
assertAttribute(currentShadow, DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_LOOT_NAME, 66666L);
assertEquals("Unexpected number of attributes", 4, attributes.size());
PrismObject<ShadowType> accountRepo = findAccountShadowByUsername(getBlackbeardRepoIcfName(), resource, result);
assertNotNull("Shadow was not created in the repository", accountRepo);
display("Repository shadow", accountRepo);
checkRepoAccountShadow(accountRepo);
checkAllShadows();
assertSteadyResource();
}
use of com.evolveum.midpoint.schema.processor.ResourceAttribute in project midpoint by Evolveum.
the class TestDummy method testLiveSyncAddDrake.
public void testLiveSyncAddDrake(final String TEST_NAME, DummySyncStyle syncStyle, QName objectClass) throws Exception {
TestUtil.displayTestTile(TEST_NAME);
// GIVEN
OperationResult result = new OperationResult(TestDummy.class.getName() + "." + TEST_NAME);
syncServiceMock.reset();
dummyResource.setSyncStyle(syncStyle);
DummyAccount newAccount = new DummyAccount(DRAKE_USERNAME);
newAccount.addAttributeValues("fullname", "Sir Francis Drake");
newAccount.setEnabled(true);
newAccount.setPassword("avast!");
dummyResource.addAccount(newAccount);
drakeIcfUid = newAccount.getId();
display("Resource before sync", dummyResource.debugDump());
ResourceShadowDiscriminator coords = new ResourceShadowDiscriminator(RESOURCE_DUMMY_OID, objectClass);
// WHEN
TestUtil.displayWhen(TEST_NAME);
provisioningService.synchronize(coords, syncTokenTask, result);
// THEN
TestUtil.displayThen(TEST_NAME);
result.computeStatus();
display("Synchronization result", result);
TestUtil.assertSuccess("Synchronization result is not OK", result);
syncServiceMock.assertNotifyChange();
ResourceObjectShadowChangeDescription lastChange = syncServiceMock.getLastChange();
display("The change", lastChange);
PrismObject<? extends ShadowType> oldShadow = lastChange.getOldShadow();
assertNotNull("Old shadow missing", oldShadow);
assertNotNull("Old shadow does not have an OID", oldShadow.getOid());
if (syncStyle == DummySyncStyle.DUMB) {
assertNull("Delta present when not expecting it", lastChange.getObjectDelta());
} else {
ObjectDelta<? extends ShadowType> objectDelta = lastChange.getObjectDelta();
assertNotNull("Delta present when not expecting it", objectDelta);
assertTrue("Delta is not add: " + objectDelta, objectDelta.isAdd());
}
ShadowType currentShadowType = lastChange.getCurrentShadow().asObjectable();
assertNotNull("Current shadow missing", lastChange.getCurrentShadow());
PrismAsserts.assertClass("current shadow", ShadowType.class, currentShadowType);
ResourceAttributeContainer attributesContainer = ShadowUtil.getAttributesContainer(currentShadowType);
assertNotNull("No attributes container in current shadow", attributesContainer);
Collection<ResourceAttribute<?>> attributes = attributesContainer.getAttributes();
assertFalse("Attributes container is empty", attributes.isEmpty());
assertEquals("Unexpected number of attributes", 3, attributes.size());
ResourceAttribute<?> fullnameAttribute = attributesContainer.findAttribute(new QName(ResourceTypeUtil.getResourceNamespace(resourceType), "fullname"));
assertNotNull("No fullname attribute in current shadow", fullnameAttribute);
assertEquals("Wrong value of fullname attribute in current shadow", "Sir Francis Drake", fullnameAttribute.getRealValue());
drakeAccountOid = currentShadowType.getOid();
PrismObject<ShadowType> repoShadow = repositoryService.getObject(ShadowType.class, drakeAccountOid, null, result);
display("Drake repo shadow", repoShadow);
PrismObject<ShadowType> accountRepo = findAccountShadowByUsername(getDrakeRepoIcfName(), resource, result);
assertNotNull("Shadow was not created in the repository", accountRepo);
display("Repository shadow", accountRepo);
checkRepoAccountShadow(accountRepo);
checkAllShadows();
assertSteadyResource();
}
Aggregations