/* * Copyright (c) 2010-2016 Evolveum * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.evolveum.midpoint.model.impl; import com.evolveum.midpoint.common.crypto.CryptoUtil; import com.evolveum.midpoint.common.refinery.RefinedAttributeDefinition; import com.evolveum.midpoint.common.refinery.RefinedObjectClassDefinition; import com.evolveum.midpoint.model.impl.lens.LensContext; import com.evolveum.midpoint.model.impl.lens.LensFocusContext; import com.evolveum.midpoint.model.impl.lens.LensProjectionContext; import com.evolveum.midpoint.model.test.AbstractModelIntegrationTest; import com.evolveum.midpoint.prism.PrismObject; import com.evolveum.midpoint.prism.PrismPropertyValue; import com.evolveum.midpoint.prism.crypto.EncryptionException; import com.evolveum.midpoint.prism.delta.ObjectDelta; import com.evolveum.midpoint.prism.delta.PropertyDelta; import com.evolveum.midpoint.prism.path.ItemPath; import com.evolveum.midpoint.prism.util.PrismTestUtil; import com.evolveum.midpoint.schema.DeltaConvertor; import com.evolveum.midpoint.schema.ResourceShadowDiscriminator; import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.schema.util.ResourceTypeUtil; import com.evolveum.midpoint.schema.util.ShadowUtil; import com.evolveum.midpoint.task.api.Task; import com.evolveum.midpoint.util.exception.*; import com.evolveum.midpoint.xml.ns._public.common.api_types_3.ObjectModificationType; import com.evolveum.midpoint.xml.ns._public.common.common_3.*; import org.jetbrains.annotations.NotNull; import javax.xml.bind.JAXBException; import javax.xml.namespace.QName; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.util.function.Consumer; import static com.evolveum.midpoint.test.IntegrationTestTools.display; import static org.testng.AssertJUnit.*; /** * An enhancement of AbstractModelIntegrationTest (i.e. model-api-level test) that contains various useful * methods that depend on model-impl functionality - but without importing various objects at initialization time. * * @author semancik * @author mederly */ public class AbstractModelImplementationIntegrationTest extends AbstractModelIntegrationTest { @Override public void initSystem(Task initTask, OperationResult initResult) throws Exception { super.initSystem(initTask, initResult); } protected <O extends ObjectType> LensContext<O> createLensContext(Class<O> focusType) { return new LensContext<O>(focusType, prismContext, provisioningService); } protected LensContext<UserType> createUserLensContext() { return new LensContext<UserType>(UserType.class, prismContext, provisioningService); } protected <O extends ObjectType> LensFocusContext<O> fillContextWithFocus(LensContext<O> context, PrismObject<O> focus) throws SchemaException, ObjectNotFoundException { LensFocusContext<O> focusContext = context.getOrCreateFocusContext(); focusContext.setLoadedObject(focus); return focusContext; } protected <O extends ObjectType> LensFocusContext<O> fillContextWithFocus(LensContext<O> context, Class<O> type, String userOid, OperationResult result) throws SchemaException, ObjectNotFoundException { PrismObject<O> focus = repositoryService.getObject(type, userOid, null, result); return fillContextWithFocus(context, focus); } protected LensFocusContext<UserType> fillContextWithUser(LensContext<UserType> context, String userOid, OperationResult result) throws SchemaException, ObjectNotFoundException { return fillContextWithFocus(context, UserType.class, userOid, result); } protected <O extends ObjectType> void fillContextWithFocus(LensContext<O> context, File file) throws SchemaException, ObjectNotFoundException, CommunicationException, ConfigurationException, SecurityViolationException, IOException { PrismObject<O> user = PrismTestUtil.parseObject(file); fillContextWithFocus(context, user); } protected void fillContextWithEmtptyAddUserDelta(LensContext<UserType> context, OperationResult result) throws SchemaException { ObjectDelta<UserType> userDelta = ObjectDelta.createEmptyAddDelta(UserType.class, null, prismContext); LensFocusContext<UserType> focusContext = context.getOrCreateFocusContext(); focusContext.setPrimaryDelta(userDelta); } protected void fillContextWithAddUserDelta(LensContext<UserType> context, PrismObject<UserType> user) throws SchemaException, EncryptionException { CryptoUtil.encryptValues(protector, user); ObjectDelta<UserType> userDelta = ObjectDelta.createAddDelta(user); LensFocusContext<UserType> focusContext = context.getOrCreateFocusContext(); focusContext.setPrimaryDelta(userDelta); } protected LensProjectionContext fillContextWithAccount(LensContext<UserType> context, String accountOid, OperationResult result) throws SchemaException, ObjectNotFoundException, CommunicationException, ConfigurationException, SecurityViolationException { PrismObject<ShadowType> account = repositoryService.getObject(ShadowType.class, accountOid, null, result); provisioningService.applyDefinition(account, result); return fillContextWithAccount(context, account, result); } protected LensProjectionContext fillContextWithAccountFromFile(LensContext<UserType> context, File file, OperationResult result) throws SchemaException, ObjectNotFoundException, CommunicationException, ConfigurationException, SecurityViolationException, IOException { PrismObject<ShadowType> account = PrismTestUtil.parseObject(file); provisioningService.applyDefinition(account, result); return fillContextWithAccount(context, account, result); } protected LensProjectionContext fillContextWithAccount(LensContext<UserType> context, PrismObject<ShadowType> account, OperationResult result) throws SchemaException, ObjectNotFoundException, CommunicationException, ConfigurationException, SecurityViolationException { ShadowType accountType = account.asObjectable(); String resourceOid = accountType.getResourceRef().getOid(); ResourceType resourceType = provisioningService.getObject(ResourceType.class, resourceOid, null, null, result).asObjectable(); applyResourceSchema(accountType, resourceType); ResourceShadowDiscriminator rat = new ResourceShadowDiscriminator(resourceOid, ShadowKindType.ACCOUNT, ShadowUtil.getIntent(accountType)); LensProjectionContext accountSyncContext = context.findOrCreateProjectionContext(rat); accountSyncContext.setOid(account.getOid()); accountSyncContext.setLoadedObject(account); accountSyncContext.setResource(resourceType); accountSyncContext.setExists(true); context.rememberResource(resourceType); return accountSyncContext; } protected <O extends ObjectType> ObjectDelta<O> addFocusModificationToContext( LensContext<O> context, File file) throws JAXBException, SchemaException, IOException { ObjectModificationType modElement = PrismTestUtil.parseAtomicValue( file, ObjectModificationType.COMPLEX_TYPE); ObjectDelta<O> focusDelta = DeltaConvertor.createObjectDelta( modElement, context.getFocusClass(), prismContext); return addFocusDeltaToContext(context, focusDelta); } protected <O extends ObjectType> ObjectDelta<O> addFocusDeltaToContext( LensContext<O> context, ObjectDelta<O> focusDelta) throws SchemaException { LensFocusContext<O> focusContext = context.getOrCreateFocusContext(); focusContext.addPrimaryDelta(focusDelta); return focusDelta; } protected ObjectDelta<UserType> addModificationToContextReplaceUserProperty( LensContext<UserType> context, QName propertyName, Object... propertyValues) throws SchemaException { return addModificationToContextReplaceUserProperty(context, new ItemPath(propertyName), propertyValues); } protected ObjectDelta<UserType> addModificationToContextReplaceUserProperty( LensContext<UserType> context, ItemPath propertyPath, Object... propertyValues) throws SchemaException { LensFocusContext<UserType> focusContext = context.getOrCreateFocusContext(); ObjectDelta<UserType> userDelta = ObjectDelta.createModificationReplaceProperty(UserType.class, focusContext .getObjectOld().getOid(), propertyPath, prismContext, propertyValues); focusContext.addPrimaryDelta(userDelta); return userDelta; } protected ObjectDelta<UserType> addModificationToContextAddAccountFromFile( LensContext<UserType> context, String filename) throws JAXBException, SchemaException, IOException { return addModificationToContextAddProjection(context, UserType.class, new File(filename)); } protected ObjectDelta<UserType> addModificationToContextAddAccountFromFile( LensContext<UserType> context, File file) throws JAXBException, SchemaException, IOException { return addModificationToContextAddProjection(context, UserType.class, file); } protected <F extends FocusType> ObjectDelta<F> addModificationToContextAddProjection( LensContext<F> context, Class<F> focusType, File file) throws JAXBException, SchemaException, IOException { PrismObject<ShadowType> account = PrismTestUtil.parseObject(file); account.trim(); account.checkConsistence(); LensFocusContext<F> focusContext = context.getOrCreateFocusContext(); ObjectDelta<F> userDelta = ObjectDelta.createModificationAddReference(focusType, focusContext .getObjectOld().getOid(), FocusType.F_LINK_REF, prismContext, account); focusContext.addPrimaryDelta(userDelta); return userDelta; } protected ObjectDelta<ShadowType> addModificationToContextDeleteAccount( LensContext<UserType> context, String accountOid) throws SchemaException, FileNotFoundException { LensProjectionContext accountCtx = context.findProjectionContextByOid(accountOid); ObjectDelta<ShadowType> deleteAccountDelta = ObjectDelta.createDeleteDelta(ShadowType.class, accountOid, prismContext); accountCtx.addPrimaryDelta(deleteAccountDelta); return deleteAccountDelta; } protected <T> ObjectDelta<ShadowType> addModificationToContextReplaceAccountAttribute( LensContext<UserType> context, String accountOid, String attributeLocalName, T... propertyValues) throws SchemaException { LensProjectionContext accCtx = context.findProjectionContextByOid(accountOid); ObjectDelta<ShadowType> accountDelta = createAccountDelta(accCtx, accountOid, attributeLocalName, propertyValues); accCtx.addPrimaryDelta(accountDelta); return accountDelta; } protected <T> ObjectDelta<ShadowType> addSyncModificationToContextReplaceAccountAttribute( LensContext<UserType> context, String accountOid, String attributeLocalName, T... propertyValues) throws SchemaException { LensProjectionContext accCtx = context.findProjectionContextByOid(accountOid); ObjectDelta<ShadowType> accountDelta = createAccountDelta(accCtx, accountOid, attributeLocalName, propertyValues); accCtx.addAccountSyncDelta(accountDelta); return accountDelta; } protected ObjectDelta<UserType> addModificationToContextAssignRole( LensContext<UserType> context, String userOid, String roleOid) throws SchemaException { return addModificationToContextAssignRole(context, userOid, roleOid, null); } protected ObjectDelta<UserType> addModificationToContextAssignRole( LensContext<UserType> context, String userOid, String roleOid, Consumer<AssignmentType> modificationBlock) throws SchemaException { LensFocusContext<UserType> focusContext = context.getOrCreateFocusContext(); ObjectDelta<UserType> userDelta = createAssignmentUserDelta(userOid, roleOid, RoleType.COMPLEX_TYPE, null, modificationBlock, true); focusContext.addPrimaryDelta(userDelta); return userDelta; } protected ObjectDelta<UserType> addModificationToContextUnassignRole( LensContext<UserType> context, String userOid, String roleOid) throws SchemaException { LensFocusContext<UserType> focusContext = context.getOrCreateFocusContext(); ObjectDelta<UserType> userDelta = createAssignmentUserDelta(userOid, roleOid, RoleType.COMPLEX_TYPE, null, null, null, false); focusContext.addPrimaryDelta(userDelta); return userDelta; } protected <T> ObjectDelta<ShadowType> createAccountDelta(LensProjectionContext accCtx, String accountOid, String attributeLocalName, T... propertyValues) throws SchemaException { ResourceType resourceType = accCtx.getResource(); QName attrQName = new QName(ResourceTypeUtil.getResourceNamespace(resourceType), attributeLocalName); ItemPath attrPath = new ItemPath(ShadowType.F_ATTRIBUTES, attrQName); RefinedObjectClassDefinition refinedAccountDefinition = accCtx.getCompositeObjectClassDefinition(); RefinedAttributeDefinition attrDef = refinedAccountDefinition.findAttributeDefinition(attrQName); assertNotNull("No definition of attribute "+attrQName+" in account def "+refinedAccountDefinition, attrDef); ObjectDelta<ShadowType> accountDelta = ObjectDelta.createEmptyModifyDelta(ShadowType.class, accountOid, prismContext); PropertyDelta<T> attrDelta = new PropertyDelta<T>(attrPath, attrDef, prismContext); attrDelta.setValuesToReplace(PrismPropertyValue.createCollection(propertyValues)); accountDelta.addModification(attrDelta); return accountDelta; } /** * Breaks user assignment delta in the context by inserting some empty value. This may interfere with comparing the values to * existing user values. */ protected <F extends FocusType> void breakAssignmentDelta(LensContext<F> context) throws SchemaException { LensFocusContext<F> focusContext = context.getFocusContext(); ObjectDelta<F> userPrimaryDelta = focusContext.getPrimaryDelta(); breakAssignmentDelta(userPrimaryDelta); } protected void makeImportSyncDelta(LensProjectionContext accContext) { PrismObject<ShadowType> syncAccountToAdd = accContext.getObjectOld().clone(); ObjectDelta<ShadowType> syncDelta = ObjectDelta.createAddDelta(syncAccountToAdd); accContext.setSyncDelta(syncDelta); } protected void assertNoUserPrimaryDelta(LensContext<UserType> context) { LensFocusContext<UserType> focusContext = context.getFocusContext(); ObjectDelta<UserType> userPrimaryDelta = focusContext.getPrimaryDelta(); if (userPrimaryDelta == null) { return; } assertTrue("User primary delta is not empty", userPrimaryDelta.isEmpty()); } protected void assertUserPrimaryDelta(LensContext<UserType> context) { LensFocusContext<UserType> focusContext = context.getFocusContext(); ObjectDelta<UserType> userPrimaryDelta = focusContext.getPrimaryDelta(); assertNotNull("User primary delta is null", userPrimaryDelta); assertFalse("User primary delta is empty", userPrimaryDelta.isEmpty()); } protected void assertNoUserSecondaryDelta(LensContext<UserType> context) throws SchemaException { LensFocusContext<UserType> focusContext = context.getFocusContext(); ObjectDelta<UserType> userSecondaryDelta = focusContext.getSecondaryDelta(); if (userSecondaryDelta == null) { return; } assertTrue("User secondary delta is not empty", userSecondaryDelta.isEmpty()); } protected void assertUserSecondaryDelta(LensContext<UserType> context) throws SchemaException { LensFocusContext<UserType> focusContext = context.getFocusContext(); ObjectDelta<UserType> userSecondaryDelta = focusContext.getSecondaryDelta(); assertNotNull("User secondary delta is null", userSecondaryDelta); assertFalse("User secondary delta is empty", userSecondaryDelta.isEmpty()); } @NotNull protected LensContext<UserType> createContextForRoleAssignment(String userOid, String roleOid, QName relation, Consumer<AssignmentType> modificationBlock, OperationResult result) throws SchemaException, ObjectNotFoundException, JAXBException { return createContextForAssignment(UserType.class, userOid, RoleType.class, roleOid, relation, modificationBlock, result); } @NotNull protected <F extends FocusType> LensContext<F> createContextForAssignment(Class<F> focusClass, String focusOid, Class<? extends FocusType> targetClass, String targetOid, QName relation, Consumer<AssignmentType> modificationBlock, OperationResult result) throws SchemaException, ObjectNotFoundException, JAXBException { LensContext<F> context = createLensContext(focusClass); fillContextWithFocus(context, focusClass, focusOid, result); QName targetType = prismContext.getSchemaRegistry().determineTypeForClass(targetClass); assertNotNull("Unknown target class "+targetClass, targetType); addFocusDeltaToContext(context, createAssignmentFocusDelta(focusClass, focusOid, targetOid, targetType, relation, modificationBlock, true)); context.recompute(); display("Input context", context); assertFocusModificationSanity(context); return context; } }