/*
* 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.provisioning.impl.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.assertNull;
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.apache.commons.lang.StringUtils;
import org.springframework.test.annotation.DirtiesContext;
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.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.ItemDelta;
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.provisioning.impl.AbstractProvisioningIntegrationTest;
import com.evolveum.midpoint.provisioning.impl.ProvisioningTestUtil;
import com.evolveum.midpoint.provisioning.impl.opendj.TestOpenDj;
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.schema.util.ShadowUtil;
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.ActivationType;
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.OperationProvisioningScriptsType;
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.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.midpoint.xml.ns._public.resource.capabilities_3.ScriptCapabilityType;
import com.evolveum.midpoint.xml.ns._public.resource.capabilities_3.ScriptCapabilityType.Host;
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-provisioning-test-main.xml")
@DirtiesContext
public abstract class AbstractManualResourceTest extends AbstractProvisioningIntegrationTest {
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 = "8a8e19de-1a14-11e7-965f-6f995b457a8b";
protected static final File RESOURCE_SEMI_MANUAL_FILE = new File(TEST_DIR, "resource-semi-manual.xml");
protected static final String RESOURCE_SEMI_MANUAL_OID = "8a8e19de-1a14-11e7-965f-6f995b457a8b";
public static final QName RESOURCE_ACCOUNT_OBJECTCLASS = new QName(MidPointConstants.NS_RI, "AccountObjectClass");
protected static final String MANUAL_CONNECTOR_TYPE = "ManualConnector";
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 File ACCOUNT_WILL_FILE = new File(TEST_DIR, "account-will.xml");
protected static final String ACCOUNT_WILL_OID = "c1add81e-1df7-11e7-bbb7-5731391ba751";
protected static final String ACCOUNT_WILL_USERNAME = "will";
protected static final String ACCOUNT_WILL_FULLNAME = "Will Turner";
protected static final String ACCOUNT_WILL_FULLNAME_PIRATE = "Pirate Will Turner";
protected static final String ACCOUNT_WILL_DESCRIPTION_MANUAL = "manual";
protected static final String ACCOUNT_WILL_PASSWORD_OLD = "3lizab3th";
protected static final String ACCOUNT_WILL_PASSWORD_NEW = "ELIZAbeth";
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 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;
@Override
public void initSystem(Task initTask, OperationResult initResult) throws Exception {
// We need to switch off the encryption checks. Some values cannot be encrypted as we do
// not have a definition here
InternalsConfig.encryptionChecks = false;
super.initSystem(initTask, initResult);
}
protected abstract File getResourceFile();
protected String getResourceOid() {
return RESOURCE_MANUAL_OID;
}
protected boolean supportsBackingStore() {
return false;
}
@Test
public void test000Sanity() throws Exception {
final String TEST_NAME = "test000Sanity";
TestUtil.displayTestTile(TEST_NAME);
assertNotNull("Resource is null", resource);
assertNotNull("ResourceType is null", resourceType);
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);
}
@Test
public void test003Connection() throws Exception {
final String TEST_NAME = "test003Connection";
TestUtil.displayTestTile(TEST_NAME);
// GIVEN
OperationResult result = new OperationResult(AbstractManualResourceTest.class.getName() + "." + TEST_NAME);
// 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 = provisioningService.testResource(getResourceOid());
// 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 = provisioningService.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(TestOpenDj.class.getName()+"."+TEST_NAME);
// WHEN
ResourceType resource = provisioningService.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 test100AddAccountWill() throws Exception {
final String TEST_NAME = "test100AddAccountWill";
displayTestTile(TEST_NAME);
// GIVEN
Task task = createTask(TEST_NAME);
OperationResult result = task.getResult();
syncServiceMock.reset();
PrismObject<ShadowType> account = parseObject(ACCOUNT_WILL_FILE);
account.checkConsistence();
display("Adding shadow", account);
accountWillReqestTimestampStart = clock.currentTimeXMLGregorianCalendar();
// WHEN
displayWhen(TEST_NAME);
String addedObjectOid = provisioningService.addObject(account, null, null, task, result);
// THEN
displayThen(TEST_NAME);
display("result", result);
willLastCaseOid = assertInProgress(result);
accountWillReqestTimestampEnd = clock.currentTimeXMLGregorianCalendar();
assertEquals(ACCOUNT_WILL_OID, addedObjectOid);
account.checkConsistence();
PrismObject<ShadowType> shadowRepo = repositoryService.getObject(ShadowType.class, ACCOUNT_WILL_OID, 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, ACCOUNT_WILL_USERNAME);
assertAttributeFromCache(shadowRepo, ATTR_FULLNAME_QNAME, ACCOUNT_WILL_FULLNAME);
assertShadowActivationAdministrativeStatusFromCache(shadowRepo, ActivationStatusType.ENABLED);
assertShadowExists(shadowRepo, false);
assertNoShadowPassword(shadowRepo);
syncServiceMock.assertNoNotifyChange();
syncServiceMock.assertNotifyInProgressOnly();
PrismObject<ShadowType> shadowProvisioning = provisioningService.getObject(ShadowType.class,
ACCOUNT_WILL_OID, null, task, result);
display("Provisioning shadow", shadowProvisioning);
ShadowType shadowTypeProvisioning = shadowProvisioning.asObjectable();
assertShadowName(shadowProvisioning, ACCOUNT_WILL_USERNAME);
assertEquals("Wrong kind (provisioning)", ShadowKindType.ACCOUNT, shadowTypeProvisioning.getKind());
assertAttribute(shadowProvisioning, ATTR_USERNAME_QNAME, ACCOUNT_WILL_USERNAME);
assertAttributeFromCache(shadowProvisioning, ATTR_FULLNAME_QNAME, ACCOUNT_WILL_FULLNAME);
assertShadowActivationAdministrativeStatusFromCache(shadowProvisioning, ActivationStatusType.ENABLED);
assertShadowExists(shadowProvisioning, false);
assertNoShadowPassword(shadowProvisioning);
assertSinglePendingOperation(shadowProvisioning, accountWillReqestTimestampStart, accountWillReqestTimestampEnd);
assertNotNull("No async reference in result", willLastCaseOid);
assertCase(willLastCaseOid, SchemaConstants.CASE_STATE_OPEN);
}
@Test
public void test102GetAccountWillFuture() throws Exception {
final String TEST_NAME = "test102GetAccountWillFuture";
displayTestTile(TEST_NAME);
// GIVEN
Task task = createTask(TEST_NAME);
OperationResult result = task.getResult();
syncServiceMock.reset();
Collection<SelectorOptions<GetOperationOptions>> options = SelectorOptions.createCollection(GetOperationOptions.createPointInTimeType(PointInTimeType.FUTURE));
// WHEN
displayWhen(TEST_NAME);
PrismObject<ShadowType> shadowProvisioning = provisioningService.getObject(ShadowType.class, ACCOUNT_WILL_OID, options, task, result);
// THEN
displayThen(TEST_NAME);
assertSuccess(result);
display("Provisioning shadow", shadowProvisioning);
ShadowType shadowTypeProvisioning = shadowProvisioning.asObjectable();
assertShadowName(shadowProvisioning, ACCOUNT_WILL_USERNAME);
assertEquals("Wrong kind (provisioning)", ShadowKindType.ACCOUNT, shadowTypeProvisioning.getKind());
assertAttribute(shadowProvisioning, ATTR_USERNAME_QNAME, ACCOUNT_WILL_USERNAME);
assertAttribute(shadowProvisioning, ATTR_FULLNAME_QNAME, ACCOUNT_WILL_FULLNAME);
assertNoAttribute(shadowProvisioning, ATTR_DESCRIPTION_QNAME);
assertShadowActivationAdministrativeStatus(shadowProvisioning, ActivationStatusType.ENABLED);
assertShadowExists(shadowProvisioning, true);
// TODO
// assertShadowPassword(shadowProvisioning);
}
/**
* Case haven't changed. There should be no change in the shadow.
*/
@Test
public void test104RefreshAccountWill() throws Exception {
final String TEST_NAME = "test104RefreshAccountWill";
displayTestTile(TEST_NAME);
// GIVEN
Task task = createTask(TEST_NAME);
OperationResult result = task.getResult();
syncServiceMock.reset();
PrismObject<ShadowType> shadowBefore = provisioningService.getObject(ShadowType.class, ACCOUNT_WILL_OID, null, task, result);
display("Shadow before", shadowBefore);
// WHEN
displayWhen(TEST_NAME);
provisioningService.refreshShadow(shadowBefore, null, task, result);
// THEN
displayThen(TEST_NAME);
assertSuccess(result);
PrismObject<ShadowType> shadowRepo = repositoryService.getObject(ShadowType.class, ACCOUNT_WILL_OID, null, result);
display("Repo shadow", shadowRepo);
assertSinglePendingOperation(shadowRepo, accountWillReqestTimestampStart, accountWillReqestTimestampEnd);
assertAttribute(shadowRepo, ATTR_USERNAME_QNAME, ACCOUNT_WILL_USERNAME);
assertAttributeFromCache(shadowRepo, ATTR_FULLNAME_QNAME, ACCOUNT_WILL_FULLNAME);
assertNoAttribute(shadowRepo, ATTR_DESCRIPTION_QNAME);
assertShadowActivationAdministrativeStatusFromCache(shadowRepo, ActivationStatusType.ENABLED);
assertNoShadowPassword(shadowRepo);
assertShadowExists(shadowRepo, false);
syncServiceMock.assertNoNotifyChange();
syncServiceMock.assertNoNotifcations();
PrismObject<ShadowType> shadowProvisioning = provisioningService.getObject(ShadowType.class,
ACCOUNT_WILL_OID, null, task, result);
display("Provisioning shadow", shadowProvisioning);
ShadowType shadowTypeProvisioning = shadowProvisioning.asObjectable();
assertShadowName(shadowProvisioning, ACCOUNT_WILL_USERNAME);
assertEquals("Wrong kind (provisioning)", ShadowKindType.ACCOUNT, shadowTypeProvisioning.getKind());
assertAttribute(shadowProvisioning, ATTR_USERNAME_QNAME, ACCOUNT_WILL_USERNAME);
assertAttributeFromCache(shadowProvisioning, ATTR_FULLNAME_QNAME, ACCOUNT_WILL_FULLNAME);
assertNoAttribute(shadowProvisioning, ATTR_DESCRIPTION_QNAME);
assertShadowActivationAdministrativeStatusFromCache(shadowProvisioning, ActivationStatusType.ENABLED);
assertNoShadowPassword(shadowProvisioning);
PendingOperationType pendingOperation = assertSinglePendingOperation(shadowProvisioning, 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();
syncServiceMock.reset();
// WHEN
displayWhen(TEST_NAME);
PrismObject<ShadowType> shadowProvisioning = provisioningService.getObject(ShadowType.class, ACCOUNT_WILL_OID, null, task, result);
// THEN
displayThen(TEST_NAME);
assertSuccess(result);
display("Provisioning shadow", shadowProvisioning);
ShadowType shadowTypeProvisioning = shadowProvisioning.asObjectable();
assertShadowName(shadowProvisioning, ACCOUNT_WILL_USERNAME);
assertEquals("Wrong kind (provisioning)", ShadowKindType.ACCOUNT, shadowTypeProvisioning.getKind());
assertAttribute(shadowProvisioning, ATTR_USERNAME_QNAME, ACCOUNT_WILL_USERNAME);
assertAttribute(shadowProvisioning, ATTR_FULLNAME_QNAME, ACCOUNT_WILL_FULLNAME);
assertAttributeFromBackingStore(shadowProvisioning, ATTR_DESCRIPTION_QNAME, ACCOUNT_WILL_DESCRIPTION_MANUAL);
assertShadowActivationAdministrativeStatus(shadowProvisioning, ActivationStatusType.ENABLED);
assertShadowExists(shadowProvisioning, supportsBackingStore());
assertShadowPassword(shadowProvisioning);
PrismObject<ShadowType> shadowRepo = repositoryService.getObject(ShadowType.class, ACCOUNT_WILL_OID, null, result);
display("Repo shadow", shadowRepo);
assertSinglePendingOperation(shadowRepo, accountWillReqestTimestampStart, accountWillReqestTimestampEnd);
assertAttribute(shadowRepo, ATTR_USERNAME_QNAME, ACCOUNT_WILL_USERNAME);
assertAttributeFromCache(shadowRepo, ATTR_FULLNAME_QNAME, ACCOUNT_WILL_FULLNAME);
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();
syncServiceMock.reset();
Collection<SelectorOptions<GetOperationOptions>> options = SelectorOptions.createCollection(GetOperationOptions.createPointInTimeType(PointInTimeType.FUTURE));
// WHEN
displayWhen(TEST_NAME);
PrismObject<ShadowType> shadowProvisioning = provisioningService.getObject(ShadowType.class, ACCOUNT_WILL_OID, options, task, result);
// THEN
displayThen(TEST_NAME);
assertSuccess(result);
display("Provisioning shadow", shadowProvisioning);
assertNotNull("no OID", shadowProvisioning.getOid());
ShadowType shadowTypeProvisioning = shadowProvisioning.asObjectable();
assertShadowName(shadowProvisioning, ACCOUNT_WILL_USERNAME);
assertEquals("Wrong kind (provisioning)", ShadowKindType.ACCOUNT, shadowTypeProvisioning.getKind());
assertAttribute(shadowProvisioning, ATTR_USERNAME_QNAME, ACCOUNT_WILL_USERNAME);
assertAttribute(shadowProvisioning, ATTR_FULLNAME_QNAME, ACCOUNT_WILL_FULLNAME);
assertAttributeFromBackingStore(shadowProvisioning, ATTR_DESCRIPTION_QNAME, ACCOUNT_WILL_DESCRIPTION_MANUAL);
assertShadowActivationAdministrativeStatus(shadowProvisioning, ActivationStatusType.ENABLED);
assertShadowExists(shadowProvisioning, true);
// TODO
// assertShadowPassword(shadowProvisioning);
PrismObject<ShadowType> shadowRepo = repositoryService.getObject(ShadowType.class, ACCOUNT_WILL_OID, null, result);
display("Repo shadow", shadowRepo);
assertSinglePendingOperation(shadowRepo, accountWillReqestTimestampStart, accountWillReqestTimestampEnd);
assertAttribute(shadowRepo, ATTR_USERNAME_QNAME, ACCOUNT_WILL_USERNAME);
assertAttributeFromCache(shadowRepo, ATTR_FULLNAME_QNAME, ACCOUNT_WILL_FULLNAME);
assertNoAttribute(shadowRepo, ATTR_DESCRIPTION_QNAME);
assertShadowActivationAdministrativeStatusFromCache(shadowRepo, ActivationStatusType.ENABLED);
assertNoShadowPassword(shadowRepo);
assertShadowExists(shadowRepo, supportsBackingStore());
}
@Test
public void test109GetAccountWillFutureNoFetch() throws Exception {
final String TEST_NAME = "test109GetAccountWillFutureNoFetch";
displayTestTile(TEST_NAME);
// GIVEN
Task task = createTask(TEST_NAME);
OperationResult result = task.getResult();
GetOperationOptions options = GetOperationOptions.createPointInTimeType(PointInTimeType.FUTURE);
options.setNoFetch(true);
// WHEN
displayWhen(TEST_NAME);
PrismObject<ShadowType> shadowProvisioningFuture = provisioningService.getObject(ShadowType.class,
ACCOUNT_WILL_OID,
SelectorOptions.createCollection(options),
task, result);
// THEN
displayThen(TEST_NAME);
assertSuccess(result);
display("Provisioning shadow (future,noFetch)", shadowProvisioningFuture);
assertNotNull("no OID", shadowProvisioningFuture.getOid());
ShadowType shadowTypeProvisioning = shadowProvisioningFuture.asObjectable();
assertShadowName(shadowProvisioningFuture, ACCOUNT_WILL_USERNAME);
assertEquals("Wrong kind (provisioning)", ShadowKindType.ACCOUNT, shadowTypeProvisioning.getKind());
assertAttribute(shadowProvisioningFuture, ATTR_USERNAME_QNAME, ACCOUNT_WILL_USERNAME);
assertAttributeFromCache(shadowProvisioningFuture, ATTR_FULLNAME_QNAME, ACCOUNT_WILL_FULLNAME);
assertNoAttribute(shadowProvisioningFuture, ATTR_DESCRIPTION_QNAME);
assertShadowActivationAdministrativeStatusFromCache(shadowProvisioningFuture, ActivationStatusType.ENABLED);
assertShadowExists(shadowProvisioningFuture, true);
// TODO
// assertShadowPassword(shadowProvisioningFuture);
}
/**
* Case is closed. The operation is complete.
*/
@Test
public void test110CloseCaseAndRefreshAccountWill() throws Exception {
final String TEST_NAME = "test110CloseCaseAndRefreshAccountWill";
displayTestTile(TEST_NAME);
// GIVEN
Task task = createTask(TEST_NAME);
OperationResult result = task.getResult();
syncServiceMock.reset();
PrismObject<ShadowType> shadowBefore = provisioningService.getObject(ShadowType.class, ACCOUNT_WILL_OID, null, task, result);
display("Shadow before", shadowBefore);
closeCase(willLastCaseOid);
accountWillCompletionTimestampStart = clock.currentTimeXMLGregorianCalendar();
// WHEN
displayWhen(TEST_NAME);
provisioningService.refreshShadow(shadowBefore, null, task, result);
// THEN
displayThen(TEST_NAME);
assertSuccess(result);
accountWillCompletionTimestampEnd = clock.currentTimeXMLGregorianCalendar();
PrismObject<ShadowType> shadowRepo = repositoryService.getObject(ShadowType.class, ACCOUNT_WILL_OID, null, result);
display("Repo shadow", shadowRepo);
assertSinglePendingOperation(shadowRepo,
accountWillReqestTimestampStart, accountWillReqestTimestampEnd,
OperationResultStatusType.SUCCESS,
accountWillCompletionTimestampStart, accountWillCompletionTimestampEnd);
assertAttribute(shadowRepo, ATTR_USERNAME_QNAME, ACCOUNT_WILL_USERNAME);
assertAttributeFromCache(shadowRepo, ATTR_FULLNAME_QNAME, ACCOUNT_WILL_FULLNAME);
assertShadowActivationAdministrativeStatusFromCache(shadowRepo, ActivationStatusType.ENABLED);
syncServiceMock.assertNoNotifyChange();
syncServiceMock.assertNotifySuccessOnly();
PrismObject<ShadowType> shadowProvisioning = provisioningService.getObject(ShadowType.class,
ACCOUNT_WILL_OID, null, task, result);
display("Provisioning shadow", shadowProvisioning);
ShadowType shadowTypeProvisioning = shadowProvisioning.asObjectable();
assertShadowName(shadowProvisioning, ACCOUNT_WILL_USERNAME);
assertEquals("Wrong kind (provisioning)", ShadowKindType.ACCOUNT, shadowTypeProvisioning.getKind());
assertAttribute(shadowProvisioning, ATTR_USERNAME_QNAME, ACCOUNT_WILL_USERNAME);
assertAttribute(shadowProvisioning, ATTR_FULLNAME_QNAME, ACCOUNT_WILL_FULLNAME);
assertAttributeFromBackingStore(shadowProvisioning, ATTR_DESCRIPTION_QNAME, ACCOUNT_WILL_DESCRIPTION_MANUAL);
assertShadowActivationAdministrativeStatus(shadowProvisioning, ActivationStatusType.ENABLED);
assertShadowPassword(shadowProvisioning);
PendingOperationType pendingOperation = assertSinglePendingOperation(shadowProvisioning,
accountWillReqestTimestampStart, accountWillReqestTimestampEnd,
OperationResultStatusType.SUCCESS,
accountWillCompletionTimestampStart, accountWillCompletionTimestampEnd);
assertCase(willLastCaseOid, SchemaConstants.CASE_STATE_CLOSED);
}
/**
* ff 5min, everything should be the same (grace not expired yet)
*/
@Test
public void test120RefreshAccountWillAfter5min() throws Exception {
final String TEST_NAME = "test120RefreshAccountWillAfter5min";
displayTestTile(TEST_NAME);
// GIVEN
Task task = createTask(TEST_NAME);
OperationResult result = task.getResult();
syncServiceMock.reset();
clock.overrideDuration("PT5M");
PrismObject<ShadowType> shadowBefore = provisioningService.getObject(ShadowType.class, ACCOUNT_WILL_OID, null, task, result);
display("Shadow before", shadowBefore);
// WHEN
displayWhen(TEST_NAME);
provisioningService.refreshShadow(shadowBefore, null, task, result);
// THEN
displayThen(TEST_NAME);
assertSuccess(result);
PrismObject<ShadowType> shadowRepo = repositoryService.getObject(ShadowType.class, ACCOUNT_WILL_OID, null, result);
display("Repo shadow", shadowRepo);
assertSinglePendingOperation(shadowRepo,
accountWillReqestTimestampStart, accountWillReqestTimestampEnd,
OperationResultStatusType.SUCCESS,
accountWillCompletionTimestampStart, accountWillCompletionTimestampEnd);
syncServiceMock.assertNoNotifyChange();
PrismObject<ShadowType> shadowProvisioning = provisioningService.getObject(ShadowType.class,
ACCOUNT_WILL_OID, null, task, result);
PendingOperationType pendingOperation = assertSinglePendingOperation(shadowProvisioning,
accountWillReqestTimestampStart, accountWillReqestTimestampEnd,
OperationResultStatusType.SUCCESS,
accountWillCompletionTimestampStart, accountWillCompletionTimestampEnd);
assertCase(willLastCaseOid, SchemaConstants.CASE_STATE_CLOSED);
syncServiceMock.assertNoNotifyChange();
syncServiceMock.assertNoNotifcations();
}
/**
* ff 20min, grace should expire
*/
@Test
public void test130RefreshAccountWillAfter25min() throws Exception {
final String TEST_NAME = "test130RefreshAccountWillAfter25min";
displayTestTile(TEST_NAME);
// GIVEN
Task task = createTask(TEST_NAME);
OperationResult result = task.getResult();
syncServiceMock.reset();
clock.overrideDuration("PT20M");
PrismObject<ShadowType> shadowBefore = provisioningService.getObject(ShadowType.class, ACCOUNT_WILL_OID, null, task, result);
display("Shadow before", shadowBefore);
// WHEN
displayWhen(TEST_NAME);
provisioningService.refreshShadow(shadowBefore, null, task, result);
// THEN
displayThen(TEST_NAME);
assertSuccess(result);
PrismObject<ShadowType> shadowRepo = repositoryService.getObject(ShadowType.class, ACCOUNT_WILL_OID, null, result);
display("Repo shadow", shadowRepo);
assertNoPendingOperation(shadowRepo);
syncServiceMock.assertNoNotifyChange();
PrismObject<ShadowType> shadowProvisioning = provisioningService.getObject(ShadowType.class,
ACCOUNT_WILL_OID, null, task, result);
assertNoPendingOperation(shadowProvisioning);
assertCase(willLastCaseOid, SchemaConstants.CASE_STATE_CLOSED);
syncServiceMock.assertNoNotifyChange();
syncServiceMock.assertNoNotifcations();
}
@Test
public void test200ModifyAccountWillFullname() throws Exception {
final String TEST_NAME = "test200ModifyAccountWillFullname";
displayTestTile(TEST_NAME);
// GIVEN
Task task = createTask(TEST_NAME);
OperationResult result = task.getResult();
syncServiceMock.reset();
ObjectDelta<ShadowType> delta = ObjectDelta.createModificationReplaceProperty(ShadowType.class,
ACCOUNT_WILL_OID, new ItemPath(ShadowType.F_ATTRIBUTES, ATTR_FULLNAME_QNAME), prismContext,
ACCOUNT_WILL_FULLNAME_PIRATE);
display("ObjectDelta", delta);
accountWillReqestTimestampStart = clock.currentTimeXMLGregorianCalendar();
// WHEN
displayWhen(TEST_NAME);
provisioningService.modifyObject(ShadowType.class, delta.getOid(), delta.getModifications(),
null, null, task, result);
// THEN
displayThen(TEST_NAME);
display("result", result);
willLastCaseOid = assertInProgress(result);
accountWillReqestTimestampEnd = clock.currentTimeXMLGregorianCalendar();
PrismObject<ShadowType> shadowRepo = repositoryService.getObject(ShadowType.class, ACCOUNT_WILL_OID, 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, ACCOUNT_WILL_USERNAME);
assertAttributeFromCache(shadowRepo, ATTR_FULLNAME_QNAME, ACCOUNT_WILL_FULLNAME);
syncServiceMock.assertNoNotifyChange();
syncServiceMock.assertNotifyInProgressOnly();
PrismObject<ShadowType> shadowProvisioning = provisioningService.getObject(ShadowType.class,
ACCOUNT_WILL_OID, null, task, result);
display("Provisioning shadow", shadowProvisioning);
ShadowType shadowTypeProvisioning = shadowProvisioning.asObjectable();
assertShadowName(shadowProvisioning, ACCOUNT_WILL_USERNAME);
assertEquals("Wrong kind (provisioning)", ShadowKindType.ACCOUNT, shadowTypeProvisioning.getKind());
assertShadowActivationAdministrativeStatus(shadowProvisioning, ActivationStatusType.ENABLED);
assertAttribute(shadowProvisioning, ATTR_USERNAME_QNAME, ACCOUNT_WILL_USERNAME);
assertAttribute(shadowProvisioning, ATTR_FULLNAME_QNAME, ACCOUNT_WILL_FULLNAME);
assertAttributeFromBackingStore(shadowProvisioning, ATTR_DESCRIPTION_QNAME, ACCOUNT_WILL_DESCRIPTION_MANUAL);
assertShadowPassword(shadowProvisioning);
assertSinglePendingOperation(shadowProvisioning, accountWillReqestTimestampStart, accountWillReqestTimestampEnd);
PrismObject<ShadowType> shadowProvisioningFuture = provisioningService.getObject(ShadowType.class,
ACCOUNT_WILL_OID,
SelectorOptions.createCollection(GetOperationOptions.createPointInTimeType(PointInTimeType.FUTURE)),
task, result);
display("Provisioning shadow (future)", shadowProvisioningFuture);
assertShadowName(shadowProvisioningFuture, ACCOUNT_WILL_USERNAME);
assertEquals("Wrong kind (provisioning)", ShadowKindType.ACCOUNT, shadowProvisioningFuture.asObjectable().getKind());
assertShadowActivationAdministrativeStatus(shadowProvisioningFuture, ActivationStatusType.ENABLED);
assertAttribute(shadowProvisioningFuture, ATTR_USERNAME_QNAME, ACCOUNT_WILL_USERNAME);
assertAttribute(shadowProvisioningFuture, ATTR_FULLNAME_QNAME, ACCOUNT_WILL_FULLNAME_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 test202RefreshAccountWill() throws Exception {
final String TEST_NAME = "test202RefreshAccountWill";
displayTestTile(TEST_NAME);
// GIVEN
Task task = createTask(TEST_NAME);
OperationResult result = task.getResult();
syncServiceMock.reset();
PrismObject<ShadowType> shadowBefore = provisioningService.getObject(ShadowType.class, ACCOUNT_WILL_OID, null, task, result);
display("Shadow before", shadowBefore);
// WHEN
displayWhen(TEST_NAME);
provisioningService.refreshShadow(shadowBefore, null, task, result);
// THEN
displayThen(TEST_NAME);
assertSuccess(result);
PrismObject<ShadowType> shadowRepo = repositoryService.getObject(ShadowType.class, ACCOUNT_WILL_OID, 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, ACCOUNT_WILL_USERNAME);
assertAttributeFromCache(shadowRepo, ATTR_FULLNAME_QNAME, ACCOUNT_WILL_FULLNAME);
syncServiceMock.assertNoNotifyChange();
syncServiceMock.assertNoNotifcations();
PrismObject<ShadowType> shadowProvisioning = provisioningService.getObject(ShadowType.class,
ACCOUNT_WILL_OID, null, task, result);
display("Provisioning shadow", shadowProvisioning);
ShadowType shadowTypeProvisioning = shadowProvisioning.asObjectable();
assertShadowName(shadowProvisioning, ACCOUNT_WILL_USERNAME);
assertEquals("Wrong kind (provisioning)", ShadowKindType.ACCOUNT, shadowTypeProvisioning.getKind());
assertShadowActivationAdministrativeStatus(shadowProvisioning, ActivationStatusType.ENABLED);
assertAttribute(shadowProvisioning, ATTR_USERNAME_QNAME, ACCOUNT_WILL_USERNAME);
assertAttribute(shadowProvisioning, ATTR_FULLNAME_QNAME, ACCOUNT_WILL_FULLNAME);
assertShadowPassword(shadowProvisioning);
assertSinglePendingOperation(shadowProvisioning, accountWillReqestTimestampStart, accountWillReqestTimestampEnd);
PrismObject<ShadowType> shadowProvisioningFuture = provisioningService.getObject(ShadowType.class,
ACCOUNT_WILL_OID,
SelectorOptions.createCollection(GetOperationOptions.createPointInTimeType(PointInTimeType.FUTURE)),
task, result);
display("Provisioning shadow (future)", shadowProvisioningFuture);
assertShadowName(shadowProvisioningFuture, ACCOUNT_WILL_USERNAME);
assertEquals("Wrong kind (provisioning)", ShadowKindType.ACCOUNT, shadowProvisioningFuture.asObjectable().getKind());
assertShadowActivationAdministrativeStatus(shadowProvisioningFuture, ActivationStatusType.ENABLED);
assertAttribute(shadowProvisioningFuture, ATTR_USERNAME_QNAME, ACCOUNT_WILL_USERNAME);
assertAttribute(shadowProvisioningFuture, ATTR_FULLNAME_QNAME, ACCOUNT_WILL_FULLNAME_PIRATE);
assertShadowPassword(shadowProvisioningFuture);
assertCase(willLastCaseOid, SchemaConstants.CASE_STATE_OPEN);
}
/**
* Case is closed. The operation is complete.
*/
@Test
public void test204CloseCaseAndRefreshAccountWill() throws Exception {
final String TEST_NAME = "test204CloseCaseAndRefreshAccountWill";
displayTestTile(TEST_NAME);
// GIVEN
Task task = createTask(TEST_NAME);
OperationResult result = task.getResult();
syncServiceMock.reset();
PrismObject<ShadowType> shadowBefore = provisioningService.getObject(ShadowType.class, ACCOUNT_WILL_OID, null, task, result);
display("Shadow before", shadowBefore);
closeCase(willLastCaseOid);
accountWillCompletionTimestampStart = clock.currentTimeXMLGregorianCalendar();
// WHEN
displayWhen(TEST_NAME);
provisioningService.refreshShadow(shadowBefore, null, task, result);
// THEN
displayThen(TEST_NAME);
assertSuccess(result);
accountWillCompletionTimestampEnd = clock.currentTimeXMLGregorianCalendar();
PrismObject<ShadowType> shadowRepo = repositoryService.getObject(ShadowType.class, ACCOUNT_WILL_OID, null, result);
display("Repo shadow", shadowRepo);
assertSinglePendingOperation(shadowRepo,
accountWillReqestTimestampStart, accountWillReqestTimestampEnd,
OperationResultStatusType.SUCCESS,
accountWillCompletionTimestampStart, accountWillCompletionTimestampEnd);
assertShadowActivationAdministrativeStatusFromCache(shadowRepo, ActivationStatusType.ENABLED);
assertAttribute(shadowRepo, ATTR_USERNAME_QNAME, ACCOUNT_WILL_USERNAME);
assertAttributeFromCache(shadowRepo, ATTR_FULLNAME_QNAME, ACCOUNT_WILL_FULLNAME_PIRATE);
PrismObject<ShadowType> shadowProvisioning = provisioningService.getObject(ShadowType.class,
ACCOUNT_WILL_OID, null, task, result);
display("Provisioning shadow", shadowProvisioning);
ShadowType shadowTypeProvisioning = shadowProvisioning.asObjectable();
assertShadowName(shadowProvisioning, ACCOUNT_WILL_USERNAME);
assertEquals("Wrong kind (provisioning)", ShadowKindType.ACCOUNT, shadowTypeProvisioning.getKind());
assertShadowActivationAdministrativeStatus(shadowProvisioning, ActivationStatusType.ENABLED);
assertAttribute(shadowProvisioning, ATTR_USERNAME_QNAME, ACCOUNT_WILL_USERNAME);
if (supportsBackingStore()) {
assertAttribute(shadowProvisioning, ATTR_FULLNAME_QNAME, ACCOUNT_WILL_FULLNAME);
} else {
assertAttribute(shadowProvisioning, ATTR_FULLNAME_QNAME, ACCOUNT_WILL_FULLNAME_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 = provisioningService.getObject(ShadowType.class,
ACCOUNT_WILL_OID,
SelectorOptions.createCollection(GetOperationOptions.createPointInTimeType(PointInTimeType.FUTURE)),
task, result);
display("Provisioning shadow (future)", shadowProvisioningFuture);
assertShadowName(shadowProvisioningFuture, ACCOUNT_WILL_USERNAME);
assertEquals("Wrong kind (provisioning)", ShadowKindType.ACCOUNT, shadowProvisioningFuture.asObjectable().getKind());
assertShadowActivationAdministrativeStatus(shadowProvisioningFuture, ActivationStatusType.ENABLED);
assertAttribute(shadowProvisioningFuture, ATTR_USERNAME_QNAME, ACCOUNT_WILL_USERNAME);
assertAttribute(shadowProvisioningFuture, ATTR_FULLNAME_QNAME, ACCOUNT_WILL_FULLNAME_PIRATE);
assertAttributeFromBackingStore(shadowProvisioningFuture, ATTR_DESCRIPTION_QNAME, ACCOUNT_WILL_DESCRIPTION_MANUAL);
assertShadowPassword(shadowProvisioningFuture);
assertCase(willLastCaseOid, SchemaConstants.CASE_STATE_CLOSED);
// In this case check notifications at the end. There were some reads that
// internally triggered refresh. Maku sure no extra notifications were sent.
syncServiceMock.assertNoNotifyChange();
syncServiceMock.assertNotifySuccessOnly();
}
/**
* ff 5min, everything should be the same (grace not expired yet)
*/
@Test
public void test210RefreshAccountWillAfter5min() throws Exception {
final String TEST_NAME = "test210RefreshAccountWillAfter5min";
displayTestTile(TEST_NAME);
// GIVEN
Task task = createTask(TEST_NAME);
OperationResult result = task.getResult();
syncServiceMock.reset();
clock.overrideDuration("PT5M");
PrismObject<ShadowType> shadowBefore = provisioningService.getObject(ShadowType.class, ACCOUNT_WILL_OID, null, task, result);
display("Shadow before", shadowBefore);
// WHEN
displayWhen(TEST_NAME);
provisioningService.refreshShadow(shadowBefore, null, task, result);
// THEN
displayThen(TEST_NAME);
assertSuccess(result);
PrismObject<ShadowType> shadowRepo = repositoryService.getObject(ShadowType.class, ACCOUNT_WILL_OID, null, result);
display("Repo shadow", shadowRepo);
assertSinglePendingOperation(shadowRepo,
accountWillReqestTimestampStart, accountWillReqestTimestampEnd,
OperationResultStatusType.SUCCESS,
accountWillCompletionTimestampStart, accountWillCompletionTimestampEnd);
syncServiceMock.assertNoNotifyChange();
syncServiceMock.assertNoNotifcations();
PrismObject<ShadowType> shadowProvisioning = provisioningService.getObject(ShadowType.class,
ACCOUNT_WILL_OID, null, task, result);
assertShadowActivationAdministrativeStatus(shadowProvisioning, ActivationStatusType.ENABLED);
assertAttribute(shadowProvisioning, ATTR_USERNAME_QNAME, ACCOUNT_WILL_USERNAME);
if (supportsBackingStore()) {
assertAttribute(shadowProvisioning, ATTR_FULLNAME_QNAME, ACCOUNT_WILL_FULLNAME);
} else {
assertAttribute(shadowProvisioning, ATTR_FULLNAME_QNAME, ACCOUNT_WILL_FULLNAME_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 = provisioningService.getObject(ShadowType.class,
ACCOUNT_WILL_OID,
SelectorOptions.createCollection(GetOperationOptions.createPointInTimeType(PointInTimeType.FUTURE)),
task, result);
display("Provisioning shadow (future)", shadowProvisioningFuture);
assertShadowName(shadowProvisioningFuture, ACCOUNT_WILL_USERNAME);
assertEquals("Wrong kind (provisioning)", ShadowKindType.ACCOUNT, shadowProvisioningFuture.asObjectable().getKind());
assertShadowActivationAdministrativeStatus(shadowProvisioningFuture, ActivationStatusType.ENABLED);
assertAttribute(shadowProvisioningFuture, ATTR_USERNAME_QNAME, ACCOUNT_WILL_USERNAME);
assertAttribute(shadowProvisioningFuture, ATTR_FULLNAME_QNAME, ACCOUNT_WILL_FULLNAME_PIRATE);
assertAttributeFromBackingStore(shadowProvisioningFuture, ATTR_DESCRIPTION_QNAME, ACCOUNT_WILL_DESCRIPTION_MANUAL);
assertShadowPassword(shadowProvisioningFuture);
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();
syncServiceMock.reset();
PrismObject<ShadowType> shadowBefore = provisioningService.getObject(ShadowType.class, ACCOUNT_WILL_OID, null, task, result);
display("Shadow before", shadowBefore);
backingStoreUpdateWill(ACCOUNT_WILL_FULLNAME_PIRATE, ActivationStatusType.ENABLED, ACCOUNT_WILL_PASSWORD_OLD);
// WHEN
displayWhen(TEST_NAME);
provisioningService.refreshShadow(shadowBefore, null, task, result);
// THEN
displayThen(TEST_NAME);
assertSuccess(result);
PrismObject<ShadowType> shadowRepo = repositoryService.getObject(ShadowType.class, ACCOUNT_WILL_OID, null, result);
display("Repo shadow", shadowRepo);
assertSinglePendingOperation(shadowRepo,
accountWillReqestTimestampStart, accountWillReqestTimestampEnd,
OperationResultStatusType.SUCCESS,
accountWillCompletionTimestampStart, accountWillCompletionTimestampEnd);
syncServiceMock.assertNoNotifyChange();
syncServiceMock.assertNoNotifcations();
PrismObject<ShadowType> shadowProvisioning = provisioningService.getObject(ShadowType.class,
ACCOUNT_WILL_OID, null, task, result);
assertShadowActivationAdministrativeStatus(shadowProvisioning, ActivationStatusType.ENABLED);
assertAttribute(shadowProvisioning, ATTR_USERNAME_QNAME, ACCOUNT_WILL_USERNAME);
assertAttribute(shadowProvisioning, ATTR_FULLNAME_QNAME, ACCOUNT_WILL_FULLNAME_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 = provisioningService.getObject(ShadowType.class,
ACCOUNT_WILL_OID,
SelectorOptions.createCollection(GetOperationOptions.createPointInTimeType(PointInTimeType.FUTURE)),
task, result);
display("Provisioning shadow (future)", shadowProvisioningFuture);
assertShadowName(shadowProvisioningFuture, ACCOUNT_WILL_USERNAME);
assertEquals("Wrong kind (provisioning)", ShadowKindType.ACCOUNT, shadowProvisioningFuture.asObjectable().getKind());
assertShadowActivationAdministrativeStatus(shadowProvisioningFuture, ActivationStatusType.ENABLED);
assertAttribute(shadowProvisioningFuture, ATTR_USERNAME_QNAME, ACCOUNT_WILL_USERNAME);
assertAttribute(shadowProvisioningFuture, ATTR_FULLNAME_QNAME, ACCOUNT_WILL_FULLNAME_PIRATE);
assertAttributeFromBackingStore(shadowProvisioningFuture, ATTR_DESCRIPTION_QNAME, ACCOUNT_WILL_DESCRIPTION_MANUAL);
assertShadowPassword(shadowProvisioningFuture);
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 test220ModifyAccountWillDisable() throws Exception {
final String TEST_NAME = "test220ModifyAccountWillDisable";
displayTestTile(TEST_NAME);
// GIVEN
Task task = createTask(TEST_NAME);
OperationResult result = task.getResult();
syncServiceMock.reset();
ObjectDelta<ShadowType> delta = ObjectDelta.createModificationReplaceProperty(ShadowType.class,
ACCOUNT_WILL_OID, SchemaConstants.PATH_ACTIVATION_ADMINISTRATIVE_STATUS, prismContext,
ActivationStatusType.DISABLED);
display("ObjectDelta", delta);
accountWillReqestTimestampStart = clock.currentTimeXMLGregorianCalendar();
// WHEN
displayWhen(TEST_NAME);
provisioningService.modifyObject(ShadowType.class, delta.getOid(), delta.getModifications(),
null, null, task, result);
// THEN
displayThen(TEST_NAME);
display("result", result);
willLastCaseOid = assertInProgress(result);
accountWillReqestTimestampEnd = clock.currentTimeXMLGregorianCalendar();
PrismObject<ShadowType> shadowRepo = repositoryService.getObject(ShadowType.class, ACCOUNT_WILL_OID, 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, ACCOUNT_WILL_USERNAME);
assertAttributeFromCache(shadowRepo, ATTR_FULLNAME_QNAME, ACCOUNT_WILL_FULLNAME_PIRATE);
syncServiceMock.assertNoNotifyChange();
syncServiceMock.assertNotifyInProgressOnly();
PrismObject<ShadowType> shadowProvisioning = provisioningService.getObject(ShadowType.class,
ACCOUNT_WILL_OID, null, task, result);
display("Provisioning shadow", shadowProvisioning);
ShadowType shadowTypeProvisioning = shadowProvisioning.asObjectable();
assertShadowName(shadowProvisioning, ACCOUNT_WILL_USERNAME);
assertEquals("Wrong kind (provisioning)", ShadowKindType.ACCOUNT, shadowTypeProvisioning.getKind());
assertShadowActivationAdministrativeStatus(shadowProvisioning, ActivationStatusType.ENABLED);
assertAttribute(shadowProvisioning, ATTR_USERNAME_QNAME, ACCOUNT_WILL_USERNAME);
assertAttribute(shadowProvisioning, ATTR_FULLNAME_QNAME, ACCOUNT_WILL_FULLNAME_PIRATE);
assertAttributeFromBackingStore(shadowProvisioning, ATTR_DESCRIPTION_QNAME, ACCOUNT_WILL_DESCRIPTION_MANUAL);
assertShadowPassword(shadowProvisioning);
assertPendingOperationDeltas(shadowProvisioning, 2);
pendingOperation = findPendingOperation(shadowProvisioning,
OperationResultStatusType.IN_PROGRESS, SchemaConstants.PATH_ACTIVATION_ADMINISTRATIVE_STATUS);
assertPendingOperation(shadowProvisioning, pendingOperation, accountWillReqestTimestampStart, accountWillReqestTimestampEnd);
PrismObject<ShadowType> shadowProvisioningFuture = provisioningService.getObject(ShadowType.class,
ACCOUNT_WILL_OID,
SelectorOptions.createCollection(GetOperationOptions.createPointInTimeType(PointInTimeType.FUTURE)),
task, result);
display("Provisioning shadow (future)", shadowProvisioningFuture);
assertShadowName(shadowProvisioningFuture, ACCOUNT_WILL_USERNAME);
assertEquals("Wrong kind (provisioning)", ShadowKindType.ACCOUNT, shadowProvisioningFuture.asObjectable().getKind());
assertShadowActivationAdministrativeStatus(shadowProvisioningFuture, ActivationStatusType.DISABLED);
assertAttribute(shadowProvisioningFuture, ATTR_USERNAME_QNAME, ACCOUNT_WILL_USERNAME);
assertAttribute(shadowProvisioningFuture, ATTR_FULLNAME_QNAME, ACCOUNT_WILL_FULLNAME_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);
}
/**
* 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();
syncServiceMock.reset();
ObjectDelta<ShadowType> delta = ObjectDelta.createModificationReplaceProperty(ShadowType.class,
ACCOUNT_WILL_OID, SchemaConstants.PATH_ACTIVATION_ADMINISTRATIVE_STATUS, prismContext,
ActivationStatusType.ENABLED);
ProtectedStringType ps = new ProtectedStringType();
ps.setClearValue(ACCOUNT_WILL_PASSWORD_NEW);
delta.addModificationReplaceProperty(SchemaConstants.PATH_PASSWORD_VALUE, ps);
display("ObjectDelta", delta);
accountWillSecondReqestTimestampStart = clock.currentTimeXMLGregorianCalendar();
// WHEN
displayWhen(TEST_NAME);
provisioningService.modifyObject(ShadowType.class, delta.getOid(), delta.getModifications(),
null, null, task, result);
// THEN
displayThen(TEST_NAME);
display("result", result);
willSecondLastCaseOid = assertInProgress(result);
accountWillSecondReqestTimestampEnd = clock.currentTimeXMLGregorianCalendar();
PrismObject<ShadowType> shadowRepo = repositoryService.getObject(ShadowType.class, ACCOUNT_WILL_OID, 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, ACCOUNT_WILL_USERNAME);
assertAttributeFromCache(shadowRepo, ATTR_FULLNAME_QNAME, ACCOUNT_WILL_FULLNAME_PIRATE);
syncServiceMock.assertNoNotifyChange();
syncServiceMock.assertNotifyInProgressOnly();
PrismObject<ShadowType> shadowProvisioning = provisioningService.getObject(ShadowType.class,
ACCOUNT_WILL_OID, null, task, result);
display("Provisioning shadow", shadowProvisioning);
ShadowType shadowTypeProvisioning = shadowProvisioning.asObjectable();
assertShadowName(shadowProvisioning, ACCOUNT_WILL_USERNAME);
assertEquals("Wrong kind (provisioning)", ShadowKindType.ACCOUNT, shadowTypeProvisioning.getKind());
assertShadowActivationAdministrativeStatus(shadowProvisioning, ActivationStatusType.ENABLED);
assertAttribute(shadowProvisioning, ATTR_USERNAME_QNAME, ACCOUNT_WILL_USERNAME);
assertAttribute(shadowProvisioning, ATTR_FULLNAME_QNAME, ACCOUNT_WILL_FULLNAME_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 = provisioningService.getObject(ShadowType.class,
ACCOUNT_WILL_OID,
SelectorOptions.createCollection(GetOperationOptions.createPointInTimeType(PointInTimeType.FUTURE)),
task, result);
display("Provisioning shadow (future)", shadowProvisioningFuture);
assertShadowName(shadowProvisioningFuture, ACCOUNT_WILL_USERNAME);
assertEquals("Wrong kind (provisioning)", ShadowKindType.ACCOUNT, shadowProvisioningFuture.asObjectable().getKind());
assertShadowActivationAdministrativeStatus(shadowProvisioningFuture, ActivationStatusType.ENABLED);
assertAttribute(shadowProvisioningFuture, ATTR_USERNAME_QNAME, ACCOUNT_WILL_USERNAME);
assertAttribute(shadowProvisioningFuture, ATTR_FULLNAME_QNAME, ACCOUNT_WILL_FULLNAME_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();
syncServiceMock.reset();
closeCase(willLastCaseOid);
PrismObject<ShadowType> shadowBefore = provisioningService.getObject(ShadowType.class, ACCOUNT_WILL_OID, null, task, result);
display("Shadow before", shadowBefore);
accountWillCompletionTimestampStart = clock.currentTimeXMLGregorianCalendar();
// WHEN
displayWhen(TEST_NAME);
PrismObject<ShadowType> shadowProvisioning = provisioningService.getObject(ShadowType.class,
ACCOUNT_WILL_OID, null, task, result);
// THEN
displayThen(TEST_NAME);
assertSuccess(result);
accountWillCompletionTimestampEnd = clock.currentTimeXMLGregorianCalendar();
PrismObject<ShadowType> shadowRepo = repositoryService.getObject(ShadowType.class, ACCOUNT_WILL_OID, 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, ACCOUNT_WILL_USERNAME);
assertAttributeFromCache(shadowRepo, ATTR_FULLNAME_QNAME, ACCOUNT_WILL_FULLNAME_PIRATE);
syncServiceMock.assertNoNotifyChange();
syncServiceMock.assertNotifySuccessOnly();
display("Provisioning shadow", shadowProvisioning);
ShadowType shadowTypeProvisioning = shadowProvisioning.asObjectable();
assertShadowName(shadowProvisioning, ACCOUNT_WILL_USERNAME);
assertEquals("Wrong kind (provisioning)", ShadowKindType.ACCOUNT, shadowTypeProvisioning.getKind());
if (supportsBackingStore()) {
assertShadowActivationAdministrativeStatus(shadowProvisioning, ActivationStatusType.ENABLED);
} else {
assertShadowActivationAdministrativeStatus(shadowProvisioning, ActivationStatusType.DISABLED);
}
assertAttribute(shadowProvisioning, ATTR_USERNAME_QNAME, ACCOUNT_WILL_USERNAME);
assertAttribute(shadowProvisioning, ATTR_FULLNAME_QNAME, ACCOUNT_WILL_FULLNAME_PIRATE);
assertAttributeFromBackingStore(shadowProvisioning, ATTR_DESCRIPTION_QNAME, ACCOUNT_WILL_DESCRIPTION_MANUAL);
assertShadowPassword(shadowProvisioning);
assertPendingOperationDeltas(shadowProvisioning, 3);
pendingOperation = findPendingOperation(shadowProvisioning,
OperationResultStatusType.SUCCESS, SchemaConstants.PATH_ACTIVATION_ADMINISTRATIVE_STATUS);
assertPendingOperation(shadowProvisioning, pendingOperation,
accountWillReqestTimestampStart, accountWillReqestTimestampEnd,
OperationResultStatusType.SUCCESS,
accountWillCompletionTimestampStart, accountWillCompletionTimestampEnd);
PrismObject<ShadowType> shadowProvisioningFuture = provisioningService.getObject(ShadowType.class,
ACCOUNT_WILL_OID,
SelectorOptions.createCollection(GetOperationOptions.createPointInTimeType(PointInTimeType.FUTURE)),
task, result);
display("Provisioning shadow (future)", shadowProvisioningFuture);
assertShadowName(shadowProvisioningFuture, ACCOUNT_WILL_USERNAME);
assertEquals("Wrong kind (provisioning)", ShadowKindType.ACCOUNT, shadowProvisioningFuture.asObjectable().getKind());
assertShadowActivationAdministrativeStatus(shadowProvisioningFuture, ActivationStatusType.ENABLED);
assertAttribute(shadowProvisioningFuture, ATTR_USERNAME_QNAME, ACCOUNT_WILL_USERNAME);
assertAttribute(shadowProvisioningFuture, ATTR_FULLNAME_QNAME, ACCOUNT_WILL_FULLNAME_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);
}
/**
* lets ff 5min just for fun. Refresh, make sure everything should be the same (grace not expired yet)
*/
@Test
public void test250RefreshAccountWillAfter5min() throws Exception {
final String TEST_NAME = "test250RefreshAccountWillAfter5min";
displayTestTile(TEST_NAME);
// GIVEN
Task task = createTask(TEST_NAME);
OperationResult result = task.getResult();
syncServiceMock.reset();
clock.overrideDuration("PT5M");
PrismObject<ShadowType> shadowBefore = provisioningService.getObject(ShadowType.class, ACCOUNT_WILL_OID, null, task, result);
display("Shadow before", shadowBefore);
// WHEN
displayWhen(TEST_NAME);
provisioningService.refreshShadow(shadowBefore, null, task, result);
// THEN
displayThen(TEST_NAME);
assertSuccess(result);
PrismObject<ShadowType> shadowRepo = repositoryService.getObject(ShadowType.class, ACCOUNT_WILL_OID, 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, ACCOUNT_WILL_USERNAME);
assertAttributeFromCache(shadowRepo, ATTR_FULLNAME_QNAME, ACCOUNT_WILL_FULLNAME_PIRATE);
syncServiceMock.assertNoNotifyChange();
syncServiceMock.assertNoNotifcations();
PrismObject<ShadowType> shadowProvisioning = provisioningService.getObject(ShadowType.class,
ACCOUNT_WILL_OID, null, task, result);
display("Provisioning shadow", shadowProvisioning);
ShadowType shadowTypeProvisioning = shadowProvisioning.asObjectable();
assertShadowName(shadowProvisioning, ACCOUNT_WILL_USERNAME);
assertEquals("Wrong kind (provisioning)", ShadowKindType.ACCOUNT, shadowTypeProvisioning.getKind());
if (supportsBackingStore()) {
assertShadowActivationAdministrativeStatus(shadowProvisioning, ActivationStatusType.ENABLED);
} else {
assertShadowActivationAdministrativeStatus(shadowProvisioning, ActivationStatusType.DISABLED);
}
assertAttribute(shadowProvisioning, ATTR_USERNAME_QNAME, ACCOUNT_WILL_USERNAME);
assertAttribute(shadowProvisioning, ATTR_FULLNAME_QNAME, ACCOUNT_WILL_FULLNAME_PIRATE);
assertAttributeFromBackingStore(shadowProvisioning, ATTR_DESCRIPTION_QNAME, ACCOUNT_WILL_DESCRIPTION_MANUAL);
assertShadowPassword(shadowProvisioning);
assertPendingOperationDeltas(shadowProvisioning, 3);
pendingOperation = findPendingOperation(shadowProvisioning,
OperationResultStatusType.SUCCESS, SchemaConstants.PATH_ACTIVATION_ADMINISTRATIVE_STATUS);
assertPendingOperation(shadowProvisioning, pendingOperation,
accountWillReqestTimestampStart, accountWillReqestTimestampEnd,
OperationResultStatusType.SUCCESS,
accountWillCompletionTimestampStart, accountWillCompletionTimestampEnd);
PrismObject<ShadowType> shadowProvisioningFuture = provisioningService.getObject(ShadowType.class,
ACCOUNT_WILL_OID,
SelectorOptions.createCollection(GetOperationOptions.createPointInTimeType(PointInTimeType.FUTURE)),
task, result);
display("Provisioning shadow (future)", shadowProvisioningFuture);
assertShadowName(shadowProvisioningFuture, ACCOUNT_WILL_USERNAME);
assertEquals("Wrong kind (provisioning)", ShadowKindType.ACCOUNT, shadowProvisioningFuture.asObjectable().getKind());
assertShadowActivationAdministrativeStatus(shadowProvisioningFuture, ActivationStatusType.ENABLED);
assertAttribute(shadowProvisioningFuture, ATTR_USERNAME_QNAME, ACCOUNT_WILL_USERNAME);
assertAttribute(shadowProvisioningFuture, ATTR_FULLNAME_QNAME, ACCOUNT_WILL_FULLNAME_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();
syncServiceMock.reset();
PrismObject<ShadowType> shadowBefore = provisioningService.getObject(ShadowType.class, ACCOUNT_WILL_OID, null, task, result);
display("Shadow before", shadowBefore);
backingStoreUpdateWill(ACCOUNT_WILL_FULLNAME_PIRATE, ActivationStatusType.DISABLED, ACCOUNT_WILL_PASSWORD_OLD);
// WHEN
displayWhen(TEST_NAME);
provisioningService.refreshShadow(shadowBefore, null, task, result);
// THEN
displayThen(TEST_NAME);
assertSuccess(result);
PrismObject<ShadowType> shadowRepo = repositoryService.getObject(ShadowType.class, ACCOUNT_WILL_OID, null, result);
display("Repo shadow", shadowRepo);
assertPendingOperationDeltas(shadowRepo, 3);
syncServiceMock.assertNoNotifyChange();
syncServiceMock.assertNoNotifcations();
PrismObject<ShadowType> shadowProvisioning = provisioningService.getObject(ShadowType.class,
ACCOUNT_WILL_OID, null, task, result);
display("Provisioning shadow", shadowProvisioning);
ShadowType shadowTypeProvisioning = shadowProvisioning.asObjectable();
assertShadowName(shadowProvisioning, ACCOUNT_WILL_USERNAME);
assertEquals("Wrong kind (provisioning)", ShadowKindType.ACCOUNT, shadowTypeProvisioning.getKind());
assertShadowActivationAdministrativeStatus(shadowProvisioning, ActivationStatusType.DISABLED);
assertAttribute(shadowProvisioning, ATTR_USERNAME_QNAME, ACCOUNT_WILL_USERNAME);
assertAttribute(shadowProvisioning, ATTR_FULLNAME_QNAME, ACCOUNT_WILL_FULLNAME_PIRATE);
assertAttributeFromBackingStore(shadowProvisioning, ATTR_DESCRIPTION_QNAME, ACCOUNT_WILL_DESCRIPTION_MANUAL);
assertShadowPassword(shadowProvisioning);
assertPendingOperationDeltas(shadowProvisioning, 3);
PrismObject<ShadowType> shadowProvisioningFuture = provisioningService.getObject(ShadowType.class,
ACCOUNT_WILL_OID,
SelectorOptions.createCollection(GetOperationOptions.createPointInTimeType(PointInTimeType.FUTURE)),
task, result);
display("Provisioning shadow (future)", shadowProvisioningFuture);
assertShadowName(shadowProvisioningFuture, ACCOUNT_WILL_USERNAME);
assertEquals("Wrong kind (provisioning)", ShadowKindType.ACCOUNT, shadowProvisioningFuture.asObjectable().getKind());
assertShadowActivationAdministrativeStatus(shadowProvisioningFuture, ActivationStatusType.ENABLED);
assertAttribute(shadowProvisioningFuture, ATTR_USERNAME_QNAME, ACCOUNT_WILL_USERNAME);
assertAttribute(shadowProvisioningFuture, ATTR_FULLNAME_QNAME, ACCOUNT_WILL_FULLNAME_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);
}
/**
* Password change/enable case is closed. The account should be disabled. But there is still the other
* delta pending.
*/
@Test
public void test260ClosePasswordChangeCaseAndRefreshAccountWill() throws Exception {
final String TEST_NAME = "test260ClosePasswordChangeCaseAndRefreshAccountWill";
displayTestTile(TEST_NAME);
// GIVEN
Task task = createTask(TEST_NAME);
OperationResult result = task.getResult();
syncServiceMock.reset();
closeCase(willSecondLastCaseOid);
// Get repo shadow here. Make sure refresh works with this as well.
PrismObject<ShadowType> shadowBefore = repositoryService.getObject(ShadowType.class, ACCOUNT_WILL_OID, null, result);
provisioningService.applyDefinition(shadowBefore, result);
display("Shadow before", shadowBefore);
accountWillSecondCompletionTimestampStart = clock.currentTimeXMLGregorianCalendar();
// WHEN
displayWhen(TEST_NAME);
provisioningService.refreshShadow(shadowBefore, null, task, result);
// THEN
displayThen(TEST_NAME);
assertSuccess(result);
accountWillSecondCompletionTimestampEnd = clock.currentTimeXMLGregorianCalendar();
PrismObject<ShadowType> shadowRepo = repositoryService.getObject(ShadowType.class, ACCOUNT_WILL_OID, 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, ACCOUNT_WILL_USERNAME);
assertAttributeFromCache(shadowRepo, ATTR_FULLNAME_QNAME, ACCOUNT_WILL_FULLNAME_PIRATE);
syncServiceMock.assertNoNotifyChange();
syncServiceMock.assertNotifySuccessOnly();
PrismObject<ShadowType> shadowProvisioning = provisioningService.getObject(ShadowType.class,
ACCOUNT_WILL_OID, null, task, result);
display("Provisioning shadow", shadowProvisioning);
ShadowType shadowTypeProvisioning = shadowProvisioning.asObjectable();
assertShadowName(shadowProvisioning, ACCOUNT_WILL_USERNAME);
assertEquals("Wrong kind (provisioning)", ShadowKindType.ACCOUNT, shadowTypeProvisioning.getKind());
if (supportsBackingStore()) {
assertShadowActivationAdministrativeStatus(shadowProvisioning, ActivationStatusType.DISABLED);
} else {
assertShadowActivationAdministrativeStatus(shadowProvisioning, ActivationStatusType.ENABLED);
}
assertAttribute(shadowProvisioning, ATTR_USERNAME_QNAME, ACCOUNT_WILL_USERNAME);
assertAttribute(shadowProvisioning, ATTR_FULLNAME_QNAME, ACCOUNT_WILL_FULLNAME_PIRATE);
assertAttributeFromBackingStore(shadowProvisioning, ATTR_DESCRIPTION_QNAME, ACCOUNT_WILL_DESCRIPTION_MANUAL);
assertShadowPassword(shadowProvisioning);
assertPendingOperationDeltas(shadowProvisioning, 3);
pendingOperation = findPendingOperation(shadowProvisioning,
OperationResultStatusType.SUCCESS, SchemaConstants.PATH_PASSWORD_VALUE);
assertPendingOperation(shadowRepo, pendingOperation,
accountWillSecondReqestTimestampStart, accountWillSecondReqestTimestampEnd,
OperationResultStatusType.SUCCESS,
accountWillSecondCompletionTimestampStart, accountWillSecondCompletionTimestampEnd);
PrismObject<ShadowType> shadowProvisioningFuture = provisioningService.getObject(ShadowType.class,
ACCOUNT_WILL_OID,
SelectorOptions.createCollection(GetOperationOptions.createPointInTimeType(PointInTimeType.FUTURE)),
task, result);
display("Provisioning shadow (future)", shadowProvisioningFuture);
assertShadowName(shadowProvisioningFuture, ACCOUNT_WILL_USERNAME);
assertEquals("Wrong kind (provisioning)", ShadowKindType.ACCOUNT, shadowProvisioningFuture.asObjectable().getKind());
assertShadowActivationAdministrativeStatus(shadowProvisioningFuture, ActivationStatusType.ENABLED);
assertAttribute(shadowProvisioningFuture, ATTR_USERNAME_QNAME, ACCOUNT_WILL_USERNAME);
assertAttribute(shadowProvisioningFuture, ATTR_FULLNAME_QNAME, ACCOUNT_WILL_FULLNAME_PIRATE);
assertAttributeFromBackingStore(shadowProvisioningFuture, ATTR_DESCRIPTION_QNAME, ACCOUNT_WILL_DESCRIPTION_MANUAL);
assertShadowPassword(shadowProvisioningFuture);
assertCase(willLastCaseOid, SchemaConstants.CASE_STATE_CLOSED);
assertCase(willSecondLastCaseOid, SchemaConstants.CASE_STATE_CLOSED);
}
/**
* ff 10min. Refresh. Oldest delta should expire.
*/
@Test
public void test270RefreshAccountWillAfter10min() throws Exception {
final String TEST_NAME = "test130RefreshAccountWillAfter10min";
displayTestTile(TEST_NAME);
// GIVEN
Task task = createTask(TEST_NAME);
OperationResult result = task.getResult();
syncServiceMock.reset();
clock.overrideDuration("PT10M");
PrismObject<ShadowType> shadowBefore = provisioningService.getObject(ShadowType.class, ACCOUNT_WILL_OID, null, task, result);
display("Shadow before", shadowBefore);
// WHEN
displayWhen(TEST_NAME);
provisioningService.refreshShadow(shadowBefore, null, task, result);
// THEN
displayThen(TEST_NAME);
assertSuccess(result);
PrismObject<ShadowType> shadowRepo = repositoryService.getObject(ShadowType.class, ACCOUNT_WILL_OID, 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, ACCOUNT_WILL_USERNAME);
assertAttributeFromCache(shadowRepo, ATTR_FULLNAME_QNAME, ACCOUNT_WILL_FULLNAME_PIRATE);
syncServiceMock.assertNoNotifyChange();
syncServiceMock.assertNoNotifcations();
PrismObject<ShadowType> shadowProvisioning = provisioningService.getObject(ShadowType.class,
ACCOUNT_WILL_OID, null, task, result);
display("Provisioning shadow", shadowProvisioning);
ShadowType shadowTypeProvisioning = shadowProvisioning.asObjectable();
assertShadowName(shadowProvisioning, ACCOUNT_WILL_USERNAME);
assertEquals("Wrong kind (provisioning)", ShadowKindType.ACCOUNT, shadowTypeProvisioning.getKind());
if (supportsBackingStore()) {
assertShadowActivationAdministrativeStatus(shadowProvisioning, ActivationStatusType.DISABLED);
} else {
assertShadowActivationAdministrativeStatus(shadowProvisioning, ActivationStatusType.ENABLED);
}
assertAttribute(shadowProvisioning, ATTR_USERNAME_QNAME, ACCOUNT_WILL_USERNAME);
assertAttribute(shadowProvisioning, ATTR_FULLNAME_QNAME, ACCOUNT_WILL_FULLNAME_PIRATE);
assertAttributeFromBackingStore(shadowProvisioning, ATTR_DESCRIPTION_QNAME, ACCOUNT_WILL_DESCRIPTION_MANUAL);
assertShadowPassword(shadowProvisioning);
assertPendingOperationDeltas(shadowProvisioning, 2);
pendingOperation = findPendingOperation(shadowProvisioning,
OperationResultStatusType.SUCCESS, SchemaConstants.PATH_PASSWORD_VALUE);
assertPendingOperation(shadowRepo, pendingOperation,
accountWillSecondReqestTimestampStart, accountWillSecondReqestTimestampEnd,
OperationResultStatusType.SUCCESS,
accountWillSecondCompletionTimestampStart, accountWillSecondCompletionTimestampEnd);
PrismObject<ShadowType> shadowProvisioningFuture = provisioningService.getObject(ShadowType.class,
ACCOUNT_WILL_OID,
SelectorOptions.createCollection(GetOperationOptions.createPointInTimeType(PointInTimeType.FUTURE)),
task, result);
display("Provisioning shadow (future)", shadowProvisioningFuture);
assertShadowName(shadowProvisioningFuture, ACCOUNT_WILL_USERNAME);
assertEquals("Wrong kind (provisioning)", ShadowKindType.ACCOUNT, shadowProvisioningFuture.asObjectable().getKind());
assertShadowActivationAdministrativeStatus(shadowProvisioningFuture, ActivationStatusType.ENABLED);
assertAttribute(shadowProvisioningFuture, ATTR_USERNAME_QNAME, ACCOUNT_WILL_USERNAME);
assertAttribute(shadowProvisioningFuture, ATTR_FULLNAME_QNAME, ACCOUNT_WILL_FULLNAME_PIRATE);
assertAttributeFromBackingStore(shadowProvisioningFuture, ATTR_DESCRIPTION_QNAME, ACCOUNT_WILL_DESCRIPTION_MANUAL);
assertShadowPassword(shadowProvisioningFuture);
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();
syncServiceMock.reset();
PrismObject<ShadowType> shadowBefore = provisioningService.getObject(ShadowType.class, ACCOUNT_WILL_OID, null, task, result);
display("Shadow before", shadowBefore);
backingStoreUpdateWill(ACCOUNT_WILL_FULLNAME_PIRATE, ActivationStatusType.ENABLED, ACCOUNT_WILL_PASSWORD_NEW);
// WHEN
displayWhen(TEST_NAME);
provisioningService.refreshShadow(shadowBefore, null, task, result);
// THEN
displayThen(TEST_NAME);
assertSuccess(result);
PrismObject<ShadowType> shadowRepo = repositoryService.getObject(ShadowType.class, ACCOUNT_WILL_OID, null, result);
display("Repo shadow", shadowRepo);
assertPendingOperationDeltas(shadowRepo, 2);
syncServiceMock.assertNoNotifyChange();
syncServiceMock.assertNoNotifcations();
PrismObject<ShadowType> shadowProvisioning = provisioningService.getObject(ShadowType.class,
ACCOUNT_WILL_OID, null, task, result);
display("Provisioning shadow", shadowProvisioning);
ShadowType shadowTypeProvisioning = shadowProvisioning.asObjectable();
assertShadowName(shadowProvisioning, ACCOUNT_WILL_USERNAME);
assertEquals("Wrong kind (provisioning)", ShadowKindType.ACCOUNT, shadowTypeProvisioning.getKind());
assertShadowActivationAdministrativeStatus(shadowProvisioning, ActivationStatusType.ENABLED);
assertAttribute(shadowProvisioning, ATTR_USERNAME_QNAME, ACCOUNT_WILL_USERNAME);
assertAttribute(shadowProvisioning, ATTR_FULLNAME_QNAME, ACCOUNT_WILL_FULLNAME_PIRATE);
assertAttributeFromBackingStore(shadowProvisioning, ATTR_DESCRIPTION_QNAME, ACCOUNT_WILL_DESCRIPTION_MANUAL);
assertShadowPassword(shadowProvisioning);
assertPendingOperationDeltas(shadowProvisioning, 2);
PrismObject<ShadowType> shadowProvisioningFuture = provisioningService.getObject(ShadowType.class,
ACCOUNT_WILL_OID,
SelectorOptions.createCollection(GetOperationOptions.createPointInTimeType(PointInTimeType.FUTURE)),
task, result);
display("Provisioning shadow (future)", shadowProvisioningFuture);
assertShadowName(shadowProvisioningFuture, ACCOUNT_WILL_USERNAME);
assertEquals("Wrong kind (provisioning)", ShadowKindType.ACCOUNT, shadowProvisioningFuture.asObjectable().getKind());
assertShadowActivationAdministrativeStatus(shadowProvisioningFuture, ActivationStatusType.ENABLED);
assertAttribute(shadowProvisioningFuture, ATTR_USERNAME_QNAME, ACCOUNT_WILL_USERNAME);
assertAttribute(shadowProvisioningFuture, ATTR_FULLNAME_QNAME, ACCOUNT_WILL_FULLNAME_PIRATE);
assertAttributeFromBackingStore(shadowProvisioningFuture, 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 test280RefreshAccountWillAfter5min() throws Exception {
final String TEST_NAME = "test132RefreshAccountWillAfter10min";
displayTestTile(TEST_NAME);
// GIVEN
Task task = createTask(TEST_NAME);
OperationResult result = task.getResult();
syncServiceMock.reset();
clock.overrideDuration("PT5M");
PrismObject<ShadowType> shadowBefore = provisioningService.getObject(ShadowType.class, ACCOUNT_WILL_OID, null, task, result);
display("Shadow before", shadowBefore);
// WHEN
displayWhen(TEST_NAME);
provisioningService.refreshShadow(shadowBefore, null, task, result);
// THEN
displayThen(TEST_NAME);
assertSuccess(result);
PrismObject<ShadowType> shadowRepo = repositoryService.getObject(ShadowType.class, ACCOUNT_WILL_OID, 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, ACCOUNT_WILL_USERNAME);
assertAttributeFromCache(shadowRepo, ATTR_FULLNAME_QNAME, ACCOUNT_WILL_FULLNAME_PIRATE);
syncServiceMock.assertNoNotifyChange();
syncServiceMock.assertNoNotifcations();
PrismObject<ShadowType> shadowProvisioning = provisioningService.getObject(ShadowType.class,
ACCOUNT_WILL_OID, null, task, result);
display("Provisioning shadow", shadowProvisioning);
ShadowType shadowTypeProvisioning = shadowProvisioning.asObjectable();
assertShadowName(shadowProvisioning, ACCOUNT_WILL_USERNAME);
assertEquals("Wrong kind (provisioning)", ShadowKindType.ACCOUNT, shadowTypeProvisioning.getKind());
assertShadowActivationAdministrativeStatus(shadowProvisioning, ActivationStatusType.ENABLED);
assertAttribute(shadowProvisioning, ATTR_USERNAME_QNAME, ACCOUNT_WILL_USERNAME);
assertAttribute(shadowProvisioning, ATTR_FULLNAME_QNAME, ACCOUNT_WILL_FULLNAME_PIRATE);
assertAttributeFromBackingStore(shadowProvisioning, ATTR_DESCRIPTION_QNAME, ACCOUNT_WILL_DESCRIPTION_MANUAL);
assertShadowPassword(shadowProvisioning);
assertPendingOperationDeltas(shadowProvisioning, 1);
pendingOperation = findPendingOperation(shadowProvisioning,
OperationResultStatusType.SUCCESS, SchemaConstants.PATH_PASSWORD_VALUE);
assertPendingOperation(shadowRepo, pendingOperation,
accountWillSecondReqestTimestampStart, accountWillSecondReqestTimestampEnd,
OperationResultStatusType.SUCCESS,
accountWillSecondCompletionTimestampStart, accountWillSecondCompletionTimestampEnd);
PrismObject<ShadowType> shadowProvisioningFuture = provisioningService.getObject(ShadowType.class,
ACCOUNT_WILL_OID,
SelectorOptions.createCollection(GetOperationOptions.createPointInTimeType(PointInTimeType.FUTURE)),
task, result);
display("Provisioning shadow (future)", shadowProvisioningFuture);
assertShadowName(shadowProvisioningFuture, ACCOUNT_WILL_USERNAME);
assertEquals("Wrong kind (provisioning)", ShadowKindType.ACCOUNT, shadowProvisioningFuture.asObjectable().getKind());
assertShadowActivationAdministrativeStatus(shadowProvisioningFuture, ActivationStatusType.ENABLED);
assertAttribute(shadowProvisioningFuture, ATTR_USERNAME_QNAME, ACCOUNT_WILL_USERNAME);
assertAttribute(shadowProvisioningFuture, ATTR_FULLNAME_QNAME, ACCOUNT_WILL_FULLNAME_PIRATE);
assertAttributeFromBackingStore(shadowProvisioningFuture, ATTR_DESCRIPTION_QNAME, ACCOUNT_WILL_DESCRIPTION_MANUAL);
assertShadowPassword(shadowProvisioningFuture);
assertCase(willLastCaseOid, SchemaConstants.CASE_STATE_CLOSED);
assertCase(willSecondLastCaseOid, SchemaConstants.CASE_STATE_CLOSED);
}
/**
* ff 5min. Refresh. All delta should expire.
*/
@Test
public void test290RefreshAccountWillAfter5min() throws Exception {
final String TEST_NAME = "test134RefreshAccountWillAfter5min";
displayTestTile(TEST_NAME);
// GIVEN
Task task = createTask(TEST_NAME);
OperationResult result = task.getResult();
syncServiceMock.reset();
clock.overrideDuration("PT5M");
PrismObject<ShadowType> shadowBefore = repositoryService.getObject(ShadowType.class, ACCOUNT_WILL_OID, null, result);
display("Shadow before", shadowBefore);
// WHEN
displayWhen(TEST_NAME);
provisioningService.refreshShadow(shadowBefore, null, task, result);
// THEN
displayThen(TEST_NAME);
assertSuccess(result);
PrismObject<ShadowType> shadowRepo = repositoryService.getObject(ShadowType.class, ACCOUNT_WILL_OID, null, result);
display("Repo shadow", shadowRepo);
assertPendingOperationDeltas(shadowRepo, 0);
assertShadowActivationAdministrativeStatusFromCache(shadowRepo, ActivationStatusType.ENABLED);
assertAttribute(shadowRepo, ATTR_USERNAME_QNAME, ACCOUNT_WILL_USERNAME);
assertAttributeFromCache(shadowRepo, ATTR_FULLNAME_QNAME, ACCOUNT_WILL_FULLNAME_PIRATE);
syncServiceMock.assertNoNotifyChange();
syncServiceMock.assertNoNotifcations();
PrismObject<ShadowType> shadowProvisioning = provisioningService.getObject(ShadowType.class,
ACCOUNT_WILL_OID, null, task, result);
display("Provisioning shadow", shadowProvisioning);
ShadowType shadowTypeProvisioning = shadowProvisioning.asObjectable();
assertShadowName(shadowProvisioning, ACCOUNT_WILL_USERNAME);
assertEquals("Wrong kind (provisioning)", ShadowKindType.ACCOUNT, shadowTypeProvisioning.getKind());
assertShadowActivationAdministrativeStatus(shadowProvisioning, ActivationStatusType.ENABLED);
assertAttribute(shadowProvisioning, ATTR_USERNAME_QNAME, ACCOUNT_WILL_USERNAME);
assertAttribute(shadowProvisioning, ATTR_FULLNAME_QNAME, ACCOUNT_WILL_FULLNAME_PIRATE);
assertAttributeFromBackingStore(shadowProvisioning, ATTR_DESCRIPTION_QNAME, ACCOUNT_WILL_DESCRIPTION_MANUAL);
assertShadowPassword(shadowProvisioning);
assertPendingOperationDeltas(shadowProvisioning, 0);
PrismObject<ShadowType> shadowProvisioningFuture = provisioningService.getObject(ShadowType.class,
ACCOUNT_WILL_OID,
SelectorOptions.createCollection(GetOperationOptions.createPointInTimeType(PointInTimeType.FUTURE)),
task, result);
display("Provisioning shadow (future)", shadowProvisioningFuture);
assertShadowName(shadowProvisioningFuture, ACCOUNT_WILL_USERNAME);
assertEquals("Wrong kind (provisioning)", ShadowKindType.ACCOUNT, shadowProvisioningFuture.asObjectable().getKind());
assertShadowActivationAdministrativeStatus(shadowProvisioningFuture, ActivationStatusType.ENABLED);
assertAttribute(shadowProvisioningFuture, ATTR_USERNAME_QNAME, ACCOUNT_WILL_USERNAME);
assertAttribute(shadowProvisioningFuture, ATTR_FULLNAME_QNAME, ACCOUNT_WILL_FULLNAME_PIRATE);
assertAttributeFromBackingStore(shadowProvisioningFuture, ATTR_DESCRIPTION_QNAME, ACCOUNT_WILL_DESCRIPTION_MANUAL);
assertShadowPassword(shadowProvisioningFuture);
assertCase(willLastCaseOid, SchemaConstants.CASE_STATE_CLOSED);
assertCase(willSecondLastCaseOid, SchemaConstants.CASE_STATE_CLOSED);
}
@Test
public void test300DeleteAccountWill() throws Exception {
final String TEST_NAME = "test300DeleteAccountWill";
displayTestTile(TEST_NAME);
// GIVEN
Task task = createTask(TEST_NAME);
OperationResult result = task.getResult();
syncServiceMock.reset();
accountWillReqestTimestampStart = clock.currentTimeXMLGregorianCalendar();
// WHEN
displayWhen(TEST_NAME);
provisioningService.deleteObject(ShadowType.class, ACCOUNT_WILL_OID, null, null, task, result);
// THEN
displayThen(TEST_NAME);
display("result", result);
willLastCaseOid = assertInProgress(result);
accountWillReqestTimestampEnd = clock.currentTimeXMLGregorianCalendar();
PrismObject<ShadowType> shadowRepo = repositoryService.getObject(ShadowType.class, ACCOUNT_WILL_OID, 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, ACCOUNT_WILL_USERNAME);
assertAttributeFromCache(shadowRepo, ATTR_FULLNAME_QNAME, ACCOUNT_WILL_FULLNAME_PIRATE);
syncServiceMock.assertNoNotifyChange();
syncServiceMock.assertNotifyInProgressOnly();
PrismObject<ShadowType> shadowProvisioning = provisioningService.getObject(ShadowType.class,
ACCOUNT_WILL_OID, null, task, result);
display("Provisioning shadow", shadowProvisioning);
ShadowType shadowTypeProvisioning = shadowProvisioning.asObjectable();
assertShadowName(shadowProvisioning, ACCOUNT_WILL_USERNAME);
assertEquals("Wrong kind (provisioning)", ShadowKindType.ACCOUNT, shadowTypeProvisioning.getKind());
assertShadowActivationAdministrativeStatus(shadowProvisioning, ActivationStatusType.ENABLED);
assertAttribute(shadowProvisioning, ATTR_USERNAME_QNAME, ACCOUNT_WILL_USERNAME);
assertAttribute(shadowProvisioning, ATTR_FULLNAME_QNAME, ACCOUNT_WILL_FULLNAME_PIRATE);
assertAttributeFromBackingStore(shadowProvisioning, ATTR_DESCRIPTION_QNAME, ACCOUNT_WILL_DESCRIPTION_MANUAL);
assertShadowPassword(shadowProvisioning);
assertPendingOperationDeltas(shadowProvisioning, 1);
pendingOperation = findPendingOperation(shadowProvisioning,
OperationResultStatusType.IN_PROGRESS, null);
assertPendingOperation(shadowProvisioning, pendingOperation, accountWillReqestTimestampStart, accountWillReqestTimestampEnd);
PrismObject<ShadowType> shadowProvisioningFuture = provisioningService.getObject(ShadowType.class,
ACCOUNT_WILL_OID,
SelectorOptions.createCollection(GetOperationOptions.createPointInTimeType(PointInTimeType.FUTURE)),
task, result);
display("Provisioning shadow (future)", shadowProvisioningFuture);
assertShadowName(shadowProvisioningFuture, ACCOUNT_WILL_USERNAME);
assertShadowDead(shadowProvisioningFuture);
assertShadowPassword(shadowProvisioningFuture);
assertNotNull("No async reference in result", willLastCaseOid);
assertCase(willLastCaseOid, SchemaConstants.CASE_STATE_OPEN);
}
@Test
public void test302GetAccountWillFuture() throws Exception {
final String TEST_NAME = "test302GetAccountWillFuture";
displayTestTile(TEST_NAME);
// GIVEN
Task task = createTask(TEST_NAME);
OperationResult result = task.getResult();
// WHEN
displayWhen(TEST_NAME);
PrismObject<ShadowType> shadowProvisioningFuture = provisioningService.getObject(ShadowType.class,
ACCOUNT_WILL_OID,
SelectorOptions.createCollection(GetOperationOptions.createPointInTimeType(PointInTimeType.FUTURE)),
task, result);
// THEN
displayThen(TEST_NAME);
assertSuccess(result);
display("Provisioning shadow (future)", shadowProvisioningFuture);
assertShadowName(shadowProvisioningFuture, ACCOUNT_WILL_USERNAME);
assertShadowDead(shadowProvisioningFuture);
assertShadowPassword(shadowProvisioningFuture);
}
@Test
public void test303GetAccountWillFutureNoFetch() throws Exception {
final String TEST_NAME = "test303GetAccountWillFutureNoFetch";
displayTestTile(TEST_NAME);
// GIVEN
Task task = createTask(TEST_NAME);
OperationResult result = task.getResult();
GetOperationOptions options = GetOperationOptions.createPointInTimeType(PointInTimeType.FUTURE);
options.setNoFetch(true);
// WHEN
displayWhen(TEST_NAME);
PrismObject<ShadowType> shadowProvisioningFuture = provisioningService.getObject(ShadowType.class,
ACCOUNT_WILL_OID,
SelectorOptions.createCollection(options),
task, result);
// THEN
displayThen(TEST_NAME);
assertSuccess(result);
display("Provisioning shadow (future,noFetch)", shadowProvisioningFuture);
assertNotNull("no OID", shadowProvisioningFuture.getOid());
assertShadowName(shadowProvisioningFuture, ACCOUNT_WILL_USERNAME);
assertShadowDead(shadowProvisioningFuture);
assertNoShadowPassword(shadowProvisioningFuture);
}
/**
* Case is closed. The operation is complete.
*/
@Test
public void test310CloseCaseAndRefreshAccountWill() throws Exception {
final String TEST_NAME = "test310CloseCaseAndRefreshAccountWill";
displayTestTile(TEST_NAME);
// GIVEN
Task task = createTask(TEST_NAME);
OperationResult result = task.getResult();
syncServiceMock.reset();
closeCase(willLastCaseOid);
PrismObject<ShadowType> shadowBefore = provisioningService.getObject(ShadowType.class, ACCOUNT_WILL_OID, null, task, result);
display("Shadow before", shadowBefore);
accountWillCompletionTimestampStart = clock.currentTimeXMLGregorianCalendar();
// WHEN
displayWhen(TEST_NAME);
provisioningService.refreshShadow(shadowBefore, null, task, result);
// THEN
displayThen(TEST_NAME);
assertSuccess(result);
accountWillCompletionTimestampEnd = clock.currentTimeXMLGregorianCalendar();
PrismObject<ShadowType> shadowRepo = repositoryService.getObject(ShadowType.class, ACCOUNT_WILL_OID, null, result);
display("Repo shadow", shadowRepo);
assertSinglePendingOperation(shadowRepo,
accountWillReqestTimestampStart, accountWillReqestTimestampEnd,
OperationResultStatusType.SUCCESS,
accountWillCompletionTimestampStart, accountWillCompletionTimestampEnd);
assertShadowDead(shadowRepo);
syncServiceMock.assertNoNotifyChange();
syncServiceMock.assertNotifySuccessOnly();
PrismObject<ShadowType> shadowProvisioning = provisioningService.getObject(ShadowType.class,
ACCOUNT_WILL_OID, null, task, result);
display("Provisioning shadow", shadowProvisioning);
ShadowType shadowTypeProvisioning = shadowProvisioning.asObjectable();
assertShadowName(shadowProvisioning, ACCOUNT_WILL_USERNAME);
assertEquals("Wrong kind (provisioning)", ShadowKindType.ACCOUNT, shadowTypeProvisioning.getKind());
assertShadowDead(shadowProvisioning);
assertShadowPassword(shadowProvisioning);
PendingOperationType pendingOperation = assertSinglePendingOperation(shadowProvisioning,
accountWillReqestTimestampStart, accountWillReqestTimestampEnd,
OperationResultStatusType.SUCCESS,
accountWillCompletionTimestampStart, accountWillCompletionTimestampEnd);
PrismObject<ShadowType> shadowProvisioningFuture = provisioningService.getObject(ShadowType.class,
ACCOUNT_WILL_OID,
SelectorOptions.createCollection(GetOperationOptions.createPointInTimeType(PointInTimeType.FUTURE)),
task, result);
display("Provisioning shadow (future)", shadowProvisioningFuture);
assertShadowName(shadowProvisioningFuture, ACCOUNT_WILL_USERNAME);
assertShadowDead(shadowProvisioningFuture);
assertShadowPassword(shadowProvisioningFuture);
assertCase(willLastCaseOid, SchemaConstants.CASE_STATE_CLOSED);
}
/**
* ff 5min, everything should be the same (grace not expired yet)
*/
@Test
public void test320RefreshAccountWillAfter5min() throws Exception {
final String TEST_NAME = "test320RefreshAccountWillAfter5min";
displayTestTile(TEST_NAME);
// GIVEN
Task task = createTask(TEST_NAME);
OperationResult result = task.getResult();
syncServiceMock.reset();
clock.overrideDuration("PT5M");
PrismObject<ShadowType> shadowBefore = provisioningService.getObject(ShadowType.class, ACCOUNT_WILL_OID, null, task, result);
display("Shadow before", shadowBefore);
// WHEN
displayWhen(TEST_NAME);
provisioningService.refreshShadow(shadowBefore, null, task, result);
// THEN
displayThen(TEST_NAME);
assertSuccess(result);
PrismObject<ShadowType> shadowRepo = repositoryService.getObject(ShadowType.class, ACCOUNT_WILL_OID, null, result);
display("Repo shadow", shadowRepo);
assertSinglePendingOperation(shadowRepo,
accountWillReqestTimestampStart, accountWillReqestTimestampEnd,
OperationResultStatusType.SUCCESS,
accountWillCompletionTimestampStart, accountWillCompletionTimestampEnd);
assertShadowDead(shadowRepo);
syncServiceMock.assertNoNotifyChange();
syncServiceMock.assertNoNotifcations();
PrismObject<ShadowType> shadowProvisioning = provisioningService.getObject(ShadowType.class,
ACCOUNT_WILL_OID, null, task, result);
display("Provisioning shadow", shadowProvisioning);
ShadowType shadowTypeProvisioning = shadowProvisioning.asObjectable();
assertShadowName(shadowProvisioning, ACCOUNT_WILL_USERNAME);
assertEquals("Wrong kind (provisioning)", ShadowKindType.ACCOUNT, shadowTypeProvisioning.getKind());
assertShadowDead(shadowProvisioning);
assertShadowPassword(shadowProvisioning);
PendingOperationType pendingOperation = assertSinglePendingOperation(shadowProvisioning,
accountWillReqestTimestampStart, accountWillReqestTimestampEnd,
OperationResultStatusType.SUCCESS,
accountWillCompletionTimestampStart, accountWillCompletionTimestampEnd);
PrismObject<ShadowType> shadowProvisioningFuture = provisioningService.getObject(ShadowType.class,
ACCOUNT_WILL_OID,
SelectorOptions.createCollection(GetOperationOptions.createPointInTimeType(PointInTimeType.FUTURE)),
task, result);
display("Provisioning shadow (future)", shadowProvisioningFuture);
assertShadowName(shadowProvisioningFuture, ACCOUNT_WILL_USERNAME);
assertShadowDead(shadowProvisioningFuture);
assertShadowPassword(shadowProvisioningFuture);
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)
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());
}
}