/*
* Copyright (c) 2010-2017 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.intest.manual;
import static com.evolveum.midpoint.test.IntegrationTestTools.display;
import static org.testng.AssertJUnit.assertEquals;
import static org.testng.AssertJUnit.assertFalse;
import static org.testng.AssertJUnit.assertNotNull;
import static org.testng.AssertJUnit.assertTrue;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import javax.xml.datatype.XMLGregorianCalendar;
import javax.xml.namespace.QName;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.annotation.DirtiesContext.ClassMode;
import org.springframework.test.context.ContextConfiguration;
import org.testng.AssertJUnit;
import org.testng.annotations.Test;
import org.w3c.dom.Element;
import com.evolveum.midpoint.common.refinery.RefinedResourceSchemaImpl;
import com.evolveum.midpoint.model.intest.AbstractConfiguredModelIntegrationTest;
import com.evolveum.midpoint.prism.Containerable;
import com.evolveum.midpoint.prism.PrismContainer;
import com.evolveum.midpoint.prism.PrismContainerDefinition;
import com.evolveum.midpoint.prism.PrismContext;
import com.evolveum.midpoint.prism.PrismObject;
import com.evolveum.midpoint.prism.PrismProperty;
import com.evolveum.midpoint.prism.PrismPropertyDefinition;
import com.evolveum.midpoint.prism.PrismPropertyValue;
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.CapabilityUtil;
import com.evolveum.midpoint.schema.GetOperationOptions;
import com.evolveum.midpoint.schema.PointInTimeType;
import com.evolveum.midpoint.schema.SelectorOptions;
import com.evolveum.midpoint.schema.constants.MidPointConstants;
import com.evolveum.midpoint.schema.constants.SchemaConstants;
import com.evolveum.midpoint.schema.internals.InternalsConfig;
import com.evolveum.midpoint.schema.processor.ObjectClassComplexTypeDefinition;
import com.evolveum.midpoint.schema.processor.ResourceAttributeDefinition;
import com.evolveum.midpoint.schema.processor.ResourceSchema;
import com.evolveum.midpoint.schema.processor.ResourceSchemaImpl;
import com.evolveum.midpoint.schema.result.OperationResult;
import com.evolveum.midpoint.schema.util.ObjectTypeUtil;
import com.evolveum.midpoint.schema.util.ResourceTypeUtil;
import com.evolveum.midpoint.task.api.Task;
import com.evolveum.midpoint.test.IntegrationTestTools;
import com.evolveum.midpoint.test.util.TestUtil;
import com.evolveum.midpoint.util.exception.ObjectAlreadyExistsException;
import com.evolveum.midpoint.util.exception.ObjectNotFoundException;
import com.evolveum.midpoint.util.exception.SchemaException;
import com.evolveum.midpoint.util.logging.Trace;
import com.evolveum.midpoint.util.logging.TraceManager;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ActivationStatusType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.AssignmentPolicyEnforcementType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.CachingMetadataType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.CapabilitiesType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.CapabilityCollectionType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.CaseType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ConnectorType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.OperationResultStatusType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.PendingOperationType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ResourceType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowKindType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.XmlSchemaType;
import com.evolveum.midpoint.xml.ns._public.resource.capabilities_3.AbstractWriteCapabilityType;
import com.evolveum.midpoint.xml.ns._public.resource.capabilities_3.ActivationCapabilityType;
import com.evolveum.midpoint.xml.ns._public.resource.capabilities_3.CreateCapabilityType;
import com.evolveum.midpoint.xml.ns._public.resource.capabilities_3.ReadCapabilityType;
import com.evolveum.prism.xml.ns._public.types_3.ItemDeltaType;
import com.evolveum.prism.xml.ns._public.types_3.ObjectDeltaType;
import com.evolveum.prism.xml.ns._public.types_3.ProtectedStringType;
/**
* @author Radovan Semancik
*/
@ContextConfiguration(locations = {"classpath:ctx-model-intest-test-main.xml"})
@DirtiesContext(classMode = ClassMode.AFTER_CLASS)
public abstract class AbstractManualResourceTest extends AbstractConfiguredModelIntegrationTest {
protected static final File TEST_DIR = new File("src/test/resources/manual/");
protected static final File RESOURCE_MANUAL_FILE = new File(TEST_DIR, "resource-manual.xml");
protected static final String RESOURCE_MANUAL_OID = "0ef80ab8-2906-11e7-b81a-3f343e28c264";
protected static final File RESOURCE_SEMI_MANUAL_FILE = new File(TEST_DIR, "resource-semi-manual.xml");
protected static final String RESOURCE_SEMI_MANUAL_OID = "aea5a57c-2904-11e7-8020-7b121a9e3595";
public static final QName RESOURCE_ACCOUNT_OBJECTCLASS = new QName(MidPointConstants.NS_RI, "AccountObjectClass");
private static final Trace LOGGER = TraceManager.getTrace(AbstractManualResourceTest.class);
protected static final String NS_MANUAL_CONF = "http://midpoint.evolveum.com/xml/ns/public/connector/builtin-1/bundle/com.evolveum.midpoint.provisioning.ucf.impl.builtin/ManualConnector";
protected static final QName CONF_PROPERTY_DEFAULT_ASSIGNEE_QNAME = new QName(NS_MANUAL_CONF, "defaultAssignee");
protected static final String USER_WILL_NAME = "will";
protected static final String USER_WILL_GIVEN_NAME = "Will";
protected static final String USER_WILL_FAMILY_NAME = "Turner";
protected static final String USER_WILL_FULL_NAME = "Will Turner";
protected static final String USER_WILL_FULL_NAME_PIRATE = "Pirate Will Turner";
protected static final String ACCOUNT_WILL_DESCRIPTION_MANUAL = "manual";
protected static final String USER_WILL_PASSWORD_OLD = "3lizab3th";
protected static final String USER_WILL_PASSWORD_NEW = "ELIZAbeth";
private static final File TASK_SHADOW_REFRESH_FILE = new File(TEST_DIR, "task-shadow-refresh.xml");
private static final String TASK_SHADOW_REFRESH_OID = "eb8f5be6-2b51-11e7-848c-2fd84a283b03";
protected static final String ATTR_USERNAME = "username";
protected static final QName ATTR_USERNAME_QNAME = new QName(MidPointConstants.NS_RI, ATTR_USERNAME);
protected static final String ATTR_FULLNAME = "fullname";
protected static final QName ATTR_FULLNAME_QNAME = new QName(MidPointConstants.NS_RI, ATTR_FULLNAME);
protected static final String ATTR_DESCRIPTION = "description";
protected static final QName ATTR_DESCRIPTION_QNAME = new QName(MidPointConstants.NS_RI, ATTR_DESCRIPTION);
protected PrismObject<ResourceType> resource;
protected ResourceType resourceType;
protected String userWillOid;
protected String accountWillOid;
protected XMLGregorianCalendar accountWillReqestTimestampStart;
protected XMLGregorianCalendar accountWillReqestTimestampEnd;
protected XMLGregorianCalendar accountWillCompletionTimestampStart;
protected XMLGregorianCalendar accountWillCompletionTimestampEnd;
protected XMLGregorianCalendar accountWillSecondReqestTimestampStart;
protected XMLGregorianCalendar accountWillSecondReqestTimestampEnd;
protected XMLGregorianCalendar accountWillSecondCompletionTimestampStart;
protected XMLGregorianCalendar accountWillSecondCompletionTimestampEnd;
protected String willLastCaseOid;
protected String willSecondLastCaseOid;
protected String accountJackOid;
protected XMLGregorianCalendar accountJackReqestTimestampStart;
protected XMLGregorianCalendar accountJackReqestTimestampEnd;
protected XMLGregorianCalendar accountJackCompletionTimestampStart;
protected XMLGregorianCalendar accountJackCompletionTimestampEnd;
protected String jackLastCaseOid;
@Override
public void initSystem(Task initTask, OperationResult initResult) throws Exception {
super.initSystem(initTask, initResult);
repoAddObjectFromFile(SECURITY_POLICY_FILE, initResult);
importObjectFromFile(getResourceFile(), initResult);
addObject(USER_JACK_FILE);
PrismObject<UserType> userWill = createUserWill();
addObject(userWill, initTask, initResult);
display("User will", userWill);
userWillOid = userWill.getOid();
assumeAssignmentPolicy(AssignmentPolicyEnforcementType.FULL);
}
private PrismObject<UserType> createUserWill() throws SchemaException {
PrismObject<UserType> user = prismContext.getSchemaRegistry().findObjectDefinitionByCompileTimeClass(UserType.class).instantiate();
user.asObjectable()
.name(USER_WILL_NAME)
.givenName(USER_WILL_GIVEN_NAME)
.familyName(USER_WILL_FAMILY_NAME)
.fullName(USER_WILL_FULL_NAME)
.beginActivation().administrativeStatus(ActivationStatusType.ENABLED).<UserType>end()
.beginCredentials().beginPassword().beginValue().setClearValue(USER_WILL_PASSWORD_OLD);
return user;
}
protected abstract File getResourceFile();
protected abstract String getResourceOid();
protected boolean supportsBackingStore() {
return false;
}
@Test
public void test000Sanity() throws Exception {
final String TEST_NAME = "test000Sanity";
TestUtil.displayTestTile(TEST_NAME);
OperationResult result = new OperationResult(AbstractManualResourceTest.class.getName()
+ "." + TEST_NAME);
ResourceType repoResource = repositoryService.getObject(ResourceType.class, getResourceOid(),
null, result).asObjectable();
assertNotNull("No connector ref", repoResource.getConnectorRef());
String connectorOid = repoResource.getConnectorRef().getOid();
assertNotNull("No connector ref OID", connectorOid);
ConnectorType repoConnector = repositoryService
.getObject(ConnectorType.class, connectorOid, null, result).asObjectable();
assertNotNull(repoConnector);
display("Manual Connector", repoConnector);
// Check connector schema
IntegrationTestTools.assertConnectorSchemaSanity(repoConnector, prismContext);
PrismObject<UserType> userWill = getUser(userWillOid);
assertUser(userWill, userWillOid, USER_WILL_NAME, USER_WILL_FULL_NAME, USER_WILL_GIVEN_NAME, USER_WILL_FAMILY_NAME);
assertAdministrativeStatus(userWill, ActivationStatusType.ENABLED);
assertUserPassword(userWill, USER_WILL_PASSWORD_OLD);
}
@Test
public void test003Connection() throws Exception {
final String TEST_NAME = "test003Connection";
TestUtil.displayTestTile(TEST_NAME);
// GIVEN
Task task = createTask(TEST_NAME);
OperationResult result = task.getResult();
// Check that there is a schema, but no capabilities before test (pre-condition)
ResourceType resourceBefore = repositoryService.getObject(ResourceType.class, getResourceOid(),
null, result).asObjectable();
Element resourceXsdSchemaElementBefore = ResourceTypeUtil.getResourceXsdSchema(resourceBefore);
assertResourceSchemaBeforeTest(resourceXsdSchemaElementBefore);
CapabilitiesType capabilities = resourceBefore.getCapabilities();
if (capabilities != null) {
AssertJUnit.assertNull("Native capabilities present before test connection. Bad test setup?", capabilities.getNative());
}
// WHEN
OperationResult testResult = modelService.testResource(getResourceOid(), task);
// THEN
display("Test result", testResult);
TestUtil.assertSuccess("Test resource failed (result)", testResult);
PrismObject<ResourceType> resourceRepoAfter = repositoryService.getObject(ResourceType.class, getResourceOid(), null, result);
ResourceType resourceTypeRepoAfter = resourceRepoAfter.asObjectable();
display("Resource after test", resourceTypeRepoAfter);
XmlSchemaType xmlSchemaTypeAfter = resourceTypeRepoAfter.getSchema();
assertNotNull("No schema after test connection", xmlSchemaTypeAfter);
Element resourceXsdSchemaElementAfter = ResourceTypeUtil.getResourceXsdSchema(resourceTypeRepoAfter);
assertNotNull("No schema after test connection", resourceXsdSchemaElementAfter);
String resourceXml = prismContext.serializeObjectToString(resourceRepoAfter, PrismContext.LANG_XML);
display("Resource XML", resourceXml);
CachingMetadataType cachingMetadata = xmlSchemaTypeAfter.getCachingMetadata();
assertNotNull("No caching metadata", cachingMetadata);
assertNotNull("No retrievalTimestamp", cachingMetadata.getRetrievalTimestamp());
assertNotNull("No serialNumber", cachingMetadata.getSerialNumber());
Element xsdElement = ObjectTypeUtil.findXsdElement(xmlSchemaTypeAfter);
ResourceSchema parsedSchema = ResourceSchemaImpl.parse(xsdElement, resourceBefore.toString(), prismContext);
assertNotNull("No schema after parsing", parsedSchema);
// schema will be checked in next test
}
protected abstract void assertResourceSchemaBeforeTest(Element resourceXsdSchemaElementBefore);
@Test
public void test004Configuration() throws Exception {
final String TEST_NAME = "test004Configuration";
TestUtil.displayTestTile(TEST_NAME);
// GIVEN
OperationResult result = new OperationResult(AbstractManualResourceTest.class.getName()
+ "." + TEST_NAME);
// WHEN
resource = modelService.getObject(ResourceType.class, getResourceOid(), null, null, result);
resourceType = resource.asObjectable();
PrismContainer<Containerable> configurationContainer = resource.findContainer(ResourceType.F_CONNECTOR_CONFIGURATION);
assertNotNull("No configuration container", configurationContainer);
PrismContainerDefinition confContDef = configurationContainer.getDefinition();
assertNotNull("No configuration container definition", confContDef);
PrismProperty<String> propDefaultAssignee = configurationContainer.findProperty(CONF_PROPERTY_DEFAULT_ASSIGNEE_QNAME);
assertNotNull("No defaultAssignee conf prop", propDefaultAssignee);
// assertNotNull("No configuration properties container", confingurationPropertiesContainer);
// PrismContainerDefinition confPropDef = confingurationPropertiesContainer.getDefinition();
// assertNotNull("No configuration properties container definition", confPropDef);
}
@Test
public void test005ParsedSchema() throws Exception {
final String TEST_NAME = "test005ParsedSchema";
TestUtil.displayTestTile(TEST_NAME);
// GIVEN
OperationResult result = new OperationResult(AbstractManualResourceTest.class.getName() + "." + TEST_NAME);
// THEN
// The returned type should have the schema pre-parsed
assertNotNull(RefinedResourceSchemaImpl.hasParsedSchema(resourceType));
// Also test if the utility method returns the same thing
ResourceSchema resourceSchema = RefinedResourceSchemaImpl.getResourceSchema(resourceType, prismContext);
display("Parsed resource schema", resourceSchema);
// 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", resourceSchema == RefinedResourceSchemaImpl.getResourceSchema(resourceType, prismContext));
ObjectClassComplexTypeDefinition accountDef = resourceSchema.findObjectClassDefinition(RESOURCE_ACCOUNT_OBJECTCLASS);
assertNotNull("Account definition is missing", accountDef);
assertNotNull("Null identifiers in account", accountDef.getPrimaryIdentifiers());
assertFalse("Empty identifiers in account", accountDef.getPrimaryIdentifiers().isEmpty());
assertNotNull("No naming attribute in account", accountDef.getNamingAttribute());
assertEquals("Unexpected number of definitions", getNumberOfAccountAttributeDefinitions(), accountDef.getDefinitions().size());
ResourceAttributeDefinition<String> usernameDef = accountDef.findAttributeDefinition(ATTR_USERNAME);
assertNotNull("No definition for username", usernameDef);
assertEquals(1, usernameDef.getMaxOccurs());
assertEquals(1, usernameDef.getMinOccurs());
assertTrue("No username create", usernameDef.canAdd());
assertTrue("No username update", usernameDef.canModify());
assertTrue("No username read", usernameDef.canRead());
ResourceAttributeDefinition<String> fullnameDef = accountDef.findAttributeDefinition(ATTR_FULLNAME);
assertNotNull("No definition for fullname", fullnameDef);
assertEquals(1, fullnameDef.getMaxOccurs());
assertEquals(0, fullnameDef.getMinOccurs());
assertTrue("No fullname create", fullnameDef.canAdd());
assertTrue("No fullname update", fullnameDef.canModify());
assertTrue("No fullname read", fullnameDef.canRead());
}
protected int getNumberOfAccountAttributeDefinitions() {
return 4;
}
@Test
public void test006Capabilities() throws Exception {
final String TEST_NAME = "test006Capabilities";
TestUtil.displayTestTile(TEST_NAME);
// GIVEN
OperationResult result = new OperationResult(AbstractManualResourceTest.class.getName()+"."+TEST_NAME);
// WHEN
ResourceType resource = modelService.getObject(ResourceType.class, getResourceOid(), null, null, result).asObjectable();
// THEN
display("Resource from provisioninig", resource);
display("Resource from provisioninig (XML)", PrismTestUtil.serializeObjectToString(resource.asPrismObject(), PrismContext.LANG_XML));
CapabilityCollectionType nativeCapabilities = resource.getCapabilities().getNative();
List<Object> nativeCapabilitiesList = nativeCapabilities.getAny();
assertFalse("Empty capabilities returned",nativeCapabilitiesList.isEmpty());
CreateCapabilityType capCreate = CapabilityUtil.getCapability(nativeCapabilitiesList, CreateCapabilityType.class);
assertNotNull("Missing create capability", capCreate);
assertManual(capCreate);
ActivationCapabilityType capAct = CapabilityUtil.getCapability(nativeCapabilitiesList, ActivationCapabilityType.class);
assertNotNull("Missing activation capability", capAct);
ReadCapabilityType capRead = CapabilityUtil.getCapability(nativeCapabilitiesList, ReadCapabilityType.class);
assertNotNull("Missing read capability" ,capRead);
assertEquals("Wrong caching-only setting in read capability", Boolean.TRUE, capRead.isCachingOnly());
List<Object> effectiveCapabilities = ResourceTypeUtil.getEffectiveCapabilities(resource);
for (Object capability : effectiveCapabilities) {
System.out.println("Capability: "+CapabilityUtil.getCapabilityDisplayName(capability)+" : "+capability);
}
}
@Test
public void test100AssignAccountWill() throws Exception {
assignAccountWill("test100AssignAccountWill");
}
@Test
public void test102GetAccountWillFuture() throws Exception {
final String TEST_NAME = "test102GetAccountWillFuture";
displayTestTile(TEST_NAME);
// GIVEN
Task task = createTask(TEST_NAME);
OperationResult result = task.getResult();
Collection<SelectorOptions<GetOperationOptions>> options = SelectorOptions.createCollection(GetOperationOptions.createPointInTimeType(PointInTimeType.FUTURE));
// WHEN
displayWhen(TEST_NAME);
PrismObject<ShadowType> shadowModel = modelService.getObject(ShadowType.class, accountWillOid, options, task, result);
// THEN
displayThen(TEST_NAME);
assertSuccess(result);
display("Model shadow", shadowModel);
ShadowType shadowTypeProvisioning = shadowModel.asObjectable();
assertShadowName(shadowModel, USER_WILL_NAME);
assertEquals("Wrong kind (provisioning)", ShadowKindType.ACCOUNT, shadowTypeProvisioning.getKind());
assertAttribute(shadowModel, ATTR_USERNAME_QNAME, USER_WILL_NAME);
assertAttribute(shadowModel, ATTR_FULLNAME_QNAME, USER_WILL_FULL_NAME);
assertNoAttribute(shadowModel, ATTR_DESCRIPTION_QNAME);
assertShadowActivationAdministrativeStatus(shadowModel, ActivationStatusType.ENABLED);
assertShadowExists(shadowModel, true);
// TODO
// assertShadowPassword(shadowProvisioning);
}
@Test
public void test104RecomputeWill() throws Exception {
final String TEST_NAME = "test104RecomputeWill";
displayTestTile(TEST_NAME);
// GIVEN
Task task = createTask(TEST_NAME);
OperationResult result = task.getResult();
// WHEN
displayWhen(TEST_NAME);
recomputeUser(userWillOid, task, result);
// THEN
displayThen(TEST_NAME);
assertSuccess(result);
PrismObject<ShadowType> shadowRepo = repositoryService.getObject(ShadowType.class, accountWillOid, null, result);
display("Repo shadow", shadowRepo);
assertSinglePendingOperation(shadowRepo, accountWillReqestTimestampStart, accountWillReqestTimestampEnd);
assertAttribute(shadowRepo, ATTR_USERNAME_QNAME, USER_WILL_NAME);
assertAttributeFromCache(shadowRepo, ATTR_FULLNAME_QNAME, USER_WILL_FULL_NAME);
assertNoAttribute(shadowRepo, ATTR_DESCRIPTION_QNAME);
assertShadowActivationAdministrativeStatusFromCache(shadowRepo, ActivationStatusType.ENABLED);
assertNoShadowPassword(shadowRepo);
assertShadowExists(shadowRepo, false);
PrismObject<ShadowType> shadowModel = modelService.getObject(ShadowType.class,
accountWillOid, null, task, result);
display("Model shadow", shadowModel);
ShadowType shadowTypeProvisioning = shadowModel.asObjectable();
assertShadowName(shadowModel, USER_WILL_NAME);
assertEquals("Wrong kind (provisioning)", ShadowKindType.ACCOUNT, shadowTypeProvisioning.getKind());
assertAttribute(shadowModel, ATTR_USERNAME_QNAME, USER_WILL_NAME);
assertAttributeFromCache(shadowModel, ATTR_FULLNAME_QNAME, USER_WILL_FULL_NAME);
assertNoAttribute(shadowModel, ATTR_DESCRIPTION_QNAME);
assertShadowActivationAdministrativeStatusFromCache(shadowModel, ActivationStatusType.ENABLED);
assertNoShadowPassword(shadowModel);
PendingOperationType pendingOperation = assertSinglePendingOperation(shadowModel, accountWillReqestTimestampStart, accountWillReqestTimestampEnd);
assertCase(pendingOperation.getAsynchronousOperationReference(), SchemaConstants.CASE_STATE_OPEN);
}
protected void backingStoreAddWill() throws IOException {
// nothing to do here
}
@Test
public void test106AddToBackingStoreAndGetAccountWill() throws Exception {
final String TEST_NAME = "test106AddToBackingStoreAndGetAccountWill";
displayTestTile(TEST_NAME);
// GIVEN
Task task = createTask(TEST_NAME);
OperationResult result = task.getResult();
backingStoreAddWill();
// WHEN
displayWhen(TEST_NAME);
PrismObject<ShadowType> shadowModel = modelService.getObject(ShadowType.class, accountWillOid, null, task, result);
// THEN
displayThen(TEST_NAME);
assertSuccess(result);
display("Model shadow", shadowModel);
ShadowType shadowTypeProvisioning = shadowModel.asObjectable();
assertShadowName(shadowModel, USER_WILL_NAME);
assertEquals("Wrong kind (provisioning)", ShadowKindType.ACCOUNT, shadowTypeProvisioning.getKind());
assertAttribute(shadowModel, ATTR_USERNAME_QNAME, USER_WILL_NAME);
assertAttribute(shadowModel, ATTR_FULLNAME_QNAME, USER_WILL_FULL_NAME);
assertAttributeFromBackingStore(shadowModel, ATTR_DESCRIPTION_QNAME, ACCOUNT_WILL_DESCRIPTION_MANUAL);
assertShadowActivationAdministrativeStatus(shadowModel, ActivationStatusType.ENABLED);
assertShadowExists(shadowModel, supportsBackingStore());
assertShadowPassword(shadowModel);
PrismObject<ShadowType> shadowRepo = repositoryService.getObject(ShadowType.class, accountWillOid, null, result);
display("Repo shadow", shadowRepo);
assertSinglePendingOperation(shadowRepo, accountWillReqestTimestampStart, accountWillReqestTimestampEnd);
assertAttribute(shadowRepo, ATTR_USERNAME_QNAME, USER_WILL_NAME);
assertAttributeFromCache(shadowRepo, ATTR_FULLNAME_QNAME, USER_WILL_FULL_NAME);
assertNoAttribute(shadowRepo, ATTR_DESCRIPTION_QNAME);
assertShadowActivationAdministrativeStatusFromCache(shadowRepo, ActivationStatusType.ENABLED);
assertNoShadowPassword(shadowRepo);
assertShadowExists(shadowRepo, supportsBackingStore());
}
@Test
public void test108GetAccountWillFuture() throws Exception {
final String TEST_NAME = "test108GetAccountWillFuture";
displayTestTile(TEST_NAME);
// GIVEN
Task task = createTask(TEST_NAME);
OperationResult result = task.getResult();
Collection<SelectorOptions<GetOperationOptions>> options = SelectorOptions.createCollection(GetOperationOptions.createPointInTimeType(PointInTimeType.FUTURE));
// WHEN
displayWhen(TEST_NAME);
PrismObject<ShadowType> shadowModel = modelService.getObject(ShadowType.class, accountWillOid, options, task, result);
// THEN
displayThen(TEST_NAME);
assertSuccess(result);
display("Model shadow", shadowModel);
ShadowType shadowTypeProvisioning = shadowModel.asObjectable();
assertShadowName(shadowModel, USER_WILL_NAME);
assertEquals("Wrong kind (provisioning)", ShadowKindType.ACCOUNT, shadowTypeProvisioning.getKind());
assertAttribute(shadowModel, ATTR_USERNAME_QNAME, USER_WILL_NAME);
assertAttribute(shadowModel, ATTR_FULLNAME_QNAME, USER_WILL_FULL_NAME);
assertAttributeFromBackingStore(shadowModel, ATTR_DESCRIPTION_QNAME, ACCOUNT_WILL_DESCRIPTION_MANUAL);
assertShadowActivationAdministrativeStatus(shadowModel, ActivationStatusType.ENABLED);
assertShadowExists(shadowModel, true);
// TODO
// assertShadowPassword(shadowProvisioning);
PrismObject<ShadowType> shadowRepo = repositoryService.getObject(ShadowType.class, accountWillOid, null, result);
display("Repo shadow", shadowRepo);
assertSinglePendingOperation(shadowRepo, accountWillReqestTimestampStart, accountWillReqestTimestampEnd);
assertAttribute(shadowRepo, ATTR_USERNAME_QNAME, USER_WILL_NAME);
assertAttributeFromCache(shadowRepo, ATTR_FULLNAME_QNAME, USER_WILL_FULL_NAME);
assertNoAttribute(shadowRepo, ATTR_DESCRIPTION_QNAME);
assertShadowActivationAdministrativeStatusFromCache(shadowRepo, ActivationStatusType.ENABLED);
assertNoShadowPassword(shadowRepo);
assertShadowExists(shadowRepo, supportsBackingStore());
}
/**
* Case is closed. The operation is complete.
*/
@Test
public void test110CloseCaseAndRecomputeWill() throws Exception {
final String TEST_NAME = "test110CloseCaseAndRecomputeWill";
displayTestTile(TEST_NAME);
// GIVEN
Task task = createTask(TEST_NAME);
OperationResult result = task.getResult();
closeCase(willLastCaseOid);
accountWillCompletionTimestampStart = clock.currentTimeXMLGregorianCalendar();
// WHEN
displayWhen(TEST_NAME);
// We need reconcile and not recompute here. We need to fetch the updated case status.
reconcileUser(userWillOid, task, result);
// THEN
displayThen(TEST_NAME);
assertSuccess(result);
accountWillCompletionTimestampEnd = clock.currentTimeXMLGregorianCalendar();
assertWillAfterCreateCaseClosed(TEST_NAME, true);
}
/**
* ff 5min, everything should be the same (grace not expired yet)
*/
@Test
public void test120RecomputeWillAfter5min() throws Exception {
final String TEST_NAME = "test120RecomputeWillAfter5min";
displayTestTile(TEST_NAME);
// GIVEN
Task task = createTask(TEST_NAME);
OperationResult result = task.getResult();
clock.overrideDuration("PT5M");
// WHEN
displayWhen(TEST_NAME);
recomputeUser(userWillOid, task, result);
// THEN
displayThen(TEST_NAME);
assertSuccess(result);
PrismObject<ShadowType> shadowRepo = repositoryService.getObject(ShadowType.class, accountWillOid, null, result);
display("Repo shadow", shadowRepo);
assertSinglePendingOperation(shadowRepo,
accountWillReqestTimestampStart, accountWillReqestTimestampEnd,
OperationResultStatusType.SUCCESS,
accountWillCompletionTimestampStart, accountWillCompletionTimestampEnd);
PrismObject<ShadowType> shadowModel = modelService.getObject(ShadowType.class,
accountWillOid, null, task, result);
PendingOperationType pendingOperation = assertSinglePendingOperation(shadowModel,
accountWillReqestTimestampStart, accountWillReqestTimestampEnd,
OperationResultStatusType.SUCCESS,
accountWillCompletionTimestampStart, accountWillCompletionTimestampEnd);
assertCase(willLastCaseOid, SchemaConstants.CASE_STATE_CLOSED);
}
/**
* ff 20min, grace should expire
*/
@Test
public void test130RecomputeWillAfter25min() throws Exception {
final String TEST_NAME = "test130RecomputeWillAfter25min";
displayTestTile(TEST_NAME);
// GIVEN
Task task = createTask(TEST_NAME);
OperationResult result = task.getResult();
clock.overrideDuration("PT20M");
// WHEN
displayWhen(TEST_NAME);
recomputeUser(userWillOid, task, result);
// THEN
displayThen(TEST_NAME);
assertSuccess(result);
PrismObject<ShadowType> shadowRepo = repositoryService.getObject(ShadowType.class, accountWillOid, null, result);
display("Repo shadow", shadowRepo);
assertNoPendingOperation(shadowRepo);
PrismObject<ShadowType> shadowModel = modelService.getObject(ShadowType.class,
accountWillOid, null, task, result);
assertNoPendingOperation(shadowModel);
assertCase(willLastCaseOid, SchemaConstants.CASE_STATE_CLOSED);
}
@Test
public void test200ModifyUserWillFullname() throws Exception {
final String TEST_NAME = "test200ModifyUserWillFullname";
displayTestTile(TEST_NAME);
// GIVEN
Task task = createTask(TEST_NAME);
OperationResult result = task.getResult();
ObjectDelta<ShadowType> delta = ObjectDelta.createModificationReplaceProperty(ShadowType.class,
accountWillOid, new ItemPath(ShadowType.F_ATTRIBUTES, ATTR_FULLNAME_QNAME), prismContext,
USER_WILL_FULL_NAME_PIRATE);
display("ObjectDelta", delta);
accountWillReqestTimestampStart = clock.currentTimeXMLGregorianCalendar();
// WHEN
displayWhen(TEST_NAME);
modifyUserReplace(userWillOid, UserType.F_FULL_NAME, task, result, createPolyString(USER_WILL_FULL_NAME_PIRATE));
// THEN
displayThen(TEST_NAME);
display("result", result);
willLastCaseOid = assertInProgress(result);
accountWillReqestTimestampEnd = clock.currentTimeXMLGregorianCalendar();
PrismObject<ShadowType> shadowRepo = repositoryService.getObject(ShadowType.class, accountWillOid, null, result);
display("Repo shadow", shadowRepo);
PendingOperationType pendingOperation = assertSinglePendingOperation(shadowRepo, accountWillReqestTimestampStart, accountWillReqestTimestampEnd);
assertNotNull("No ID in pending operation", pendingOperation.getId());
// Still old data in the repo. The operation is not completed yet.
assertShadowActivationAdministrativeStatusFromCache(shadowRepo, ActivationStatusType.ENABLED);
assertAttribute(shadowRepo, ATTR_USERNAME_QNAME, USER_WILL_NAME);
assertAttributeFromCache(shadowRepo, ATTR_FULLNAME_QNAME, USER_WILL_FULL_NAME);
PrismObject<ShadowType> shadowModel = modelService.getObject(ShadowType.class,
accountWillOid, null, task, result);
display("Model shadow", shadowModel);
ShadowType shadowTypeProvisioning = shadowModel.asObjectable();
assertShadowName(shadowModel, USER_WILL_NAME);
assertEquals("Wrong kind (provisioning)", ShadowKindType.ACCOUNT, shadowTypeProvisioning.getKind());
assertShadowActivationAdministrativeStatus(shadowModel, ActivationStatusType.ENABLED);
assertAttribute(shadowModel, ATTR_USERNAME_QNAME, USER_WILL_NAME);
assertAttribute(shadowModel, ATTR_FULLNAME_QNAME, USER_WILL_FULL_NAME);
assertAttributeFromBackingStore(shadowModel, ATTR_DESCRIPTION_QNAME, ACCOUNT_WILL_DESCRIPTION_MANUAL);
assertShadowPassword(shadowModel);
assertSinglePendingOperation(shadowModel, accountWillReqestTimestampStart, accountWillReqestTimestampEnd);
PrismObject<ShadowType> shadowProvisioningFuture = modelService.getObject(ShadowType.class,
accountWillOid,
SelectorOptions.createCollection(GetOperationOptions.createPointInTimeType(PointInTimeType.FUTURE)),
task, result);
display("Model shadow (future)", shadowProvisioningFuture);
assertShadowName(shadowProvisioningFuture, USER_WILL_NAME);
assertEquals("Wrong kind (provisioning)", ShadowKindType.ACCOUNT, shadowProvisioningFuture.asObjectable().getKind());
assertShadowActivationAdministrativeStatus(shadowProvisioningFuture, ActivationStatusType.ENABLED);
assertAttribute(shadowProvisioningFuture, ATTR_USERNAME_QNAME, USER_WILL_NAME);
assertAttribute(shadowProvisioningFuture, ATTR_FULLNAME_QNAME, USER_WILL_FULL_NAME_PIRATE);
assertAttributeFromBackingStore(shadowProvisioningFuture, ATTR_DESCRIPTION_QNAME, ACCOUNT_WILL_DESCRIPTION_MANUAL);
assertShadowPassword(shadowProvisioningFuture);
assertNotNull("No async reference in result", willLastCaseOid);
assertCase(willLastCaseOid, SchemaConstants.CASE_STATE_OPEN);
}
@Test
public void test202RecomputeWill() throws Exception {
final String TEST_NAME = "test202RecomputeWill";
displayTestTile(TEST_NAME);
// GIVEN
Task task = createTask(TEST_NAME);
OperationResult result = task.getResult();
// WHEN
displayWhen(TEST_NAME);
recomputeUser(userWillOid, task, result);
// THEN
displayThen(TEST_NAME);
assertSuccess(result);
PrismObject<ShadowType> shadowRepo = repositoryService.getObject(ShadowType.class, accountWillOid, null, result);
display("Repo shadow", shadowRepo);
PendingOperationType pendingOperation = assertSinglePendingOperation(shadowRepo, accountWillReqestTimestampStart, accountWillReqestTimestampEnd);
assertNotNull("No ID in pending operation", pendingOperation.getId());
// Still old data in the repo. The operation is not completed yet.
assertShadowActivationAdministrativeStatusFromCache(shadowRepo, ActivationStatusType.ENABLED);
assertAttribute(shadowRepo, ATTR_USERNAME_QNAME, USER_WILL_NAME);
assertAttributeFromCache(shadowRepo, ATTR_FULLNAME_QNAME, USER_WILL_FULL_NAME);
PrismObject<ShadowType> shadowModel = modelService.getObject(ShadowType.class,
accountWillOid, null, task, result);
display("Model shadow", shadowModel);
ShadowType shadowTypeProvisioning = shadowModel.asObjectable();
assertShadowName(shadowModel, USER_WILL_NAME);
assertEquals("Wrong kind (provisioning)", ShadowKindType.ACCOUNT, shadowTypeProvisioning.getKind());
assertShadowActivationAdministrativeStatus(shadowModel, ActivationStatusType.ENABLED);
assertAttribute(shadowModel, ATTR_USERNAME_QNAME, USER_WILL_NAME);
assertAttribute(shadowModel, ATTR_FULLNAME_QNAME, USER_WILL_FULL_NAME);
assertShadowPassword(shadowModel);
assertSinglePendingOperation(shadowModel, accountWillReqestTimestampStart, accountWillReqestTimestampEnd);
PrismObject<ShadowType> shadowProvisioningFuture = modelService.getObject(ShadowType.class,
accountWillOid,
SelectorOptions.createCollection(GetOperationOptions.createPointInTimeType(PointInTimeType.FUTURE)),
task, result);
display("Model shadow (future)", shadowProvisioningFuture);
assertShadowName(shadowProvisioningFuture, USER_WILL_NAME);
assertEquals("Wrong kind (provisioning)", ShadowKindType.ACCOUNT, shadowProvisioningFuture.asObjectable().getKind());
assertShadowActivationAdministrativeStatus(shadowProvisioningFuture, ActivationStatusType.ENABLED);
assertAttribute(shadowProvisioningFuture, ATTR_USERNAME_QNAME, USER_WILL_NAME);
assertAttribute(shadowProvisioningFuture, ATTR_FULLNAME_QNAME, USER_WILL_FULL_NAME_PIRATE);
assertShadowPassword(shadowProvisioningFuture);
assertCase(willLastCaseOid, SchemaConstants.CASE_STATE_OPEN);
}
/**
* Case is closed. The operation is complete.
*/
@Test
public void test204CloseCaseAndRecomputeWill() throws Exception {
final String TEST_NAME = "test204CloseCaseAndRecomputeWill";
displayTestTile(TEST_NAME);
// GIVEN
Task task = createTask(TEST_NAME);
OperationResult result = task.getResult();
closeCase(willLastCaseOid);
accountWillCompletionTimestampStart = clock.currentTimeXMLGregorianCalendar();
// WHEN
displayWhen(TEST_NAME);
recomputeUser(userWillOid, task, result);
// THEN
displayThen(TEST_NAME);
assertSuccess(result);
accountWillCompletionTimestampEnd = clock.currentTimeXMLGregorianCalendar();
PrismObject<ShadowType> shadowRepo = repositoryService.getObject(ShadowType.class, accountWillOid, null, result);
display("Repo shadow", shadowRepo);
assertSinglePendingOperation(shadowRepo,
accountWillReqestTimestampStart, accountWillReqestTimestampEnd,
OperationResultStatusType.SUCCESS,
accountWillCompletionTimestampStart, accountWillCompletionTimestampEnd);
assertShadowActivationAdministrativeStatusFromCache(shadowRepo, ActivationStatusType.ENABLED);
assertAttribute(shadowRepo, ATTR_USERNAME_QNAME, USER_WILL_NAME);
assertAttributeFromCache(shadowRepo, ATTR_FULLNAME_QNAME, USER_WILL_FULL_NAME_PIRATE);
PrismObject<ShadowType> shadowProvisioning = modelService.getObject(ShadowType.class,
accountWillOid, null, task, result);
display("Model shadow", shadowProvisioning);
ShadowType shadowTypeProvisioning = shadowProvisioning.asObjectable();
assertShadowName(shadowProvisioning, USER_WILL_NAME);
assertEquals("Wrong kind (provisioning)", ShadowKindType.ACCOUNT, shadowTypeProvisioning.getKind());
assertShadowActivationAdministrativeStatus(shadowProvisioning, ActivationStatusType.ENABLED);
assertAttribute(shadowProvisioning, ATTR_USERNAME_QNAME, USER_WILL_NAME);
if (supportsBackingStore()) {
assertAttribute(shadowProvisioning, ATTR_FULLNAME_QNAME, USER_WILL_FULL_NAME);
} else {
assertAttribute(shadowProvisioning, ATTR_FULLNAME_QNAME, USER_WILL_FULL_NAME_PIRATE);
}
assertAttributeFromBackingStore(shadowProvisioning, ATTR_DESCRIPTION_QNAME, ACCOUNT_WILL_DESCRIPTION_MANUAL);
assertShadowPassword(shadowProvisioning);
PendingOperationType pendingOperation = assertSinglePendingOperation(shadowProvisioning,
accountWillReqestTimestampStart, accountWillReqestTimestampEnd,
OperationResultStatusType.SUCCESS,
accountWillCompletionTimestampStart, accountWillCompletionTimestampEnd);
PrismObject<ShadowType> shadowProvisioningFuture = modelService.getObject(ShadowType.class,
accountWillOid,
SelectorOptions.createCollection(GetOperationOptions.createPointInTimeType(PointInTimeType.FUTURE)),
task, result);
display("Model shadow (future)", shadowProvisioningFuture);
assertShadowName(shadowProvisioningFuture, USER_WILL_NAME);
assertEquals("Wrong kind (provisioning)", ShadowKindType.ACCOUNT, shadowProvisioningFuture.asObjectable().getKind());
assertShadowActivationAdministrativeStatus(shadowProvisioningFuture, ActivationStatusType.ENABLED);
assertAttribute(shadowProvisioningFuture, ATTR_USERNAME_QNAME, USER_WILL_NAME);
assertAttribute(shadowProvisioningFuture, ATTR_FULLNAME_QNAME, USER_WILL_FULL_NAME_PIRATE);
assertAttributeFromBackingStore(shadowProvisioningFuture, ATTR_DESCRIPTION_QNAME, ACCOUNT_WILL_DESCRIPTION_MANUAL);
assertShadowPassword(shadowProvisioningFuture);
assertCase(willLastCaseOid, SchemaConstants.CASE_STATE_CLOSED);
}
/**
* ff 5min, everything should be the same (grace not expired yet)
*/
@Test
public void test210RecomputeWillAfter5min() throws Exception {
final String TEST_NAME = "test210RecomputeWillAfter5min";
displayTestTile(TEST_NAME);
// GIVEN
Task task = createTask(TEST_NAME);
OperationResult result = task.getResult();
clock.overrideDuration("PT5M");
// WHEN
displayWhen(TEST_NAME);
recomputeUser(userWillOid, task, result);
// THEN
displayThen(TEST_NAME);
assertSuccess(result);
PrismObject<ShadowType> shadowRepo = repositoryService.getObject(ShadowType.class, accountWillOid, null, result);
display("Repo shadow", shadowRepo);
assertSinglePendingOperation(shadowRepo,
accountWillReqestTimestampStart, accountWillReqestTimestampEnd,
OperationResultStatusType.SUCCESS,
accountWillCompletionTimestampStart, accountWillCompletionTimestampEnd);
PrismObject<ShadowType> shadowModel = modelService.getObject(ShadowType.class,
accountWillOid, null, task, result);
assertShadowActivationAdministrativeStatus(shadowModel, ActivationStatusType.ENABLED);
assertAttribute(shadowModel, ATTR_USERNAME_QNAME, USER_WILL_NAME);
if (supportsBackingStore()) {
assertAttribute(shadowModel, ATTR_FULLNAME_QNAME, USER_WILL_FULL_NAME);
} else {
assertAttribute(shadowModel, ATTR_FULLNAME_QNAME, USER_WILL_FULL_NAME_PIRATE);
}
assertAttributeFromBackingStore(shadowModel, ATTR_DESCRIPTION_QNAME, ACCOUNT_WILL_DESCRIPTION_MANUAL);
assertShadowPassword(shadowModel);
PendingOperationType pendingOperation = assertSinglePendingOperation(shadowModel,
accountWillReqestTimestampStart, accountWillReqestTimestampEnd,
OperationResultStatusType.SUCCESS,
accountWillCompletionTimestampStart, accountWillCompletionTimestampEnd);
PrismObject<ShadowType> shadowModelFuture = modelService.getObject(ShadowType.class,
accountWillOid,
SelectorOptions.createCollection(GetOperationOptions.createPointInTimeType(PointInTimeType.FUTURE)),
task, result);
display("Model shadow (future)", shadowModelFuture);
assertShadowName(shadowModelFuture, USER_WILL_NAME);
assertEquals("Wrong kind (provisioning)", ShadowKindType.ACCOUNT, shadowModelFuture.asObjectable().getKind());
assertShadowActivationAdministrativeStatus(shadowModelFuture, ActivationStatusType.ENABLED);
assertAttribute(shadowModelFuture, ATTR_USERNAME_QNAME, USER_WILL_NAME);
assertAttribute(shadowModelFuture, ATTR_FULLNAME_QNAME, USER_WILL_FULL_NAME_PIRATE);
assertAttributeFromBackingStore(shadowModelFuture, ATTR_DESCRIPTION_QNAME, ACCOUNT_WILL_DESCRIPTION_MANUAL);
assertShadowPassword(shadowModelFuture);
assertCase(willLastCaseOid, SchemaConstants.CASE_STATE_CLOSED);
}
protected void backingStoreUpdateWill(String newFullName, ActivationStatusType newAdministrativeStatus, String password) throws IOException {
// nothing to do here
}
@Test
public void test212UpdateBackingStoreAndGetAccountWill() throws Exception {
final String TEST_NAME = "test212UpdateBackingStoreAndGetAccountWill";
displayTestTile(TEST_NAME);
// GIVEN
Task task = createTask(TEST_NAME);
OperationResult result = task.getResult();
backingStoreUpdateWill(USER_WILL_FULL_NAME_PIRATE, ActivationStatusType.ENABLED, USER_WILL_PASSWORD_OLD);
// WHEN
displayWhen(TEST_NAME);
PrismObject<ShadowType> shadowModel = modelService.getObject(ShadowType.class,
accountWillOid, null, task, result);
// THEN
displayThen(TEST_NAME);
assertSuccess(result);
assertShadowActivationAdministrativeStatus(shadowModel, ActivationStatusType.ENABLED);
assertAttribute(shadowModel, ATTR_USERNAME_QNAME, USER_WILL_NAME);
assertAttribute(shadowModel, ATTR_FULLNAME_QNAME, USER_WILL_FULL_NAME_PIRATE);
assertAttributeFromBackingStore(shadowModel, ATTR_DESCRIPTION_QNAME, ACCOUNT_WILL_DESCRIPTION_MANUAL);
assertShadowPassword(shadowModel);
PendingOperationType pendingOperation = assertSinglePendingOperation(shadowModel,
accountWillReqestTimestampStart, accountWillReqestTimestampEnd,
OperationResultStatusType.SUCCESS,
accountWillCompletionTimestampStart, accountWillCompletionTimestampEnd);
PrismObject<ShadowType> shadowRepo = repositoryService.getObject(ShadowType.class, accountWillOid, null, result);
display("Repo shadow", shadowRepo);
assertSinglePendingOperation(shadowRepo,
accountWillReqestTimestampStart, accountWillReqestTimestampEnd,
OperationResultStatusType.SUCCESS,
accountWillCompletionTimestampStart, accountWillCompletionTimestampEnd);
PrismObject<ShadowType> shadowModelFuture = modelService.getObject(ShadowType.class,
accountWillOid,
SelectorOptions.createCollection(GetOperationOptions.createPointInTimeType(PointInTimeType.FUTURE)),
task, result);
display("Model shadow (future)", shadowModelFuture);
assertShadowName(shadowModelFuture, USER_WILL_NAME);
assertEquals("Wrong kind (provisioning)", ShadowKindType.ACCOUNT, shadowModelFuture.asObjectable().getKind());
assertShadowActivationAdministrativeStatus(shadowModelFuture, ActivationStatusType.ENABLED);
assertAttribute(shadowModelFuture, ATTR_USERNAME_QNAME, USER_WILL_NAME);
assertAttribute(shadowModelFuture, ATTR_FULLNAME_QNAME, USER_WILL_FULL_NAME_PIRATE);
assertAttributeFromBackingStore(shadowModelFuture, ATTR_DESCRIPTION_QNAME, ACCOUNT_WILL_DESCRIPTION_MANUAL);
assertShadowPassword(shadowModelFuture);
assertCase(willLastCaseOid, SchemaConstants.CASE_STATE_CLOSED);
}
/**
* disable - do not complete yet (do not wait for delta to expire, we want several deltas at once).
*/
@Test
public void test220ModifyUserWillDisable() throws Exception {
final String TEST_NAME = "test220ModifyUserWillDisable";
displayTestTile(TEST_NAME);
// GIVEN
Task task = createTask(TEST_NAME);
OperationResult result = task.getResult();
accountWillReqestTimestampStart = clock.currentTimeXMLGregorianCalendar();
// WHEN
displayWhen(TEST_NAME);
modifyUserReplace(userWillOid, ACTIVATION_ADMINISTRATIVE_STATUS_PATH, task, result, ActivationStatusType.DISABLED);
// THEN
displayThen(TEST_NAME);
display("result", result);
willLastCaseOid = assertInProgress(result);
accountWillReqestTimestampEnd = clock.currentTimeXMLGregorianCalendar();
PrismObject<ShadowType> shadowRepo = repositoryService.getObject(ShadowType.class, accountWillOid, null, result);
display("Repo shadow", shadowRepo);
assertPendingOperationDeltas(shadowRepo, 2);
PendingOperationType pendingOperation = findPendingOperation(shadowRepo,
OperationResultStatusType.IN_PROGRESS, SchemaConstants.PATH_ACTIVATION_ADMINISTRATIVE_STATUS);
assertPendingOperation(shadowRepo, pendingOperation, accountWillReqestTimestampStart, accountWillReqestTimestampEnd);
assertNotNull("No ID in pending operation", pendingOperation.getId());
// Still old data in the repo. The operation is not completed yet.
assertShadowActivationAdministrativeStatusFromCache(shadowRepo, ActivationStatusType.ENABLED);
assertAttribute(shadowRepo, ATTR_USERNAME_QNAME, USER_WILL_NAME);
assertAttributeFromCache(shadowRepo, ATTR_FULLNAME_QNAME, USER_WILL_FULL_NAME_PIRATE);
PrismObject<ShadowType> shadowModel = modelService.getObject(ShadowType.class,
accountWillOid, null, task, result);
display("Model shadow", shadowModel);
ShadowType shadowTypeProvisioning = shadowModel.asObjectable();
assertShadowName(shadowModel, USER_WILL_NAME);
assertEquals("Wrong kind (provisioning)", ShadowKindType.ACCOUNT, shadowTypeProvisioning.getKind());
assertShadowActivationAdministrativeStatus(shadowModel, ActivationStatusType.ENABLED);
assertAttribute(shadowModel, ATTR_USERNAME_QNAME, USER_WILL_NAME);
assertAttribute(shadowModel, ATTR_FULLNAME_QNAME, USER_WILL_FULL_NAME_PIRATE);
assertAttributeFromBackingStore(shadowModel, ATTR_DESCRIPTION_QNAME, ACCOUNT_WILL_DESCRIPTION_MANUAL);
assertShadowPassword(shadowModel);
assertPendingOperationDeltas(shadowModel, 2);
pendingOperation = findPendingOperation(shadowModel,
OperationResultStatusType.IN_PROGRESS, SchemaConstants.PATH_ACTIVATION_ADMINISTRATIVE_STATUS);
assertPendingOperation(shadowModel, pendingOperation, accountWillReqestTimestampStart, accountWillReqestTimestampEnd);
PrismObject<ShadowType> shadowModelFuture = modelService.getObject(ShadowType.class,
accountWillOid,
SelectorOptions.createCollection(GetOperationOptions.createPointInTimeType(PointInTimeType.FUTURE)),
task, result);
display("Model shadow (future)", shadowModelFuture);
assertShadowName(shadowModelFuture, USER_WILL_NAME);
assertEquals("Wrong kind (provisioning)", ShadowKindType.ACCOUNT, shadowModelFuture.asObjectable().getKind());
assertShadowActivationAdministrativeStatus(shadowModelFuture, ActivationStatusType.DISABLED);
assertAttribute(shadowModelFuture, ATTR_USERNAME_QNAME, USER_WILL_NAME);
assertAttribute(shadowModelFuture, ATTR_FULLNAME_QNAME, USER_WILL_FULL_NAME_PIRATE);
assertAttributeFromBackingStore(shadowModelFuture, ATTR_DESCRIPTION_QNAME, ACCOUNT_WILL_DESCRIPTION_MANUAL);
assertShadowPassword(shadowModelFuture);
assertNotNull("No async reference in result", willLastCaseOid);
assertCase(willLastCaseOid, SchemaConstants.CASE_STATE_OPEN);
}
/**
* Change password, enable. There is still pending disable delta. Make sure all the deltas are
* stored correctly.
*/
@Test
public void test230ModifyAccountWillChangePasswordAndEnable() throws Exception {
final String TEST_NAME = "test230ModifyAccountWillChangePasswordAndEnable";
displayTestTile(TEST_NAME);
// GIVEN
Task task = createTask(TEST_NAME);
OperationResult result = task.getResult();
ObjectDelta<UserType> delta = ObjectDelta.createModificationReplaceProperty(UserType.class,
userWillOid, SchemaConstants.PATH_ACTIVATION_ADMINISTRATIVE_STATUS, prismContext,
ActivationStatusType.ENABLED);
ProtectedStringType ps = new ProtectedStringType();
ps.setClearValue(USER_WILL_PASSWORD_NEW);
delta.addModificationReplaceProperty(SchemaConstants.PATH_PASSWORD_VALUE, ps);
display("ObjectDelta", delta);
accountWillSecondReqestTimestampStart = clock.currentTimeXMLGregorianCalendar();
// WHEN
displayWhen(TEST_NAME);
executeChanges(delta, null, task, result);
// THEN
displayThen(TEST_NAME);
display("result", result);
willSecondLastCaseOid = assertInProgress(result);
accountWillSecondReqestTimestampEnd = clock.currentTimeXMLGregorianCalendar();
PrismObject<ShadowType> shadowRepo = repositoryService.getObject(ShadowType.class, accountWillOid, null, result);
display("Repo shadow", shadowRepo);
assertPendingOperationDeltas(shadowRepo, 3);
PendingOperationType pendingOperation = findPendingOperation(shadowRepo,
OperationResultStatusType.IN_PROGRESS, SchemaConstants.PATH_PASSWORD_VALUE);
assertPendingOperation(shadowRepo, pendingOperation, accountWillSecondReqestTimestampStart, accountWillSecondReqestTimestampEnd);
assertNotNull("No ID in pending operation", pendingOperation.getId());
// Still old data in the repo. The operation is not completed yet.
assertShadowActivationAdministrativeStatusFromCache(shadowRepo, ActivationStatusType.ENABLED);
assertAttribute(shadowRepo, ATTR_USERNAME_QNAME, USER_WILL_NAME);
assertAttributeFromCache(shadowRepo, ATTR_FULLNAME_QNAME, USER_WILL_FULL_NAME_PIRATE);
PrismObject<ShadowType> shadowProvisioning = modelService.getObject(ShadowType.class,
accountWillOid, null, task, result);
display("Model shadow", shadowProvisioning);
ShadowType shadowTypeProvisioning = shadowProvisioning.asObjectable();
assertShadowName(shadowProvisioning, USER_WILL_NAME);
assertEquals("Wrong kind (provisioning)", ShadowKindType.ACCOUNT, shadowTypeProvisioning.getKind());
assertShadowActivationAdministrativeStatus(shadowProvisioning, ActivationStatusType.ENABLED);
assertAttribute(shadowProvisioning, ATTR_USERNAME_QNAME, USER_WILL_NAME);
assertAttribute(shadowProvisioning, ATTR_FULLNAME_QNAME, USER_WILL_FULL_NAME_PIRATE);
assertAttributeFromBackingStore(shadowProvisioning, ATTR_DESCRIPTION_QNAME, ACCOUNT_WILL_DESCRIPTION_MANUAL);
assertShadowPassword(shadowProvisioning);
assertPendingOperationDeltas(shadowProvisioning, 3);
pendingOperation = findPendingOperation(shadowProvisioning,
OperationResultStatusType.IN_PROGRESS, SchemaConstants.PATH_PASSWORD_VALUE);
assertPendingOperation(shadowProvisioning, pendingOperation,
accountWillSecondReqestTimestampStart, accountWillSecondReqestTimestampEnd);
PrismObject<ShadowType> shadowProvisioningFuture = modelService.getObject(ShadowType.class,
accountWillOid,
SelectorOptions.createCollection(GetOperationOptions.createPointInTimeType(PointInTimeType.FUTURE)),
task, result);
display("Model shadow (future)", shadowProvisioningFuture);
assertShadowName(shadowProvisioningFuture, USER_WILL_NAME);
assertEquals("Wrong kind (provisioning)", ShadowKindType.ACCOUNT, shadowProvisioningFuture.asObjectable().getKind());
assertShadowActivationAdministrativeStatus(shadowProvisioningFuture, ActivationStatusType.ENABLED);
assertAttribute(shadowProvisioningFuture, ATTR_USERNAME_QNAME, USER_WILL_NAME);
assertAttribute(shadowProvisioningFuture, ATTR_FULLNAME_QNAME, USER_WILL_FULL_NAME_PIRATE);
assertAttributeFromBackingStore(shadowProvisioningFuture, ATTR_DESCRIPTION_QNAME, ACCOUNT_WILL_DESCRIPTION_MANUAL);
assertShadow(shadowProvisioningFuture);
assertNotNull("No async reference in result", willSecondLastCaseOid);
assertCase(willLastCaseOid, SchemaConstants.CASE_STATE_OPEN);
assertCase(willSecondLastCaseOid, SchemaConstants.CASE_STATE_OPEN);
}
/**
* Disable case is closed. The account should be disabled. But there is still the other
* delta pending.
* Do NOT explicitly refresh the shadow in this case. Just reading it should cause the refresh.
*/
@Test
public void test240CloseDisableCaseAndReadAccountWill() throws Exception {
final String TEST_NAME = "test240CloseDisableCaseAndReadAccountWill";
displayTestTile(TEST_NAME);
// GIVEN
Task task = createTask(TEST_NAME);
OperationResult result = task.getResult();
closeCase(willLastCaseOid);
accountWillCompletionTimestampStart = clock.currentTimeXMLGregorianCalendar();
// WHEN
displayWhen(TEST_NAME);
PrismObject<ShadowType> shadowModel = modelService.getObject(ShadowType.class,
accountWillOid, null, task, result);
// THEN
displayThen(TEST_NAME);
assertSuccess(result);
accountWillCompletionTimestampEnd = clock.currentTimeXMLGregorianCalendar();
PrismObject<ShadowType> shadowRepo = repositoryService.getObject(ShadowType.class, accountWillOid, null, result);
display("Repo shadow", shadowRepo);
assertPendingOperationDeltas(shadowRepo, 3);
PendingOperationType pendingOperation = findPendingOperation(shadowRepo,
OperationResultStatusType.SUCCESS, SchemaConstants.PATH_ACTIVATION_ADMINISTRATIVE_STATUS);
assertPendingOperation(shadowRepo, pendingOperation,
accountWillReqestTimestampStart, accountWillReqestTimestampEnd,
OperationResultStatusType.SUCCESS,
accountWillCompletionTimestampStart, accountWillCompletionTimestampEnd);
pendingOperation = findPendingOperation(shadowRepo,
OperationResultStatusType.IN_PROGRESS, SchemaConstants.PATH_PASSWORD_VALUE);
assertPendingOperation(shadowRepo, pendingOperation, accountWillSecondReqestTimestampStart, accountWillSecondReqestTimestampEnd);
assertShadowActivationAdministrativeStatusFromCache(shadowRepo, ActivationStatusType.DISABLED);
assertAttribute(shadowRepo, ATTR_USERNAME_QNAME, USER_WILL_NAME);
assertAttributeFromCache(shadowRepo, ATTR_FULLNAME_QNAME, USER_WILL_FULL_NAME_PIRATE);
display("Model shadow", shadowModel);
ShadowType shadowTypeModel = shadowModel.asObjectable();
assertShadowName(shadowModel, USER_WILL_NAME);
assertEquals("Wrong kind (provisioning)", ShadowKindType.ACCOUNT, shadowTypeModel.getKind());
if (supportsBackingStore()) {
assertShadowActivationAdministrativeStatus(shadowModel, ActivationStatusType.ENABLED);
} else {
assertShadowActivationAdministrativeStatus(shadowModel, ActivationStatusType.DISABLED);
}
assertAttribute(shadowModel, ATTR_USERNAME_QNAME, USER_WILL_NAME);
assertAttribute(shadowModel, ATTR_FULLNAME_QNAME, USER_WILL_FULL_NAME_PIRATE);
assertAttributeFromBackingStore(shadowModel, ATTR_DESCRIPTION_QNAME, ACCOUNT_WILL_DESCRIPTION_MANUAL);
assertShadowPassword(shadowModel);
assertPendingOperationDeltas(shadowModel, 3);
pendingOperation = findPendingOperation(shadowModel,
OperationResultStatusType.SUCCESS, SchemaConstants.PATH_ACTIVATION_ADMINISTRATIVE_STATUS);
assertPendingOperation(shadowModel, pendingOperation,
accountWillReqestTimestampStart, accountWillReqestTimestampEnd,
OperationResultStatusType.SUCCESS,
accountWillCompletionTimestampStart, accountWillCompletionTimestampEnd);
PrismObject<ShadowType> shadowModelFuture = modelService.getObject(ShadowType.class,
accountWillOid,
SelectorOptions.createCollection(GetOperationOptions.createPointInTimeType(PointInTimeType.FUTURE)),
task, result);
display("Model shadow (future)", shadowModelFuture);
assertShadowName(shadowModelFuture, USER_WILL_NAME);
assertEquals("Wrong kind (provisioning)", ShadowKindType.ACCOUNT, shadowModelFuture.asObjectable().getKind());
assertShadowActivationAdministrativeStatus(shadowModelFuture, ActivationStatusType.ENABLED);
assertAttribute(shadowModelFuture, ATTR_USERNAME_QNAME, USER_WILL_NAME);
assertAttribute(shadowModelFuture, ATTR_FULLNAME_QNAME, USER_WILL_FULL_NAME_PIRATE);
assertAttributeFromBackingStore(shadowModelFuture, ATTR_DESCRIPTION_QNAME, ACCOUNT_WILL_DESCRIPTION_MANUAL);
// TODO
// assertShadowPassword(shadowProvisioningFuture);
assertCase(willLastCaseOid, SchemaConstants.CASE_STATE_CLOSED);
assertCase(willSecondLastCaseOid, SchemaConstants.CASE_STATE_OPEN);
}
/**
* lets ff 5min just for fun. Refresh, make sure everything should be the same (grace not expired yet)
*/
@Test
public void test250RecomputeWillAfter5min() throws Exception {
final String TEST_NAME = "test250RecomputeWillAfter5min";
displayTestTile(TEST_NAME);
// GIVEN
Task task = createTask(TEST_NAME);
OperationResult result = task.getResult();
clock.overrideDuration("PT5M");
PrismObject<ShadowType> shadowBefore = modelService.getObject(ShadowType.class, accountWillOid, null, task, result);
display("Shadow before", shadowBefore);
// WHEN
displayWhen(TEST_NAME);
recomputeUser(userWillOid, task, result);
// THEN
displayThen(TEST_NAME);
assertSuccess(result);
PrismObject<ShadowType> shadowRepo = repositoryService.getObject(ShadowType.class, accountWillOid, null, result);
display("Repo shadow", shadowRepo);
assertPendingOperationDeltas(shadowRepo, 3);
PendingOperationType pendingOperation = findPendingOperation(shadowRepo,
OperationResultStatusType.SUCCESS, SchemaConstants.PATH_ACTIVATION_ADMINISTRATIVE_STATUS);
assertPendingOperation(shadowRepo, pendingOperation,
accountWillReqestTimestampStart, accountWillReqestTimestampEnd,
OperationResultStatusType.SUCCESS,
accountWillCompletionTimestampStart, accountWillCompletionTimestampEnd);
pendingOperation = findPendingOperation(shadowRepo,
OperationResultStatusType.IN_PROGRESS, SchemaConstants.PATH_PASSWORD_VALUE);
assertPendingOperation(shadowRepo, pendingOperation, accountWillSecondReqestTimestampStart, accountWillSecondReqestTimestampEnd);
assertShadowActivationAdministrativeStatusFromCache(shadowRepo, ActivationStatusType.DISABLED);
assertAttribute(shadowRepo, ATTR_USERNAME_QNAME, USER_WILL_NAME);
assertAttributeFromCache(shadowRepo, ATTR_FULLNAME_QNAME, USER_WILL_FULL_NAME_PIRATE);
PrismObject<ShadowType> shadowModel = modelService.getObject(ShadowType.class,
accountWillOid, null, task, result);
display("Model shadow", shadowModel);
ShadowType shadowTypeProvisioning = shadowModel.asObjectable();
assertShadowName(shadowModel, USER_WILL_NAME);
assertEquals("Wrong kind (provisioning)", ShadowKindType.ACCOUNT, shadowTypeProvisioning.getKind());
if (supportsBackingStore()) {
assertShadowActivationAdministrativeStatus(shadowModel, ActivationStatusType.ENABLED);
} else {
assertShadowActivationAdministrativeStatus(shadowModel, ActivationStatusType.DISABLED);
}
assertAttribute(shadowModel, ATTR_USERNAME_QNAME, USER_WILL_NAME);
assertAttribute(shadowModel, ATTR_FULLNAME_QNAME, USER_WILL_FULL_NAME_PIRATE);
assertAttributeFromBackingStore(shadowModel, ATTR_DESCRIPTION_QNAME, ACCOUNT_WILL_DESCRIPTION_MANUAL);
assertShadowPassword(shadowModel);
assertPendingOperationDeltas(shadowModel, 3);
pendingOperation = findPendingOperation(shadowModel,
OperationResultStatusType.SUCCESS, SchemaConstants.PATH_ACTIVATION_ADMINISTRATIVE_STATUS);
assertPendingOperation(shadowModel, pendingOperation,
accountWillReqestTimestampStart, accountWillReqestTimestampEnd,
OperationResultStatusType.SUCCESS,
accountWillCompletionTimestampStart, accountWillCompletionTimestampEnd);
PrismObject<ShadowType> shadowProvisioningFuture = modelService.getObject(ShadowType.class,
accountWillOid,
SelectorOptions.createCollection(GetOperationOptions.createPointInTimeType(PointInTimeType.FUTURE)),
task, result);
display("Model shadow (future)", shadowProvisioningFuture);
assertShadowName(shadowProvisioningFuture, USER_WILL_NAME);
assertEquals("Wrong kind (provisioning)", ShadowKindType.ACCOUNT, shadowProvisioningFuture.asObjectable().getKind());
assertShadowActivationAdministrativeStatus(shadowProvisioningFuture, ActivationStatusType.ENABLED);
assertAttribute(shadowProvisioningFuture, ATTR_USERNAME_QNAME, USER_WILL_NAME);
assertAttribute(shadowProvisioningFuture, ATTR_FULLNAME_QNAME, USER_WILL_FULL_NAME_PIRATE);
assertAttributeFromBackingStore(shadowProvisioningFuture, ATTR_DESCRIPTION_QNAME, ACCOUNT_WILL_DESCRIPTION_MANUAL);
// TODO
// assertShadowPassword(shadowProvisioningFuture);
assertCase(willLastCaseOid, SchemaConstants.CASE_STATE_CLOSED);
assertCase(willSecondLastCaseOid, SchemaConstants.CASE_STATE_OPEN);
}
@Test
public void test252UpdateBackingStoreAndGetAccountWill() throws Exception {
final String TEST_NAME = "test252UpdateBackingStoreAndGetAccountWill";
displayTestTile(TEST_NAME);
// GIVEN
Task task = createTask(TEST_NAME);
OperationResult result = task.getResult();
backingStoreUpdateWill(USER_WILL_FULL_NAME_PIRATE, ActivationStatusType.DISABLED, USER_WILL_PASSWORD_OLD);
// WHEN
displayWhen(TEST_NAME);
PrismObject<ShadowType> shadowModel = modelService.getObject(ShadowType.class,
accountWillOid, null, task, result);
// THEN
displayThen(TEST_NAME);
assertSuccess(result);
display("Model shadow", shadowModel);
ShadowType shadowTypeModel = shadowModel.asObjectable();
assertShadowName(shadowModel, USER_WILL_NAME);
assertEquals("Wrong kind (provisioning)", ShadowKindType.ACCOUNT, shadowTypeModel.getKind());
assertShadowActivationAdministrativeStatus(shadowModel, ActivationStatusType.DISABLED);
assertAttribute(shadowModel, ATTR_USERNAME_QNAME, USER_WILL_NAME);
assertAttribute(shadowModel, ATTR_FULLNAME_QNAME, USER_WILL_FULL_NAME_PIRATE);
assertAttributeFromBackingStore(shadowModel, ATTR_DESCRIPTION_QNAME, ACCOUNT_WILL_DESCRIPTION_MANUAL);
assertShadowPassword(shadowModel);
assertPendingOperationDeltas(shadowModel, 3);
PrismObject<ShadowType> shadowRepo = repositoryService.getObject(ShadowType.class, accountWillOid, null, result);
display("Repo shadow", shadowRepo);
assertPendingOperationDeltas(shadowRepo, 3);
PrismObject<ShadowType> shadowModelFuture = modelService.getObject(ShadowType.class,
accountWillOid,
SelectorOptions.createCollection(GetOperationOptions.createPointInTimeType(PointInTimeType.FUTURE)),
task, result);
display("Model shadow (future)", shadowModelFuture);
assertShadowName(shadowModelFuture, USER_WILL_NAME);
assertEquals("Wrong kind (provisioning)", ShadowKindType.ACCOUNT, shadowModelFuture.asObjectable().getKind());
assertShadowActivationAdministrativeStatus(shadowModelFuture, ActivationStatusType.ENABLED);
assertAttribute(shadowModelFuture, ATTR_USERNAME_QNAME, USER_WILL_NAME);
assertAttribute(shadowModelFuture, ATTR_FULLNAME_QNAME, USER_WILL_FULL_NAME_PIRATE);
assertAttributeFromBackingStore(shadowModelFuture, ATTR_DESCRIPTION_QNAME, ACCOUNT_WILL_DESCRIPTION_MANUAL);
// TODO
// assertShadowPassword(shadowProvisioningFuture);
assertCase(willLastCaseOid, SchemaConstants.CASE_STATE_CLOSED);
assertCase(willSecondLastCaseOid, SchemaConstants.CASE_STATE_OPEN);
}
/**
* Password change/enable case is closed. The account should be disabled. But there is still the other
* delta pending.
*/
@Test
public void test260ClosePasswordChangeCaseAndRecomputeWill() throws Exception {
final String TEST_NAME = "test260ClosePasswordChangeCaseAndRecomputeWill";
displayTestTile(TEST_NAME);
// GIVEN
Task task = createTask(TEST_NAME);
OperationResult result = task.getResult();
closeCase(willSecondLastCaseOid);
accountWillSecondCompletionTimestampStart = clock.currentTimeXMLGregorianCalendar();
// WHEN
displayWhen(TEST_NAME);
recomputeUser(userWillOid, task, result);
// THEN
displayThen(TEST_NAME);
assertSuccess(result);
accountWillSecondCompletionTimestampEnd = clock.currentTimeXMLGregorianCalendar();
PrismObject<ShadowType> shadowRepo = repositoryService.getObject(ShadowType.class, accountWillOid, null, result);
display("Repo shadow", shadowRepo);
assertPendingOperationDeltas(shadowRepo, 3);
PendingOperationType pendingOperation = findPendingOperation(shadowRepo,
OperationResultStatusType.SUCCESS, SchemaConstants.PATH_PASSWORD_VALUE);
assertPendingOperation(shadowRepo, pendingOperation,
accountWillSecondReqestTimestampStart, accountWillSecondReqestTimestampEnd,
OperationResultStatusType.SUCCESS,
accountWillSecondCompletionTimestampStart, accountWillSecondCompletionTimestampEnd);
pendingOperation = findPendingOperation(shadowRepo,
OperationResultStatusType.SUCCESS, SchemaConstants.PATH_PASSWORD_VALUE);
assertPendingOperation(shadowRepo, pendingOperation,
accountWillSecondReqestTimestampStart, accountWillSecondReqestTimestampEnd,
OperationResultStatusType.SUCCESS,
accountWillSecondCompletionTimestampStart, accountWillSecondCompletionTimestampEnd);
assertShadowActivationAdministrativeStatusFromCache(shadowRepo, ActivationStatusType.ENABLED);
assertAttribute(shadowRepo, ATTR_USERNAME_QNAME, USER_WILL_NAME);
assertAttributeFromCache(shadowRepo, ATTR_FULLNAME_QNAME, USER_WILL_FULL_NAME_PIRATE);
PrismObject<ShadowType> shadowModel = modelService.getObject(ShadowType.class,
accountWillOid, null, task, result);
display("Model shadow", shadowModel);
ShadowType shadowTypeProvisioning = shadowModel.asObjectable();
assertShadowName(shadowModel, USER_WILL_NAME);
assertEquals("Wrong kind (provisioning)", ShadowKindType.ACCOUNT, shadowTypeProvisioning.getKind());
if (supportsBackingStore()) {
assertShadowActivationAdministrativeStatus(shadowModel, ActivationStatusType.DISABLED);
} else {
assertShadowActivationAdministrativeStatus(shadowModel, ActivationStatusType.ENABLED);
}
assertAttribute(shadowModel, ATTR_USERNAME_QNAME, USER_WILL_NAME);
assertAttribute(shadowModel, ATTR_FULLNAME_QNAME, USER_WILL_FULL_NAME_PIRATE);
assertAttributeFromBackingStore(shadowModel, ATTR_DESCRIPTION_QNAME, ACCOUNT_WILL_DESCRIPTION_MANUAL);
assertShadowPassword(shadowModel);
assertPendingOperationDeltas(shadowModel, 3);
pendingOperation = findPendingOperation(shadowModel,
OperationResultStatusType.SUCCESS, SchemaConstants.PATH_PASSWORD_VALUE);
assertPendingOperation(shadowRepo, pendingOperation,
accountWillSecondReqestTimestampStart, accountWillSecondReqestTimestampEnd,
OperationResultStatusType.SUCCESS,
accountWillSecondCompletionTimestampStart, accountWillSecondCompletionTimestampEnd);
PrismObject<ShadowType> shadowModelFuture = modelService.getObject(ShadowType.class,
accountWillOid,
SelectorOptions.createCollection(GetOperationOptions.createPointInTimeType(PointInTimeType.FUTURE)),
task, result);
display("Model shadow (future)", shadowModelFuture);
assertShadowName(shadowModelFuture, USER_WILL_NAME);
assertEquals("Wrong kind (provisioning)", ShadowKindType.ACCOUNT, shadowModelFuture.asObjectable().getKind());
assertShadowActivationAdministrativeStatus(shadowModelFuture, ActivationStatusType.ENABLED);
assertAttribute(shadowModelFuture, ATTR_USERNAME_QNAME, USER_WILL_NAME);
assertAttribute(shadowModelFuture, ATTR_FULLNAME_QNAME, USER_WILL_FULL_NAME_PIRATE);
assertAttributeFromBackingStore(shadowModelFuture, ATTR_DESCRIPTION_QNAME, ACCOUNT_WILL_DESCRIPTION_MANUAL);
assertShadowPassword(shadowModelFuture);
assertCase(willLastCaseOid, SchemaConstants.CASE_STATE_CLOSED);
assertCase(willSecondLastCaseOid, SchemaConstants.CASE_STATE_CLOSED);
}
/**
* ff 10min. Refresh. Oldest delta should expire.
*/
@Test
public void test270RecomputeWillAfter10min() throws Exception {
final String TEST_NAME = "test130RefreshAccountWillAfter10min";
displayTestTile(TEST_NAME);
// GIVEN
Task task = createTask(TEST_NAME);
OperationResult result = task.getResult();
clock.overrideDuration("PT10M");
PrismObject<ShadowType> shadowBefore = modelService.getObject(ShadowType.class, accountWillOid, null, task, result);
display("Shadow before", shadowBefore);
// WHEN
displayWhen(TEST_NAME);
recomputeUser(userWillOid, task, result);
// THEN
displayThen(TEST_NAME);
assertSuccess(result);
PrismObject<ShadowType> shadowRepo = repositoryService.getObject(ShadowType.class, accountWillOid, null, result);
display("Repo shadow", shadowRepo);
assertPendingOperationDeltas(shadowRepo, 2);
PendingOperationType pendingOperation = findPendingOperation(shadowRepo,
OperationResultStatusType.SUCCESS, SchemaConstants.PATH_PASSWORD_VALUE);
assertPendingOperation(shadowRepo, pendingOperation,
accountWillSecondReqestTimestampStart, accountWillSecondReqestTimestampEnd,
OperationResultStatusType.SUCCESS,
accountWillSecondCompletionTimestampStart, accountWillSecondCompletionTimestampEnd);
pendingOperation = findPendingOperation(shadowRepo,
OperationResultStatusType.SUCCESS, SchemaConstants.PATH_PASSWORD_VALUE);
assertPendingOperation(shadowRepo, pendingOperation,
accountWillSecondReqestTimestampStart, accountWillSecondReqestTimestampEnd,
OperationResultStatusType.SUCCESS,
accountWillSecondCompletionTimestampStart, accountWillSecondCompletionTimestampEnd);
assertShadowActivationAdministrativeStatusFromCache(shadowRepo, ActivationStatusType.ENABLED);
assertAttribute(shadowRepo, ATTR_USERNAME_QNAME, USER_WILL_NAME);
assertAttributeFromCache(shadowRepo, ATTR_FULLNAME_QNAME, USER_WILL_FULL_NAME_PIRATE);
PrismObject<ShadowType> shadowModel = modelService.getObject(ShadowType.class,
accountWillOid, null, task, result);
display("Model shadow", shadowModel);
ShadowType shadowTypeProvisioning = shadowModel.asObjectable();
assertShadowName(shadowModel, USER_WILL_NAME);
assertEquals("Wrong kind (provisioning)", ShadowKindType.ACCOUNT, shadowTypeProvisioning.getKind());
if (supportsBackingStore()) {
assertShadowActivationAdministrativeStatus(shadowModel, ActivationStatusType.DISABLED);
} else {
assertShadowActivationAdministrativeStatus(shadowModel, ActivationStatusType.ENABLED);
}
assertAttribute(shadowModel, ATTR_USERNAME_QNAME, USER_WILL_NAME);
assertAttribute(shadowModel, ATTR_FULLNAME_QNAME, USER_WILL_FULL_NAME_PIRATE);
assertAttributeFromBackingStore(shadowModel, ATTR_DESCRIPTION_QNAME, ACCOUNT_WILL_DESCRIPTION_MANUAL);
assertShadowPassword(shadowModel);
assertPendingOperationDeltas(shadowModel, 2);
pendingOperation = findPendingOperation(shadowModel,
OperationResultStatusType.SUCCESS, SchemaConstants.PATH_PASSWORD_VALUE);
assertPendingOperation(shadowRepo, pendingOperation,
accountWillSecondReqestTimestampStart, accountWillSecondReqestTimestampEnd,
OperationResultStatusType.SUCCESS,
accountWillSecondCompletionTimestampStart, accountWillSecondCompletionTimestampEnd);
PrismObject<ShadowType> shadowModelFuture = modelService.getObject(ShadowType.class,
accountWillOid,
SelectorOptions.createCollection(GetOperationOptions.createPointInTimeType(PointInTimeType.FUTURE)),
task, result);
display("Model shadow (future)", shadowModelFuture);
assertShadowName(shadowModelFuture, USER_WILL_NAME);
assertEquals("Wrong kind (provisioning)", ShadowKindType.ACCOUNT, shadowModelFuture.asObjectable().getKind());
assertShadowActivationAdministrativeStatus(shadowModelFuture, ActivationStatusType.ENABLED);
assertAttribute(shadowModelFuture, ATTR_USERNAME_QNAME, USER_WILL_NAME);
assertAttribute(shadowModelFuture, ATTR_FULLNAME_QNAME, USER_WILL_FULL_NAME_PIRATE);
assertAttributeFromBackingStore(shadowModelFuture, ATTR_DESCRIPTION_QNAME, ACCOUNT_WILL_DESCRIPTION_MANUAL);
assertShadowPassword(shadowModelFuture);
assertCase(willLastCaseOid, SchemaConstants.CASE_STATE_CLOSED);
assertCase(willSecondLastCaseOid, SchemaConstants.CASE_STATE_CLOSED);
}
@Test
public void test272UpdateBackingStoreAndGetAccountWill() throws Exception {
final String TEST_NAME = "test272UpdateBackingStoreAndGetAccountWill";
displayTestTile(TEST_NAME);
// GIVEN
Task task = createTask(TEST_NAME);
OperationResult result = task.getResult();
backingStoreUpdateWill(USER_WILL_FULL_NAME_PIRATE, ActivationStatusType.ENABLED, USER_WILL_PASSWORD_NEW);
// WHEN
displayWhen(TEST_NAME);
PrismObject<ShadowType> shadowModel = modelService.getObject(ShadowType.class,
accountWillOid, null, task, result);
// THEN
displayThen(TEST_NAME);
assertSuccess(result);
display("Model shadow", shadowModel);
ShadowType shadowTypeProvisioning = shadowModel.asObjectable();
assertShadowName(shadowModel, USER_WILL_NAME);
assertEquals("Wrong kind (provisioning)", ShadowKindType.ACCOUNT, shadowTypeProvisioning.getKind());
assertShadowActivationAdministrativeStatus(shadowModel, ActivationStatusType.ENABLED);
assertAttribute(shadowModel, ATTR_USERNAME_QNAME, USER_WILL_NAME);
assertAttribute(shadowModel, ATTR_FULLNAME_QNAME, USER_WILL_FULL_NAME_PIRATE);
assertAttributeFromBackingStore(shadowModel, ATTR_DESCRIPTION_QNAME, ACCOUNT_WILL_DESCRIPTION_MANUAL);
assertShadowPassword(shadowModel);
assertPendingOperationDeltas(shadowModel, 2);
PrismObject<ShadowType> shadowRepo = repositoryService.getObject(ShadowType.class, accountWillOid, null, result);
display("Repo shadow", shadowRepo);
assertPendingOperationDeltas(shadowRepo, 2);
PrismObject<ShadowType> shadowModelFuture = modelService.getObject(ShadowType.class,
accountWillOid,
SelectorOptions.createCollection(GetOperationOptions.createPointInTimeType(PointInTimeType.FUTURE)),
task, result);
display("Model shadow (future)", shadowModelFuture);
assertShadowName(shadowModelFuture, USER_WILL_NAME);
assertEquals("Wrong kind (provisioning)", ShadowKindType.ACCOUNT, shadowModelFuture.asObjectable().getKind());
assertShadowActivationAdministrativeStatus(shadowModelFuture, ActivationStatusType.ENABLED);
assertAttribute(shadowModelFuture, ATTR_USERNAME_QNAME, USER_WILL_NAME);
assertAttribute(shadowModelFuture, ATTR_FULLNAME_QNAME, USER_WILL_FULL_NAME_PIRATE);
assertAttributeFromBackingStore(shadowModelFuture, ATTR_DESCRIPTION_QNAME, ACCOUNT_WILL_DESCRIPTION_MANUAL);
// TODO
// assertShadowPassword(shadowProvisioningFuture);
assertCase(willLastCaseOid, SchemaConstants.CASE_STATE_CLOSED);
assertCase(willSecondLastCaseOid, SchemaConstants.CASE_STATE_CLOSED);
}
/**
* ff 5min. Refresh. Another delta should expire.
*/
@Test
public void test280RecomputeWillAfter5min() throws Exception {
final String TEST_NAME = "test280RecomputeWillAfter5min";
displayTestTile(TEST_NAME);
// GIVEN
Task task = createTask(TEST_NAME);
OperationResult result = task.getResult();
clock.overrideDuration("PT5M");
// WHEN
displayWhen(TEST_NAME);
recomputeUser(userWillOid, task, result);
// THEN
displayThen(TEST_NAME);
assertSuccess(result);
PrismObject<ShadowType> shadowRepo = repositoryService.getObject(ShadowType.class, accountWillOid, null, result);
display("Repo shadow", shadowRepo);
assertPendingOperationDeltas(shadowRepo, 1);
PendingOperationType pendingOperation = findPendingOperation(shadowRepo,
OperationResultStatusType.SUCCESS, SchemaConstants.PATH_PASSWORD_VALUE);
assertPendingOperation(shadowRepo, pendingOperation,
accountWillSecondReqestTimestampStart, accountWillSecondReqestTimestampEnd,
OperationResultStatusType.SUCCESS,
accountWillSecondCompletionTimestampStart, accountWillSecondCompletionTimestampEnd);
pendingOperation = findPendingOperation(shadowRepo,
OperationResultStatusType.SUCCESS, SchemaConstants.PATH_PASSWORD_VALUE);
assertPendingOperation(shadowRepo, pendingOperation,
accountWillSecondReqestTimestampStart, accountWillSecondReqestTimestampEnd,
OperationResultStatusType.SUCCESS,
accountWillSecondCompletionTimestampStart, accountWillSecondCompletionTimestampEnd);
assertShadowActivationAdministrativeStatusFromCache(shadowRepo, ActivationStatusType.ENABLED);
assertAttribute(shadowRepo, ATTR_USERNAME_QNAME, USER_WILL_NAME);
assertAttributeFromCache(shadowRepo, ATTR_FULLNAME_QNAME, USER_WILL_FULL_NAME_PIRATE);
PrismObject<ShadowType> shadowModel = modelService.getObject(ShadowType.class,
accountWillOid, null, task, result);
display("Model shadow", shadowModel);
ShadowType shadowTypeProvisioning = shadowModel.asObjectable();
assertShadowName(shadowModel, USER_WILL_NAME);
assertEquals("Wrong kind (provisioning)", ShadowKindType.ACCOUNT, shadowTypeProvisioning.getKind());
assertShadowActivationAdministrativeStatus(shadowModel, ActivationStatusType.ENABLED);
assertAttribute(shadowModel, ATTR_USERNAME_QNAME, USER_WILL_NAME);
assertAttribute(shadowModel, ATTR_FULLNAME_QNAME, USER_WILL_FULL_NAME_PIRATE);
assertAttributeFromBackingStore(shadowModel, ATTR_DESCRIPTION_QNAME, ACCOUNT_WILL_DESCRIPTION_MANUAL);
assertShadowPassword(shadowModel);
assertPendingOperationDeltas(shadowModel, 1);
pendingOperation = findPendingOperation(shadowModel,
OperationResultStatusType.SUCCESS, SchemaConstants.PATH_PASSWORD_VALUE);
assertPendingOperation(shadowRepo, pendingOperation,
accountWillSecondReqestTimestampStart, accountWillSecondReqestTimestampEnd,
OperationResultStatusType.SUCCESS,
accountWillSecondCompletionTimestampStart, accountWillSecondCompletionTimestampEnd);
PrismObject<ShadowType> shadowModelFuture = modelService.getObject(ShadowType.class,
accountWillOid,
SelectorOptions.createCollection(GetOperationOptions.createPointInTimeType(PointInTimeType.FUTURE)),
task, result);
display("Model shadow (future)", shadowModelFuture);
assertShadowName(shadowModelFuture, USER_WILL_NAME);
assertEquals("Wrong kind (provisioning)", ShadowKindType.ACCOUNT, shadowModelFuture.asObjectable().getKind());
assertShadowActivationAdministrativeStatus(shadowModelFuture, ActivationStatusType.ENABLED);
assertAttribute(shadowModelFuture, ATTR_USERNAME_QNAME, USER_WILL_NAME);
assertAttribute(shadowModelFuture, ATTR_FULLNAME_QNAME, USER_WILL_FULL_NAME_PIRATE);
assertAttributeFromBackingStore(shadowModelFuture, ATTR_DESCRIPTION_QNAME, ACCOUNT_WILL_DESCRIPTION_MANUAL);
assertShadowPassword(shadowModelFuture);
assertCase(willLastCaseOid, SchemaConstants.CASE_STATE_CLOSED);
assertCase(willSecondLastCaseOid, SchemaConstants.CASE_STATE_CLOSED);
}
/**
* ff 5min. Refresh. All delta should expire.
*/
@Test
public void test290RecomputeWillAfter5min() throws Exception {
final String TEST_NAME = "test290RecomputeWillAfter5min";
displayTestTile(TEST_NAME);
// GIVEN
Task task = createTask(TEST_NAME);
OperationResult result = task.getResult();
clock.overrideDuration("PT5M");
// WHEN
displayWhen(TEST_NAME);
recomputeUser(userWillOid, task, result);
// THEN
displayThen(TEST_NAME);
assertSuccess(result);
PrismObject<ShadowType> shadowRepo = repositoryService.getObject(ShadowType.class, accountWillOid, null, result);
display("Repo shadow", shadowRepo);
assertPendingOperationDeltas(shadowRepo, 0);
assertShadowActivationAdministrativeStatusFromCache(shadowRepo, ActivationStatusType.ENABLED);
assertAttribute(shadowRepo, ATTR_USERNAME_QNAME, USER_WILL_NAME);
assertAttributeFromCache(shadowRepo, ATTR_FULLNAME_QNAME, USER_WILL_FULL_NAME_PIRATE);
PrismObject<ShadowType> shadowModel = modelService.getObject(ShadowType.class,
accountWillOid, null, task, result);
display("Model shadow", shadowModel);
ShadowType shadowTypeProvisioning = shadowModel.asObjectable();
assertShadowName(shadowModel, USER_WILL_NAME);
assertEquals("Wrong kind (provisioning)", ShadowKindType.ACCOUNT, shadowTypeProvisioning.getKind());
assertShadowActivationAdministrativeStatus(shadowModel, ActivationStatusType.ENABLED);
assertAttribute(shadowModel, ATTR_USERNAME_QNAME, USER_WILL_NAME);
assertAttribute(shadowModel, ATTR_FULLNAME_QNAME, USER_WILL_FULL_NAME_PIRATE);
assertAttributeFromBackingStore(shadowModel, ATTR_DESCRIPTION_QNAME, ACCOUNT_WILL_DESCRIPTION_MANUAL);
assertShadowPassword(shadowModel);
assertPendingOperationDeltas(shadowModel, 0);
PrismObject<ShadowType> shadowModelFuture = modelService.getObject(ShadowType.class,
accountWillOid,
SelectorOptions.createCollection(GetOperationOptions.createPointInTimeType(PointInTimeType.FUTURE)),
task, result);
display("Model shadow (future)", shadowModelFuture);
assertShadowName(shadowModelFuture, USER_WILL_NAME);
assertEquals("Wrong kind (provisioning)", ShadowKindType.ACCOUNT, shadowModelFuture.asObjectable().getKind());
assertShadowActivationAdministrativeStatus(shadowModelFuture, ActivationStatusType.ENABLED);
assertAttribute(shadowModelFuture, ATTR_USERNAME_QNAME, USER_WILL_NAME);
assertAttribute(shadowModelFuture, ATTR_FULLNAME_QNAME, USER_WILL_FULL_NAME_PIRATE);
assertAttributeFromBackingStore(shadowModelFuture, ATTR_DESCRIPTION_QNAME, ACCOUNT_WILL_DESCRIPTION_MANUAL);
assertShadowPassword(shadowModelFuture);
assertCase(willLastCaseOid, SchemaConstants.CASE_STATE_CLOSED);
assertCase(willSecondLastCaseOid, SchemaConstants.CASE_STATE_CLOSED);
}
@Test
public void test300UnassignAccountWill() throws Exception {
final String TEST_NAME = "test300UnassignAccountWill";
displayTestTile(TEST_NAME);
// GIVEN
Task task = createTask(TEST_NAME);
OperationResult result = task.getResult();
accountWillReqestTimestampStart = clock.currentTimeXMLGregorianCalendar();
// WHEN
displayWhen(TEST_NAME);
unassignAccount(userWillOid, getResourceOid(), null, task, result);
// THEN
displayThen(TEST_NAME);
display("result", result);
willLastCaseOid = assertInProgress(result);
accountWillReqestTimestampEnd = clock.currentTimeXMLGregorianCalendar();
PrismObject<ShadowType> shadowRepo = repositoryService.getObject(ShadowType.class, accountWillOid, null, result);
display("Repo shadow", shadowRepo);
assertPendingOperationDeltas(shadowRepo, 1);
PendingOperationType pendingOperation = findPendingOperation(shadowRepo,
OperationResultStatusType.IN_PROGRESS, null);
assertPendingOperation(shadowRepo, pendingOperation, accountWillReqestTimestampStart, accountWillReqestTimestampEnd);
assertNotNull("No ID in pending operation", pendingOperation.getId());
// Still old data in the repo. The operation is not completed yet.
assertShadowActivationAdministrativeStatusFromCache(shadowRepo, ActivationStatusType.ENABLED);
assertAttribute(shadowRepo, ATTR_USERNAME_QNAME, USER_WILL_NAME);
assertAttributeFromCache(shadowRepo, ATTR_FULLNAME_QNAME, USER_WILL_FULL_NAME_PIRATE);
PrismObject<ShadowType> shadowModel = modelService.getObject(ShadowType.class,
accountWillOid, null, task, result);
display("Model shadow", shadowModel);
ShadowType shadowTypeProvisioning = shadowModel.asObjectable();
assertShadowName(shadowModel, USER_WILL_NAME);
assertEquals("Wrong kind (provisioning)", ShadowKindType.ACCOUNT, shadowTypeProvisioning.getKind());
assertShadowActivationAdministrativeStatus(shadowModel, ActivationStatusType.ENABLED);
assertAttribute(shadowModel, ATTR_USERNAME_QNAME, USER_WILL_NAME);
assertAttribute(shadowModel, ATTR_FULLNAME_QNAME, USER_WILL_FULL_NAME_PIRATE);
assertAttributeFromBackingStore(shadowModel, ATTR_DESCRIPTION_QNAME, ACCOUNT_WILL_DESCRIPTION_MANUAL);
assertShadowPassword(shadowModel);
assertPendingOperationDeltas(shadowModel, 1);
pendingOperation = findPendingOperation(shadowModel,
OperationResultStatusType.IN_PROGRESS, null);
assertPendingOperation(shadowModel, pendingOperation, accountWillReqestTimestampStart, accountWillReqestTimestampEnd);
PrismObject<ShadowType> shadowModelFuture = modelService.getObject(ShadowType.class,
accountWillOid,
SelectorOptions.createCollection(GetOperationOptions.createPointInTimeType(PointInTimeType.FUTURE)),
task, result);
display("Model shadow (future)", shadowModelFuture);
assertShadowName(shadowModelFuture, USER_WILL_NAME);
assertShadowDead(shadowModelFuture);
assertShadowPassword(shadowModelFuture);
// Make sure that the account is still linked
PrismObject<UserType> userAfter = getUser(userWillOid);
display("User after", userAfter);
String accountWillOidAfter = getSingleLinkOid(userAfter);
assertEquals(accountWillOid, accountWillOidAfter);
assertNoAssignments(userAfter);
assertNotNull("No async reference in result", willLastCaseOid);
assertCase(willLastCaseOid, SchemaConstants.CASE_STATE_OPEN);
}
/**
* Recompute. Make sure model will not try to delete the account again.
*/
@Test
public void test302RecomputeWill() throws Exception {
final String TEST_NAME = "test302RecomputeWill";
displayTestTile(TEST_NAME);
// GIVEN
Task task = createTask(TEST_NAME);
OperationResult result = task.getResult();
// WHEN
displayWhen(TEST_NAME);
recomputeUser(userWillOid, task, result);
// THEN
displayThen(TEST_NAME);
display("result", result);
assertSuccess(result);
PrismObject<ShadowType> shadowRepo = repositoryService.getObject(ShadowType.class, accountWillOid, null, result);
display("Repo shadow", shadowRepo);
assertPendingOperationDeltas(shadowRepo, 1);
PendingOperationType pendingOperation = findPendingOperation(shadowRepo,
OperationResultStatusType.IN_PROGRESS, null);
assertPendingOperation(shadowRepo, pendingOperation, accountWillReqestTimestampStart, accountWillReqestTimestampEnd);
assertNotNull("No ID in pending operation", pendingOperation.getId());
// Still old data in the repo. The operation is not completed yet.
assertShadowActivationAdministrativeStatusFromCache(shadowRepo, ActivationStatusType.ENABLED);
assertAttribute(shadowRepo, ATTR_USERNAME_QNAME, USER_WILL_NAME);
assertAttributeFromCache(shadowRepo, ATTR_FULLNAME_QNAME, USER_WILL_FULL_NAME_PIRATE);
PrismObject<ShadowType> shadowModel = modelService.getObject(ShadowType.class,
accountWillOid, null, task, result);
display("Model shadow", shadowModel);
ShadowType shadowTypeProvisioning = shadowModel.asObjectable();
assertShadowName(shadowModel, USER_WILL_NAME);
assertEquals("Wrong kind (provisioning)", ShadowKindType.ACCOUNT, shadowTypeProvisioning.getKind());
assertShadowActivationAdministrativeStatus(shadowModel, ActivationStatusType.ENABLED);
assertAttribute(shadowModel, ATTR_USERNAME_QNAME, USER_WILL_NAME);
assertAttribute(shadowModel, ATTR_FULLNAME_QNAME, USER_WILL_FULL_NAME_PIRATE);
assertAttributeFromBackingStore(shadowModel, ATTR_DESCRIPTION_QNAME, ACCOUNT_WILL_DESCRIPTION_MANUAL);
assertShadowPassword(shadowModel);
assertPendingOperationDeltas(shadowModel, 1);
pendingOperation = findPendingOperation(shadowModel,
OperationResultStatusType.IN_PROGRESS, null);
assertPendingOperation(shadowModel, pendingOperation, accountWillReqestTimestampStart, accountWillReqestTimestampEnd);
PrismObject<ShadowType> shadowModelFuture = modelService.getObject(ShadowType.class,
accountWillOid,
SelectorOptions.createCollection(GetOperationOptions.createPointInTimeType(PointInTimeType.FUTURE)),
task, result);
display("Model shadow (future)", shadowModelFuture);
assertShadowName(shadowModelFuture, USER_WILL_NAME);
assertShadowDead(shadowModelFuture);
assertShadowPassword(shadowModelFuture);
// Make sure that the account is still linked
PrismObject<UserType> userAfter = getUser(userWillOid);
display("User after", userAfter);
String accountWillOidAfter = getSingleLinkOid(userAfter);
assertEquals(accountWillOid, accountWillOidAfter);
assertNoAssignments(userAfter);
assertNotNull("No async reference in result", willLastCaseOid);
assertCase(willLastCaseOid, SchemaConstants.CASE_STATE_OPEN);
}
/**
* Case is closed. The operation is complete.
*/
@Test
public void test310CloseCaseAndRecomputeWill() throws Exception {
final String TEST_NAME = "test310CloseCaseAndRecomputeWill";
displayTestTile(TEST_NAME);
// GIVEN
Task task = createTask(TEST_NAME);
OperationResult result = task.getResult();
closeCase(willLastCaseOid);
accountWillCompletionTimestampStart = clock.currentTimeXMLGregorianCalendar();
// WHEN
displayWhen(TEST_NAME);
// We need reconcile and not recompute here. We need to fetch the updated case status.
reconcileUser(userWillOid, task, result);
// THEN
displayThen(TEST_NAME);
display("result", result);
assertSuccess(result);
accountWillCompletionTimestampEnd = clock.currentTimeXMLGregorianCalendar();
PrismObject<ShadowType> shadowRepo = repositoryService.getObject(ShadowType.class, accountWillOid, null, result);
display("Repo shadow", shadowRepo);
assertSinglePendingOperation(shadowRepo,
accountWillReqestTimestampStart, accountWillReqestTimestampEnd,
OperationResultStatusType.SUCCESS,
accountWillCompletionTimestampStart, accountWillCompletionTimestampEnd);
assertShadowDead(shadowRepo);
PrismObject<ShadowType> shadowModel = modelService.getObject(ShadowType.class,
accountWillOid, null, task, result);
display("Model shadow", shadowModel);
ShadowType shadowTypeProvisioning = shadowModel.asObjectable();
assertShadowName(shadowModel, USER_WILL_NAME);
assertEquals("Wrong kind (provisioning)", ShadowKindType.ACCOUNT, shadowTypeProvisioning.getKind());
assertShadowDead(shadowModel);
assertShadowPassword(shadowModel);
PendingOperationType pendingOperation = assertSinglePendingOperation(shadowModel,
accountWillReqestTimestampStart, accountWillReqestTimestampEnd,
OperationResultStatusType.SUCCESS,
accountWillCompletionTimestampStart, accountWillCompletionTimestampEnd);
PrismObject<ShadowType> shadowModelFuture = modelService.getObject(ShadowType.class,
accountWillOid,
SelectorOptions.createCollection(GetOperationOptions.createPointInTimeType(PointInTimeType.FUTURE)),
task, result);
display("Model shadow (future)", shadowModelFuture);
assertShadowName(shadowModelFuture, USER_WILL_NAME);
assertShadowDead(shadowModelFuture);
assertShadowPassword(shadowModelFuture);
assertCase(willLastCaseOid, SchemaConstants.CASE_STATE_CLOSED);
}
/**
* ff 5min, everything should be the same (grace not expired yet)
*/
@Test
public void test320RecomputeWillAfter5min() throws Exception {
final String TEST_NAME = "test320RecomputeWillAfter5min";
displayTestTile(TEST_NAME);
// GIVEN
Task task = createTask(TEST_NAME);
OperationResult result = task.getResult();
clock.overrideDuration("PT5M");
// WHEN
displayWhen(TEST_NAME);
recomputeUser(userWillOid, task, result);
// THEN
displayThen(TEST_NAME);
assertSuccess(result);
PrismObject<ShadowType> shadowRepo = repositoryService.getObject(ShadowType.class, accountWillOid, null, result);
display("Repo shadow", shadowRepo);
assertSinglePendingOperation(shadowRepo,
accountWillReqestTimestampStart, accountWillReqestTimestampEnd,
OperationResultStatusType.SUCCESS,
accountWillCompletionTimestampStart, accountWillCompletionTimestampEnd);
assertShadowDead(shadowRepo);
PrismObject<ShadowType> shadowModel = modelService.getObject(ShadowType.class,
accountWillOid, null, task, result);
display("Model shadow", shadowModel);
ShadowType shadowTypeProvisioning = shadowModel.asObjectable();
assertShadowName(shadowModel, USER_WILL_NAME);
assertEquals("Wrong kind (provisioning)", ShadowKindType.ACCOUNT, shadowTypeProvisioning.getKind());
assertShadowDead(shadowModel);
assertShadowPassword(shadowModel);
PendingOperationType pendingOperation = assertSinglePendingOperation(shadowModel,
accountWillReqestTimestampStart, accountWillReqestTimestampEnd,
OperationResultStatusType.SUCCESS,
accountWillCompletionTimestampStart, accountWillCompletionTimestampEnd);
PrismObject<ShadowType> shadowModelFuture = modelService.getObject(ShadowType.class,
accountWillOid,
SelectorOptions.createCollection(GetOperationOptions.createPointInTimeType(PointInTimeType.FUTURE)),
task, result);
display("Model shadow (future)", shadowModelFuture);
assertShadowName(shadowModelFuture, USER_WILL_NAME);
assertShadowDead(shadowModelFuture);
assertShadowPassword(shadowModelFuture);
assertCase(willLastCaseOid, SchemaConstants.CASE_STATE_CLOSED);
}
protected void backingStoreDeleteWill() throws IOException {
// Nothing to do here
}
@Test
public void test330UpdateBackingStoreAndRecomputeWill() throws Exception {
final String TEST_NAME = "test330UpdateBackingStoreAndRecomputeWill";
displayTestTile(TEST_NAME);
// GIVEN
Task task = createTask(TEST_NAME);
OperationResult result = task.getResult();
backingStoreDeleteWill();
// WHEN
displayWhen(TEST_NAME);
recomputeUser(userWillOid, task, result);
// THEN
displayThen(TEST_NAME);
assertSuccess(result);
PrismObject<ShadowType> shadowRepo = repositoryService.getObject(ShadowType.class, accountWillOid, null, result);
display("Repo shadow", shadowRepo);
assertSinglePendingOperation(shadowRepo,
accountWillReqestTimestampStart, accountWillReqestTimestampEnd,
OperationResultStatusType.SUCCESS,
accountWillCompletionTimestampStart, accountWillCompletionTimestampEnd);
assertShadowDead(shadowRepo);
PrismObject<ShadowType> shadowModel = modelService.getObject(ShadowType.class,
accountWillOid, null, task, result);
display("Model shadow", shadowModel);
ShadowType shadowTypeProvisioning = shadowModel.asObjectable();
assertShadowName(shadowModel, USER_WILL_NAME);
assertEquals("Wrong kind (provisioning)", ShadowKindType.ACCOUNT, shadowTypeProvisioning.getKind());
assertShadowDead(shadowModel);
PendingOperationType pendingOperation = assertSinglePendingOperation(shadowModel,
accountWillReqestTimestampStart, accountWillReqestTimestampEnd,
OperationResultStatusType.SUCCESS,
accountWillCompletionTimestampStart, accountWillCompletionTimestampEnd);
PrismObject<ShadowType> shadowModelFuture = modelService.getObject(ShadowType.class,
accountWillOid,
SelectorOptions.createCollection(GetOperationOptions.createPointInTimeType(PointInTimeType.FUTURE)),
task, result);
display("Model shadow (future)", shadowModelFuture);
assertShadowName(shadowModelFuture, USER_WILL_NAME);
assertShadowDead(shadowModelFuture);
assertCase(willLastCaseOid, SchemaConstants.CASE_STATE_CLOSED);
}
// TODO: nofetch, nofetch+future
/**
* ff 20min, grace period expired, shadow should be gone, linkRef shoud be gone.
*/
@Test
public void test340RecomputeWillAfter25min() throws Exception {
final String TEST_NAME = "test340RecomputeWillAfter25min";
displayTestTile(TEST_NAME);
// GIVEN
Task task = createTask(TEST_NAME);
OperationResult result = task.getResult();
clock.overrideDuration("PT20M");
// WHEN
displayWhen(TEST_NAME);
recomputeUser(userWillOid, task, result);
// THEN
displayThen(TEST_NAME);
assertSuccess(result);
PrismObject<UserType> userAfter = getUser(userWillOid);
display("User after", userAfter);
assertLinks(userAfter, 0);
assertNoShadow(accountWillOid);
assertCase(willLastCaseOid, SchemaConstants.CASE_STATE_CLOSED);
}
// TODO: create, close case, then update backing store.
// TODO: let grace period expire without updating the backing store (semi-manual-only)
/**
* The 8xx tests is similar routine as 1xx,2xx,3xx, but this time
* with automatic updates using refresh task.
*/
@Test
public void test800ImportShadowRefreshTask() throws Exception {
final String TEST_NAME = "test800ImportShadowRefreshTask";
displayTestTile(TEST_NAME);
// GIVEN
// WHEN
displayWhen(TEST_NAME);
addObject(TASK_SHADOW_REFRESH_FILE);
// THEN
displayThen(TEST_NAME);
waitForTaskStart(TASK_SHADOW_REFRESH_OID, false);
}
@Test
public void test810AssignAccountWill() throws Exception {
final String TEST_NAME = "test810AssignAccountWill";
Task task = createTask(TEST_NAME);
OperationResult result = task.getResult();
modifyUserReplace(userWillOid, UserType.F_FULL_NAME, task, result, createPolyString(USER_WILL_FULL_NAME));
// WHEN
assignAccountWill(TEST_NAME);
// THEN
restartTask(TASK_SHADOW_REFRESH_OID);
waitForTaskFinish(TASK_SHADOW_REFRESH_OID, false);
assertAccountWillAfterAssign(TEST_NAME);
}
@Test
public void test820AssignAccountJack() throws Exception {
final String TEST_NAME = "test820AssignAccountJack";
displayTestTile(TEST_NAME);
// GIVEN
Task task = createTask(TEST_NAME);
OperationResult result = task.getResult();
clock.overrideDuration("PT5M");
accountJackReqestTimestampStart = clock.currentTimeXMLGregorianCalendar();
// WHEN
displayWhen(TEST_NAME);
assignAccount(USER_JACK_OID, getResourceOid(), null, task, result);
// THEN
displayThen(TEST_NAME);
display("result", result);
jackLastCaseOid = assertInProgress(result);
PrismObject<UserType> userAfter = getUser(USER_JACK_OID);
display("User after", userAfter);
accountJackOid = getSingleLinkOid(userAfter);
accountJackReqestTimestampEnd = clock.currentTimeXMLGregorianCalendar();
assertAccountJackAfterAssign(TEST_NAME);
// THEN
restartTask(TASK_SHADOW_REFRESH_OID);
waitForTaskFinish(TASK_SHADOW_REFRESH_OID, false);
assertAccountJackAfterAssign(TEST_NAME);
}
@Test
public void test830CloseCaseAndWaitForRefresh() throws Exception {
final String TEST_NAME = "test830CloseCaseAndWaitForRefresh";
displayTestTile(TEST_NAME);
// GIVEN
Task task = createTask(TEST_NAME);
OperationResult result = task.getResult();
closeCase(willLastCaseOid);
accountWillCompletionTimestampStart = clock.currentTimeXMLGregorianCalendar();
// WHEN
displayWhen(TEST_NAME);
restartTask(TASK_SHADOW_REFRESH_OID);
waitForTaskFinish(TASK_SHADOW_REFRESH_OID, false);
// THEN
displayThen(TEST_NAME);
assertSuccess(result);
accountWillCompletionTimestampEnd = clock.currentTimeXMLGregorianCalendar();
assertWillAfterCreateCaseClosed(TEST_NAME, false);
assertAccountJackAfterAssign(TEST_NAME);
}
@Test
public void test840AddToBackingStoreAndGetAccountWill() throws Exception {
final String TEST_NAME = "test840AddToBackingStoreAndGetAccountWill";
displayTestTile(TEST_NAME);
// GIVEN
Task task = createTask(TEST_NAME);
OperationResult result = task.getResult();
backingStoreAddWill();
// WHEN
displayWhen(TEST_NAME);
PrismObject<ShadowType> shadowModel = modelService.getObject(ShadowType.class, accountWillOid, null, task, result);
// THEN
displayThen(TEST_NAME);
assertSuccess(result);
display("Model shadow", shadowModel);
ShadowType shadowTypeProvisioning = shadowModel.asObjectable();
assertShadowName(shadowModel, USER_WILL_NAME);
assertEquals("Wrong kind (provisioning)", ShadowKindType.ACCOUNT, shadowTypeProvisioning.getKind());
assertAttribute(shadowModel, ATTR_USERNAME_QNAME, USER_WILL_NAME);
assertAttribute(shadowModel, ATTR_FULLNAME_QNAME, USER_WILL_FULL_NAME);
assertAttributeFromBackingStore(shadowModel, ATTR_DESCRIPTION_QNAME, ACCOUNT_WILL_DESCRIPTION_MANUAL);
assertShadowActivationAdministrativeStatus(shadowModel, ActivationStatusType.ENABLED);
assertShadowExists(shadowModel, true);
assertShadowPassword(shadowModel);
PrismObject<ShadowType> shadowRepo = repositoryService.getObject(ShadowType.class, accountWillOid, null, result);
display("Repo shadow", shadowRepo);
assertSinglePendingOperation(shadowRepo,
accountWillReqestTimestampStart, accountWillReqestTimestampEnd,
OperationResultStatusType.SUCCESS,
accountWillCompletionTimestampStart, accountWillCompletionTimestampEnd);
assertAttribute(shadowRepo, ATTR_USERNAME_QNAME, USER_WILL_NAME);
assertAttributeFromCache(shadowRepo, ATTR_FULLNAME_QNAME, USER_WILL_FULL_NAME);
assertNoAttribute(shadowRepo, ATTR_DESCRIPTION_QNAME);
assertShadowActivationAdministrativeStatusFromCache(shadowRepo, ActivationStatusType.ENABLED);
assertNoShadowPassword(shadowRepo);
assertShadowExists(shadowRepo, true);
}
private void assignAccountWill(final String TEST_NAME) throws Exception {
displayTestTile(TEST_NAME);
// GIVEN
Task task = createTask(TEST_NAME);
OperationResult result = task.getResult();
accountWillReqestTimestampStart = clock.currentTimeXMLGregorianCalendar();
// WHEN
displayWhen(TEST_NAME);
assignAccount(userWillOid, getResourceOid(), null, task, result);
// THEN
displayThen(TEST_NAME);
display("result", result);
willLastCaseOid = assertInProgress(result);
PrismObject<UserType> userAfter = getUser(userWillOid);
display("User after", userAfter);
accountWillOid = getSingleLinkOid(userAfter);
accountWillReqestTimestampEnd = clock.currentTimeXMLGregorianCalendar();
assertAccountWillAfterAssign(TEST_NAME);
}
private void assertAccountWillAfterAssign(final String TEST_NAME) throws Exception {
Task task = createTask(TEST_NAME);
OperationResult result = task.getResult();
PrismObject<ShadowType> shadowRepo = repositoryService.getObject(ShadowType.class, accountWillOid, null, result);
display("Repo shadow", shadowRepo);
PendingOperationType pendingOperation = assertSinglePendingOperation(shadowRepo, accountWillReqestTimestampStart, accountWillReqestTimestampEnd);
assertNotNull("No ID in pending operation", pendingOperation.getId());
assertAttribute(shadowRepo, ATTR_USERNAME_QNAME, USER_WILL_NAME);
assertAttributeFromCache(shadowRepo, ATTR_FULLNAME_QNAME, USER_WILL_FULL_NAME);
assertShadowActivationAdministrativeStatusFromCache(shadowRepo, ActivationStatusType.ENABLED);
assertShadowExists(shadowRepo, false);
assertNoShadowPassword(shadowRepo);
PrismObject<ShadowType> shadowModel = modelService.getObject(ShadowType.class,
accountWillOid, null, task, result);
display("Model shadow", shadowModel);
ShadowType shadowTypeProvisioning = shadowModel.asObjectable();
assertShadowName(shadowModel, USER_WILL_NAME);
assertEquals("Wrong kind (provisioning)", ShadowKindType.ACCOUNT, shadowTypeProvisioning.getKind());
assertAttribute(shadowModel, ATTR_USERNAME_QNAME, USER_WILL_NAME);
assertAttributeFromCache(shadowModel, ATTR_FULLNAME_QNAME, USER_WILL_FULL_NAME);
assertShadowActivationAdministrativeStatusFromCache(shadowModel, ActivationStatusType.ENABLED);
assertShadowExists(shadowModel, false);
assertNoShadowPassword(shadowModel);
assertSinglePendingOperation(shadowModel, accountWillReqestTimestampStart, accountWillReqestTimestampEnd);
assertNotNull("No async reference in result", willLastCaseOid);
assertCase(willLastCaseOid, SchemaConstants.CASE_STATE_OPEN);
}
private void assertAccountJackAfterAssign(final String TEST_NAME) throws Exception {
Task task = createTask(TEST_NAME);
OperationResult result = task.getResult();
PrismObject<ShadowType> shadowRepo = repositoryService.getObject(ShadowType.class, accountJackOid, null, result);
display("Repo shadow", shadowRepo);
PendingOperationType pendingOperation = assertSinglePendingOperation(shadowRepo, accountJackReqestTimestampStart, accountJackReqestTimestampEnd);
assertNotNull("No ID in pending operation", pendingOperation.getId());
assertAttribute(shadowRepo, ATTR_USERNAME_QNAME, USER_JACK_USERNAME);
assertAttributeFromCache(shadowRepo, ATTR_FULLNAME_QNAME, USER_JACK_FULL_NAME);
assertShadowActivationAdministrativeStatusFromCache(shadowRepo, ActivationStatusType.ENABLED);
assertShadowExists(shadowRepo, false);
assertNoShadowPassword(shadowRepo);
PrismObject<ShadowType> shadowModel = modelService.getObject(ShadowType.class,
accountJackOid, null, task, result);
display("Model shadow", shadowModel);
ShadowType shadowTypeProvisioning = shadowModel.asObjectable();
assertShadowName(shadowModel, USER_JACK_USERNAME);
assertEquals("Wrong kind (provisioning)", ShadowKindType.ACCOUNT, shadowTypeProvisioning.getKind());
assertAttribute(shadowModel, ATTR_USERNAME_QNAME, USER_JACK_USERNAME);
assertAttributeFromCache(shadowModel, ATTR_FULLNAME_QNAME, USER_JACK_FULL_NAME);
assertShadowActivationAdministrativeStatusFromCache(shadowModel, ActivationStatusType.ENABLED);
assertShadowExists(shadowModel, false);
assertNoShadowPassword(shadowModel);
assertSinglePendingOperation(shadowModel, accountJackReqestTimestampStart, accountJackReqestTimestampEnd);
assertNotNull("No async reference in result", jackLastCaseOid);
assertCase(jackLastCaseOid, SchemaConstants.CASE_STATE_OPEN);
}
private void assertWillAfterCreateCaseClosed(final String TEST_NAME, boolean backingStoreUpdated) throws Exception {
Task task = createTask(TEST_NAME);
OperationResult result = task.getResult();
PrismObject<ShadowType> shadowRepo = repositoryService.getObject(ShadowType.class, accountWillOid, null, result);
display("Repo shadow", shadowRepo);
assertSinglePendingOperation(shadowRepo,
accountWillReqestTimestampStart, accountWillReqestTimestampEnd,
OperationResultStatusType.SUCCESS,
accountWillCompletionTimestampStart, accountWillCompletionTimestampEnd);
assertAttribute(shadowRepo, ATTR_USERNAME_QNAME, USER_WILL_NAME);
assertAttributeFromCache(shadowRepo, ATTR_FULLNAME_QNAME, USER_WILL_FULL_NAME);
assertShadowActivationAdministrativeStatusFromCache(shadowRepo, ActivationStatusType.ENABLED);
PrismObject<ShadowType> shadowModel = modelService.getObject(ShadowType.class,
accountWillOid, null, task, result);
display("Model shadow", shadowModel);
ShadowType shadowTypeProvisioning = shadowModel.asObjectable();
assertShadowName(shadowModel, USER_WILL_NAME);
assertEquals("Wrong kind (provisioning)", ShadowKindType.ACCOUNT, shadowTypeProvisioning.getKind());
assertAttribute(shadowModel, ATTR_USERNAME_QNAME, USER_WILL_NAME);
if (!supportsBackingStore() || backingStoreUpdated) {
assertAttribute(shadowModel, ATTR_FULLNAME_QNAME, USER_WILL_FULL_NAME);
assertAttributeFromBackingStore(shadowModel, ATTR_DESCRIPTION_QNAME, ACCOUNT_WILL_DESCRIPTION_MANUAL);
assertShadowActivationAdministrativeStatus(shadowModel, ActivationStatusType.ENABLED);
assertShadowPassword(shadowModel);
}
PendingOperationType pendingOperation = assertSinglePendingOperation(shadowModel,
accountWillReqestTimestampStart, accountWillReqestTimestampEnd,
OperationResultStatusType.SUCCESS,
accountWillCompletionTimestampStart, accountWillCompletionTimestampEnd);
assertCase(willLastCaseOid, SchemaConstants.CASE_STATE_CLOSED);
}
private void assertPendingOperationDeltas(PrismObject<ShadowType> shadow, int expectedNumber) {
List<PendingOperationType> pendingOperations = shadow.asObjectable().getPendingOperation();
assertEquals("Wroung number of pending operations in "+shadow, expectedNumber, pendingOperations.size());
}
private PendingOperationType assertSinglePendingOperation(PrismObject<ShadowType> shadow,
XMLGregorianCalendar requestStart, XMLGregorianCalendar requestEnd) {
return assertSinglePendingOperation(shadow, requestStart, requestEnd,
OperationResultStatusType.IN_PROGRESS, null, null);
}
private PendingOperationType assertSinglePendingOperation(PrismObject<ShadowType> shadow,
XMLGregorianCalendar requestStart, XMLGregorianCalendar requestEnd,
OperationResultStatusType expectedStatus,
XMLGregorianCalendar completionStart, XMLGregorianCalendar completionEnd) {
assertPendingOperationDeltas(shadow, 1);
return assertPendingOperation(shadow, shadow.asObjectable().getPendingOperation().get(0),
requestStart, requestEnd, expectedStatus, completionStart, completionEnd);
}
private PendingOperationType assertPendingOperation(
PrismObject<ShadowType> shadow, PendingOperationType pendingOperation,
XMLGregorianCalendar requestStart, XMLGregorianCalendar requestEnd) {
return assertPendingOperation(shadow, pendingOperation, requestStart, requestEnd,
OperationResultStatusType.IN_PROGRESS, null, null);
}
private PendingOperationType assertPendingOperation(
PrismObject<ShadowType> shadow, PendingOperationType pendingOperation,
XMLGregorianCalendar requestStart, XMLGregorianCalendar requestEnd,
OperationResultStatusType expectedStatus,
XMLGregorianCalendar completionStart, XMLGregorianCalendar completionEnd) {
assertNotNull("No operation ", pendingOperation);
ObjectDeltaType deltaType = pendingOperation.getDelta();
assertNotNull("No delta in pending operation in "+shadow, deltaType);
// TODO: check content of pending operations in the shadow
TestUtil.assertBetween("No request timestamp in pending operation in "+shadow, requestStart, requestEnd, pendingOperation.getRequestTimestamp());
OperationResultStatusType status = pendingOperation.getResultStatus();
assertEquals("Wrong status in pending operation in "+shadow, expectedStatus, status);
if (expectedStatus != OperationResultStatusType.IN_PROGRESS) {
TestUtil.assertBetween("No completion timestamp in pending operation in "+shadow, completionStart, completionEnd, pendingOperation.getCompletionTimestamp());
}
return pendingOperation;
}
private PendingOperationType findPendingOperation(PrismObject<ShadowType> shadow,
OperationResultStatusType expectedResult, ItemPath itemPath) {
List<PendingOperationType> pendingOperations = shadow.asObjectable().getPendingOperation();
for (PendingOperationType pendingOperation: pendingOperations) {
OperationResultStatusType result = pendingOperation.getResultStatus();
if (result == null) {
result = OperationResultStatusType.IN_PROGRESS;
}
if (pendingOperation.getResultStatus() != expectedResult) {
continue;
}
if (itemPath == null) {
return pendingOperation;
}
ObjectDeltaType delta = pendingOperation.getDelta();
assertNotNull("No delta in pending operation in "+shadow, delta);
for (ItemDeltaType itemDelta: delta.getItemDelta()) {
ItemPath deltaPath = itemDelta.getPath().getItemPath();
if (itemPath.equivalent(deltaPath)) {
return pendingOperation;
}
}
}
return null;
}
protected <T> void assertAttribute(PrismObject<ShadowType> shadow, QName attrName, T... expectedValues) {
assertAttribute(resource, shadow.asObjectable(), attrName, expectedValues);
}
protected <T> void assertNoAttribute(PrismObject<ShadowType> shadow, QName attrName) {
assertNoAttribute(resource, shadow.asObjectable(), attrName);
}
protected void assertAttributeFromCache(PrismObject<ShadowType> shadow, QName attrQName,
String... attrVals) {
if (supportsBackingStore()) {
assertNoAttribute(shadow, attrQName);
} else {
assertAttribute(shadow, attrQName, attrVals);
}
}
protected void assertAttributeFromBackingStore(PrismObject<ShadowType> shadow, QName attrQName,
String... attrVals) {
if (supportsBackingStore()) {
assertAttribute(shadow, attrQName, attrVals);
} else {
assertNoAttribute(shadow, attrQName);
}
}
protected void assertShadowActivationAdministrativeStatusFromCache(PrismObject<ShadowType> shadow, ActivationStatusType expectedStatus) {
if (supportsBackingStore()) {
assertShadowActivationAdministrativeStatus(shadow, null);
} else {
assertShadowActivationAdministrativeStatus(shadow, expectedStatus);
}
}
protected void assertShadowActivationAdministrativeStatus(PrismObject<ShadowType> shadow, ActivationStatusType expectedStatus) {
assertActivationAdministrativeStatus(shadow, expectedStatus);
}
protected void assertShadowPassword(PrismObject<ShadowType> shadow) {
// pure manual resource should never "read" password
assertNoShadowPassword(shadow);
}
private void assertManual(AbstractWriteCapabilityType cap) {
assertEquals("Manual flag not set in capability "+cap, Boolean.TRUE, cap.isManual());
}
}