/*
* Copyright (c) 2010-2016 Evolveum
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.evolveum.midpoint.testing.consistency;
import static com.evolveum.midpoint.test.IntegrationTestTools.assertAttribute;
import static com.evolveum.midpoint.test.IntegrationTestTools.assertAttributeNotNull;
import static com.evolveum.midpoint.test.IntegrationTestTools.assertNoRepoCache;
import static com.evolveum.midpoint.test.IntegrationTestTools.display;
import static com.evolveum.midpoint.test.IntegrationTestTools.displayJaxb;
import static com.evolveum.midpoint.test.IntegrationTestTools.waitFor;
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 static org.testng.AssertJUnit.fail;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.namespace.QName;
import javax.xml.ws.Holder;
import com.evolveum.midpoint.common.refinery.RefinedResourceSchemaImpl;
import org.apache.commons.lang.StringUtils;
import org.opends.server.types.Entry;
import org.opends.server.util.EmbeddedUtils;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.annotation.DirtiesContext.ClassMode;
import org.springframework.test.context.ContextConfiguration;
import org.testng.AssertJUnit;
import org.testng.annotations.AfterClass;
import org.testng.annotations.Test;
import org.w3c.dom.Element;
import com.evolveum.midpoint.model.api.ModelExecuteOptions;
import com.evolveum.midpoint.model.test.AbstractModelIntegrationTest;
import com.evolveum.midpoint.prism.Containerable;
import com.evolveum.midpoint.prism.Item;
import com.evolveum.midpoint.prism.ItemDefinition;
import com.evolveum.midpoint.prism.OriginType;
import com.evolveum.midpoint.prism.PrismContainer;
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.PrismReference;
import com.evolveum.midpoint.prism.PrismReferenceValue;
import com.evolveum.midpoint.prism.crypto.EncryptionException;
import com.evolveum.midpoint.prism.delta.ChangeType;
import com.evolveum.midpoint.prism.delta.ContainerDelta;
import com.evolveum.midpoint.prism.delta.DiffUtil;
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.delta.ReferenceDelta;
import com.evolveum.midpoint.prism.path.ItemPath;
import com.evolveum.midpoint.prism.polystring.PolyString;
import com.evolveum.midpoint.prism.query.ObjectQuery;
import com.evolveum.midpoint.prism.schema.SchemaRegistry;
import com.evolveum.midpoint.prism.util.PrismAsserts;
import com.evolveum.midpoint.prism.util.PrismTestUtil;
import com.evolveum.midpoint.prism.xnode.PrimitiveXNode;
import com.evolveum.midpoint.schema.DeltaConvertor;
import com.evolveum.midpoint.schema.GetOperationOptions;
import com.evolveum.midpoint.schema.SearchResultList;
import com.evolveum.midpoint.schema.SelectorOptions;
import com.evolveum.midpoint.schema.constants.ObjectTypes;
import com.evolveum.midpoint.schema.constants.SchemaConstants;
import com.evolveum.midpoint.schema.processor.ObjectClassComplexTypeDefinition;
import com.evolveum.midpoint.schema.processor.ResourceAttribute;
import com.evolveum.midpoint.schema.processor.ResourceAttributeContainer;
import com.evolveum.midpoint.schema.processor.ResourceAttributeDefinition;
import com.evolveum.midpoint.schema.processor.ResourceSchema;
import com.evolveum.midpoint.schema.result.OperationResult;
import com.evolveum.midpoint.schema.result.OperationResultStatus;
import com.evolveum.midpoint.schema.util.MiscSchemaUtil;
import com.evolveum.midpoint.schema.util.ObjectQueryUtil;
import com.evolveum.midpoint.schema.util.ObjectTypeUtil;
import com.evolveum.midpoint.schema.util.ResourceTypeUtil;
import com.evolveum.midpoint.schema.util.SchemaTestConstants;
import com.evolveum.midpoint.schema.util.ShadowUtil;
import com.evolveum.midpoint.task.api.Task;
import com.evolveum.midpoint.task.api.TaskManagerException;
import com.evolveum.midpoint.test.Checker;
import com.evolveum.midpoint.test.ldap.OpenDJController;
import com.evolveum.midpoint.test.util.MidPointAsserts;
import com.evolveum.midpoint.test.util.TestUtil;
import com.evolveum.midpoint.util.DOMUtil;
import com.evolveum.midpoint.util.JAXBUtil;
import com.evolveum.midpoint.util.exception.CommonException;
import com.evolveum.midpoint.util.exception.CommunicationException;
import com.evolveum.midpoint.util.exception.ConfigurationException;
import com.evolveum.midpoint.util.exception.ExpressionEvaluationException;
import com.evolveum.midpoint.util.exception.ObjectAlreadyExistsException;
import com.evolveum.midpoint.util.exception.ObjectNotFoundException;
import com.evolveum.midpoint.util.exception.PolicyViolationException;
import com.evolveum.midpoint.util.exception.SchemaException;
import com.evolveum.midpoint.util.exception.SecurityViolationException;
import com.evolveum.midpoint.util.exception.SystemException;
import com.evolveum.midpoint.util.logging.Trace;
import com.evolveum.midpoint.util.logging.TraceManager;
import com.evolveum.midpoint.xml.ns._public.common.api_types_3.PropertyReferenceListType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ActivationStatusType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.AssignmentPolicyEnforcementType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.AssignmentType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.AvailabilityStatusType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ConnectorType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ConstructionType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ExpressionType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.FailedOperationTypeType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.MappingType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectFactory;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.OperationResultType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.OperationalStateType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ResourceAttributeDefinitionType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ResourceType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.SchemaHandlingType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.SynchronizationType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType;
import com.evolveum.midpoint.xml.ns._public.resource.capabilities_3.ActivationCapabilityType;
import com.evolveum.prism.xml.ns._public.types_3.ItemPathType;
import com.evolveum.prism.xml.ns._public.types_3.ObjectDeltaType;
import com.evolveum.prism.xml.ns._public.types_3.RawType;
/**
* Consistency test suite. It tests consistency mechanisms. It works as end-to-end integration test accross all subsystems.
*
* @author Katarina Valalikova
*/
@ContextConfiguration(locations = { "classpath:ctx-consistency-test-main.xml" })
@DirtiesContext(classMode = ClassMode.AFTER_CLASS)
public class ConsistencyTest extends AbstractModelIntegrationTest {
private static final String REPO_DIR_NAME = "src/test/resources/repo/";
private static final String REQUEST_DIR_NAME = "src/test/resources/request/";
private static final String SYSTEM_CONFIGURATION_FILENAME = REPO_DIR_NAME + "system-configuration.xml";
private static final String ROLE_SUPERUSER_FILENAME = REPO_DIR_NAME + "role-superuser.xml";
private static final String ROLE_SUPERUSER_OID = "00000000-0000-0000-0000-000000000004";
private static final String ROLE_LDAP_ADMINS_FILENAME = REPO_DIR_NAME + "role-admins.xml";
private static final String ROLE_LDAP_ADMINS_OID = "88888888-8888-8888-8888-000000000009";
private static final String SAMPLE_CONFIGURATION_OBJECT_FILENAME = REPO_DIR_NAME + "sample-configuration-object.xml";
private static final String SAMPLE_CONFIGURATION_OBJECT_OID = "c0c010c0-d34d-b33f-f00d-999111111111";
private static final String RESOURCE_OPENDJ_FILENAME = REPO_DIR_NAME + "resource-opendj.xml";
private static final String RESOURCE_OPENDJ_OID = "ef2bc95b-76e0-59e2-86d6-3d4f02d3ffff";
private static final String RESOURCE_OPENDJ_NS = "http://midpoint.evolveum.com/xml/ns/public/resource/instance-3";
private static final QName RESOURCE_OPENDJ_ACCOUNT_OBJECTCLASS = new QName(RESOURCE_OPENDJ_NS,"inetOrgPerson");
private static final QName RESOURCE_OPENDJ_GROUP_OBJECTCLASS = new QName(RESOURCE_OPENDJ_NS,"groupOfUniqueNames");
private static final String RESOURCE_OPENDJ_PRIMARY_IDENTIFIER_LOCAL_NAME = "entryUUID";
private static final String RESOURCE_OPENDJ_SECONDARY_IDENTIFIER_LOCAL_NAME = "dn";
private static final QName RESOURCE_OPENDJ_SECONDARY_IDENTIFIER = new QName(RESOURCE_OPENDJ_NS, RESOURCE_OPENDJ_SECONDARY_IDENTIFIER_LOCAL_NAME);
private static final String CONNECTOR_LDAP_NAMESPACE = "http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/bundle/com.evolveum.polygon.connector-ldap/com.evolveum.polygon.connector.ldap.LdapConnector";
private static final String USER_TEMPLATE_FILENAME = REPO_DIR_NAME + "user-template.xml";
private static final String USER_ADMINISTRATOR_FILENAME = REPO_DIR_NAME + "user-administrator.xml";
private static final String USER_ADMINISTRATOR_NAME = "administrator";
private static final String USER_JACK_FILENAME = REPO_DIR_NAME + "user-jack.xml";
private static final String USER_JACK_OID = "c0c010c0-d34d-b33f-f00d-111111111111";
private static final String USER_DENIELS_FILENAME = REPO_DIR_NAME + "user-deniels.xml";
private static final String USER_DENIELS_OID = "c0c010c0-d34d-b33f-f00d-222111111111";
private static final String USER_JACK2_FILENAME = REPO_DIR_NAME + "user-jack2.xml";
private static final String USER_JACK2_OID = "c0c010c0-d34d-b33f-f00d-111111114444";
private static final String USER_WILL_FILENAME = REPO_DIR_NAME + "user-will.xml";
private static final String USER_WILL_OID = "c0c010c0-d34d-b33f-f00d-111111115555";
private static final String USER_JACK_LDAP_UID = "jackie";
private static final String USER_JACK_LDAP_DN = "uid=" + USER_JACK_LDAP_UID + "," + OPENDJ_PEOPLE_SUFFIX;
private static final String USER_GUYBRUSH_FILENAME = REPO_DIR_NAME + "user-guybrush.xml";
private static final String USER_GUYBRUSH_OID = "c0c010c0-d34d-b33f-f00d-111111111222";
private static final String USER_GUYBRUSH_NOT_FOUND_FILENAME = REPO_DIR_NAME + "user-guybrush-modify-not-found.xml";
private static final String USER_GUYBRUSH_NOT_FOUND_OID = "c0c010c0-d34d-b33f-f00d-111111111333";
private static final String USER_HECTOR_NOT_FOUND_FILENAME = REPO_DIR_NAME + "user-hector.xml";
private static final String USER_HECTOR_NOT_FOUND_OID = "c0c010c0-d34d-b33f-f00d-111111222333";
private static final String USER_E_FILENAME = REPO_DIR_NAME + "user-e.xml";
private static final String USER_E_OID = "c0c010c0-d34d-b33f-f00d-111111111100";
private static final String USER_ELAINE_FILENAME = REPO_DIR_NAME + "user-elaine.xml";
private static final String USER_ELAINE_OID = "c0c010c0-d34d-b33f-f00d-111111116666";
private static final String USER_HERMAN_FILENAME = REPO_DIR_NAME + "user-herman.xml";
private static final String USER_HERMAN_OID = "c0c010c0-d34d-b33f-f00d-111111119999";
private static final String USER_MORGAN_FILENAME = REQUEST_DIR_NAME + "user-morgan.xml";
private static final String USER_MORGAN_OID = "c0c010c0-d34d-b33f-f00d-171171117777";
private static final String USER_CHUCK_FILENAME = REQUEST_DIR_NAME + "user-chuck.xml";
private static final String USER_CHUCK_OID = "c0c010c0-d34d-b33f-f00d-171171118888";
private static final String USER_ANGELIKA_FILENAME = REPO_DIR_NAME + "user-angelika.xml";
private static final String USER_ANGELIKA_OID = "c0c010c0-d34d-b33f-f00d-111111111888";
private static final String USER_ALICE_FILENAME = REPO_DIR_NAME + "user-alice.xml";
private static final String USER_ALICE_OID = "c0c010c0-d34d-b33f-f00d-111111111999";
private static final String USER_BOB_NO_GIVEN_NAME_FILENAME = REPO_DIR_NAME + "user-bob-no-given-name.xml";
private static final String USER_BOB_NO_GIVEN_NAME_OID = "c0c010c0-d34d-b33f-f00d-222111222999";
private static final String USER_JOHN_WEAK_FILENAME = REPO_DIR_NAME + "user-john.xml";
private static final String USER_JOHN_WEAK_OID = "c0c010c0-d34d-b33f-f00d-999111111888";
private static final String USER_DONALD_FILENAME = REPO_DIR_NAME + "user-donald.xml";
private static final String USER_DONALD_OID = "c0c010c0-d34d-b33f-f00d-999111111777";
private static final String USER_DISCOVERY_FILENAME = REPO_DIR_NAME + "user-discovery.xml";
private static final String USER_DISCOVERY_OID = "c0c010c0-d34d-b33f-f00d-111112226666";
private static final String USER_ABOMBA_FILENAME = REPO_DIR_NAME + "user-abomba.xml";
private static final String USER_ABOMBA_OID = "c0c010c0-d34d-b33f-f00d-016016111111";
private static final String USER_ABOM_FILENAME = REPO_DIR_NAME + "user-abom.xml";
private static final String USER_ABOM_OID = "c0c010c0-d34d-b33f-f00d-111111016016";
private static final File ACCOUNT_GUYBRUSH_FILE = new File(REPO_DIR_NAME, "account-guybrush.xml");
private static final String ACCOUNT_GUYBRUSH_OID = "a0c010c0-d34d-b33f-f00d-111111111222";
private static final File ACCOUNT_HECTOR_FILE = new File(REPO_DIR_NAME, "account-hector-not-found.xml");
private static final String ACCOUNT_HECTOR_OID = "a0c010c0-d34d-b33f-f00d-111111222333";
private static final File ACCOUNT_GUYBRUSH_MODIFY_DELETE_FILE = new File(REPO_DIR_NAME, "account-guybrush-not-found.xml");
private static final String ACCOUNT_GUYBRUSH_MODIFY_DELETE_OID = "a0c010c0-d34d-b33f-f00d-111111111333";
private static final String ACCOUNT_DENIELS_FILENAME = REPO_DIR_NAME + "account-deniels.xml";
private static final String ACCOUNT_DENIELS_OID = "a0c010c0-d34d-b33f-f00d-111111111555";
private static final String ACCOUNT_CHUCK_FILENAME = REPO_DIR_NAME + "account-chuck.xml";
private static final String ACCOUNT_HERMAN_FILENAME = REPO_DIR_NAME + "account-herman.xml";
private static final String ACCOUNT_HERMAN_OID = "22220000-2200-0000-0000-333300003333";
private static final String REQUEST_USER_MODIFY_ASSIGN_ACCOUNT = "src/test/resources/request/user-modify-assign-account.xml";
private static final String REQUEST_USER_MODIFY_ADD_ACCOUNT_DIRECTLY = "src/test/resources/request/user-modify-add-account-directly.xml";
private static final String REQUEST_USER_MODIFY_DELETE_ACCOUNT = "src/test/resources/request/user-modify-delete-account.xml";
private static final String REQUEST_USER_MODIFY_DELETE_ACCOUNT_COMMUNICATION_PROBLEM = "src/test/resources/request/user-modify-delete-account-communication-problem.xml";
private static final String REQUEST_USER_MODIFY_ASSIGN_ROLE_ADMINS = "src/test/resources/request/user-modify-assign-role-admin.xml";
private static final String REQUEST_ACCOUNT_MODIFY_NOT_FOUND_DELETE_ACCOUNT = "src/test/resources/request/account-guybrush-modify-attributes.xml";
private static final String REQUEST_ACCOUNT_MODIFY_COMMUNICATION_PROBLEM = "src/test/resources/request/account-modify-attrs-communication-problem.xml";
private static final String REQUEST_ADD_ACCOUNT_JACKIE = "src/test/resources/request/add-account-jack.xml";
private static final String REQUEST_USER_MODIFY_WEAK_MAPPING_COMMUNICATION_PROBLEM = "src/test/resources/request/user-modify-employeeType.xml";
private static final String REQUEST_USER_MODIFY_WEAK_STRONG_MAPPING_COMMUNICATION_PROBLEM = "src/test/resources/request/user-modify-employeeType-givenName.xml";
private static final String REQUEST_RESOURCE_MODIFY_RESOURCE_SCHEMA = "src/test/resources/request/resource-modify-resource-schema.xml";
private static final String REQUEST_RESOURCE_MODIFY_SYNCHRONIZATION = "src/test/resources/request/resource-modify-synchronization.xml";
private static final String REQUEST_USER_MODIFY_CHANGE_PASSWORD_1 = "src/test/resources/request/user-modify-change-password-1.xml";
private static final String REQUEST_USER_MODIFY_CHANGE_PASSWORD_2 = "src/test/resources/request/user-modify-change-password-2.xml";
private static final String TASK_OPENDJ_RECONCILIATION_FILENAME = "src/test/resources/repo/task-opendj-reconciliation.xml";
private static final String TASK_OPENDJ_RECONCILIATION_OID = "91919191-76e0-59e2-86d6-3d4f02d30000";
private static final String LDIF_WILL_FILENAME = "src/test/resources/request/will.ldif";
private static final String LDIF_ELAINE_FILENAME = "src/test/resources/request/elaine.ldif";
private static final String LDIF_MORGAN_FILENAME = "src/test/resources/request/morgan.ldif";
private static final String LDIF_DISCOVERY_FILENAME = "src/test/resources/request/discovery.ldif";
private static final String LDIF_CREATE_USERS_OU_FILENAME = "src/test/resources/request/usersOu.ldif";
private static final String LDIF_CREATE_ADMINS_GROUP_FILENAME = "src/test/resources/request/adminsGroup.ldif";
private static final String LDIF_MODIFY_RENAME_FILENAME = "src/test/resources/request/modify-rename.ldif";
private static final Trace LOGGER = TraceManager.getTrace(ConsistencyTest.class);
private static final String NS_MY = "http://whatever.com/my";
private static final QName MY_SHIP_STATE = new QName(NS_MY, "shipState");
private static ResourceType resourceTypeOpenDjrepo;
private static String accountShadowOidOpendj;
private String aliceAccountDn;
// This will get called from the superclass to init the repository
// It will be called only once
public void initSystem(Task initTask, OperationResult initResult) throws Exception {
LOGGER.trace("initSystem");
super.initSystem(initTask, initResult);
repoAddObjectFromFile(ROLE_SUPERUSER_FILENAME, initResult);
repoAddObjectFromFile(ROLE_LDAP_ADMINS_FILENAME, initResult);
repoAddObjectFromFile(USER_ADMINISTRATOR_FILENAME, initResult);
// This should discover the connectors
LOGGER.trace("initSystem: trying modelService.postInit()");
modelService.postInit(initResult);
LOGGER.trace("initSystem: modelService.postInit() done");
login(USER_ADMINISTRATOR_NAME);
// We need to add config after calling postInit() so it will not be applied.
// we want original logging configuration from the test logback config file, not
// the one from the system config.
repoAddObjectFromFile(SYSTEM_CONFIGURATION_FILENAME, initResult);
// Need to import instead of add, so the (dynamic) connector reference
// will be resolved correctly
importObjectFromFile(RESOURCE_OPENDJ_FILENAME, initResult);
repoAddObjectFromFile(SAMPLE_CONFIGURATION_OBJECT_FILENAME, initResult);
repoAddObjectFromFile(USER_TEMPLATE_FILENAME, initResult);
assumeAssignmentPolicy(AssignmentPolicyEnforcementType.POSITIVE);
// DebugUtil.setDetailedDebugDump(true);
}
/**
* Initialize embedded OpenDJ instance Note: this is not in the abstract
* superclass so individual tests may avoid starting OpenDJ.
*/
@Override
public void startResources() throws Exception {
openDJController.startCleanServer();
}
/**
* Shutdown embedded OpenDJ instance Note: this is not in the abstract
* superclass so individual tests may avoid starting OpenDJ.
*/
@AfterClass
public static void stopResources() throws Exception {
openDJController.stop();
}
/**
* Test integrity of the test setup.
*/
@Test
public void test000Integrity() throws Exception {
final String TEST_NAME = "test000Integrity";
TestUtil.displayTestTile(this, TEST_NAME);
assertNotNull(modelWeb);
assertNotNull(modelService);
assertNotNull(repositoryService);
assertTrue(isSystemInitialized());
assertNotNull(taskManager);
assertNotNull(prismContext);
SchemaRegistry schemaRegistry = prismContext.getSchemaRegistry();
assertNotNull(schemaRegistry);
// This is defined in extra schema. So this effectively checks whether
// the extra schema was loaded
PrismPropertyDefinition shipStateDefinition = schemaRegistry
.findPropertyDefinitionByElementName(MY_SHIP_STATE);
assertNotNull("No my:shipState definition", shipStateDefinition);
assertEquals("Wrong maxOccurs in my:shipState definition", 1, shipStateDefinition.getMaxOccurs());
assertNoRepoCache();
OperationResult result = new OperationResult(ConsistencyTest.class.getName() + "." + TEST_NAME);
// Check if OpenDJ resource was imported correctly
PrismObject<ResourceType> openDjResource = repositoryService.getObject(ResourceType.class,
RESOURCE_OPENDJ_OID, null, result);
display("Imported OpenDJ resource (repository)", openDjResource);
AssertJUnit.assertEquals(RESOURCE_OPENDJ_OID, openDjResource.getOid());
assertNoRepoCache();
String ldapConnectorOid = openDjResource.asObjectable().getConnectorRef().getOid();
PrismObject<ConnectorType> ldapConnector = repositoryService.getObject(ConnectorType.class,
ldapConnectorOid, null, result);
display("LDAP Connector: ", ldapConnector);
}
/**
* Test the testResource method. Expect a complete success for now.
*/
@Test
public void test001TestConnectionOpenDJ() throws Exception {
final String TEST_NAME = "test001TestConnectionOpenDJ";
TestUtil.displayTestTile(TEST_NAME);
Task task = taskManager.createTaskInstance();
// GIVEN
assertNoRepoCache();
// WHEN
OperationResultType result = modelWeb.testResource(RESOURCE_OPENDJ_OID);
// THEN
assertNoRepoCache();
displayJaxb("testResource result:", result, SchemaConstants.C_RESULT);
TestUtil.assertSuccess("testResource has failed", result);
OperationResult opResult = new OperationResult(ConsistencyTest.class.getName()
+ "." + TEST_NAME);
PrismObject<ResourceType> resourceOpenDjRepo = repositoryService.getObject(ResourceType.class,
RESOURCE_OPENDJ_OID, null, opResult);
resourceTypeOpenDjrepo = resourceOpenDjRepo.asObjectable();
assertNoRepoCache();
assertEquals(RESOURCE_OPENDJ_OID, resourceTypeOpenDjrepo.getOid());
display("Initialized OpenDJ resource (respository)", resourceTypeOpenDjrepo);
assertNotNull("Resource schema was not generated", resourceTypeOpenDjrepo.getSchema());
Element resourceOpenDjXsdSchemaElement = ResourceTypeUtil
.getResourceXsdSchema(resourceTypeOpenDjrepo);
assertNotNull("Resource schema was not generated", resourceOpenDjXsdSchemaElement);
PrismObject<ResourceType> openDjResourceProvisioninig = provisioningService.getObject(
ResourceType.class, RESOURCE_OPENDJ_OID, null, task, opResult);
display("Initialized OpenDJ resource resource (provisioning)", openDjResourceProvisioninig);
PrismObject<ResourceType> openDjResourceModel = provisioningService.getObject(ResourceType.class,
RESOURCE_OPENDJ_OID, null, task, opResult);
display("Initialized OpenDJ resource OpenDJ resource (model)", openDjResourceModel);
checkOpenDjResource(resourceTypeOpenDjrepo, "repository");
System.out.println("------------------------------------------------------------------");
display("OpenDJ resource schema (repo XML)",
DOMUtil.serializeDOMToString(ResourceTypeUtil.getResourceXsdSchema(resourceOpenDjRepo)));
System.out.println("------------------------------------------------------------------");
checkOpenDjResource(openDjResourceProvisioninig.asObjectable(), "provisioning");
checkOpenDjResource(openDjResourceModel.asObjectable(), "model");
// TODO: model web
}
/**
* Attempt to add new user. It is only added to the repository, so check if
* it is in the repository after the operation.
*/
@Test
public void test100AddUser() throws Exception {
final String TEST_NAME = "test100AddUser";
UserType userType = testAddUserToRepo(TEST_NAME, USER_JACK_FILENAME, USER_JACK_OID);
OperationResult repoResult = new OperationResult("getObject");
PropertyReferenceListType resolve = new PropertyReferenceListType();
PrismObject<UserType> uObject = repositoryService
.getObject(UserType.class, USER_JACK_OID, null, repoResult);
UserType repoUser = uObject.asObjectable();
repoResult.computeStatus();
display("repository.getObject result", repoResult);
TestUtil.assertSuccess("getObject has failed", repoResult);
AssertJUnit.assertEquals(USER_JACK_OID, repoUser.getOid());
PrismAsserts.assertEqualsPolyString("User full name not equals as expected.", userType.getFullName(),
repoUser.getFullName());
// TODO: better checks
}
/**
* Add account to user. This should result in account provisioning. Check if
* that happens in repo and in LDAP.
*/
@Test
public void test110PrepareOpenDjWithAccounts() throws Exception {
final String TEST_NAME = "test110PrepareOpenDjWithAccounts";
TestUtil.displayTestTile(TEST_NAME);
OperationResult parentResult = new OperationResult(TEST_NAME);
ShadowType jackeAccount = unmarshallValueFromFile(REQUEST_ADD_ACCOUNT_JACKIE,
ShadowType.class);
Task task = taskManager.createTaskInstance();
String oid = provisioningService.addObject(jackeAccount.asPrismObject(), null, null, task, parentResult);
PrismObject<ShadowType> jackFromRepo = repositoryService.getObject(ShadowType.class,
oid, null, parentResult);
LOGGER.debug("account jack after provisioning: {}", jackFromRepo.debugDump());
PrismObject<UserType> jackUser = repositoryService.getObject(UserType.class, USER_JACK_OID,
null, parentResult);
ObjectReferenceType ort = new ObjectReferenceType();
ort.setOid(oid);
ort.setType(ShadowType.COMPLEX_TYPE);
jackUser.asObjectable().getLinkRef().add(ort);
PrismObject<UserType> jackUserRepo = repositoryService.getObject(UserType.class, USER_JACK_OID,
null, parentResult);
ObjectDelta delta = DiffUtil.diff(jackUserRepo, jackUser);
repositoryService.modifyObject(UserType.class, USER_JACK_OID, delta.getModifications(), parentResult);
// GIVEN
OperationResult repoResult = new OperationResult("getObject");
// Check if user object was modified in the repo
accountShadowOidOpendj = assertUserOneAccountRef(USER_JACK_OID);
assertFalse(accountShadowOidOpendj.isEmpty());
// Check if shadow was created in the repo
repoResult = new OperationResult("getObject");
PrismObject<ShadowType> repoShadow = repositoryService.getObject(ShadowType.class,
accountShadowOidOpendj, null, repoResult);
ShadowType repoShadowType = repoShadow.asObjectable();
repoResult.computeStatus();
TestUtil.assertSuccess("getObject has failed", repoResult);
display("Shadow (repository)", repoShadow);
assertNotNull(repoShadowType);
assertEquals(RESOURCE_OPENDJ_OID, repoShadowType.getResourceRef().getOid());
assertNotNull("Shadow stored in repository has no name", repoShadowType.getName());
// Check the "name" property, it should be set to DN, not entryUUID
assertEquals("Wrong name property", USER_JACK_LDAP_DN.toLowerCase(), repoShadowType.getName()
.getOrig().toLowerCase());
// check attributes in the shadow: should be only identifiers (ICF UID)
String uid = checkRepoShadow(repoShadow);
// check if account was created in LDAP
Entry entry = openDJController.searchAndAssertByEntryUuid(uid);
display("LDAP account", entry);
OpenDJController.assertAttribute(entry, "uid", "jackie");
OpenDJController.assertAttribute(entry, "givenName", "Jack");
OpenDJController.assertAttribute(entry, "sn", "Sparrow");
OpenDJController.assertAttribute(entry, "cn", "Jack Sparrow");
assertNoRepoCache();
Holder<OperationResultType> resultHolder = new Holder<OperationResultType>();
Holder<ObjectType> objectHolder = new Holder<ObjectType>();
// WHEN
PropertyReferenceListType resolve = new PropertyReferenceListType();
// List<ObjectOperationOptions> options = new ArrayList<ObjectOperationOptions>();
modelWeb.getObject(ObjectTypes.SHADOW.getTypeQName(), accountShadowOidOpendj, null,
objectHolder, resultHolder);
// THEN
assertNoRepoCache();
displayJaxb("getObject result", resultHolder.value, SchemaConstants.C_RESULT);
TestUtil.assertSuccess("getObject has failed", resultHolder.value);
ShadowType modelShadow = (ShadowType) objectHolder.value;
display("Shadow (model)", modelShadow);
AssertJUnit.assertNotNull(modelShadow);
AssertJUnit.assertEquals(RESOURCE_OPENDJ_OID, modelShadow.getResourceRef().getOid());
assertAttributeNotNull(modelShadow, getOpenDjPrimaryIdentifierQName());
assertAttributes(modelShadow, "jackie", "Jack", "Sparrow", "Jack Sparrow");
// "middle of nowhere");
assertNull("carLicense attribute sneaked to LDAP",
OpenDJController.getAttributeValue(entry, "carLicense"));
assertNotNull("Activation is null", modelShadow.getActivation());
assertNotNull("No 'enabled' in the shadow", modelShadow.getActivation().getAdministrativeStatus());
assertEquals("The account is not enabled in the shadow", ActivationStatusType.ENABLED, modelShadow.getActivation().getAdministrativeStatus());
TestUtil.displayTestTile("test013prepareOpenDjWithAccounts - add second account");
OperationResult secondResult = new OperationResult(
"test013prepareOpenDjWithAccounts - add second account");
ShadowType shadow = unmarshallValueFromFile(ACCOUNT_DENIELS_FILENAME, ShadowType.class);
provisioningService.addObject(shadow.asPrismObject(), null, null, task, secondResult);
repoAddObjectFromFile(USER_DENIELS_FILENAME, secondResult);
}
@Test
public void test120AddAccountAlreadyExistLinked() throws Exception {
final String TEST_NAME = "test120AddAccountAlreadyExistLinked";
TestUtil.displayTestTile(TEST_NAME);
Task task = taskManager.createTaskInstance();
// GIVEN
OperationResult parentResult = new OperationResult("Add account already exist linked");
testAddUserToRepo("test014testAssAccountAlreadyExistLinked", USER_JACK2_FILENAME, USER_JACK2_OID);
assertUserNoAccountRef(USER_JACK2_OID, parentResult);
// //check if the jackie account already exists on the resource
String accountRef = assertUserOneAccountRef(USER_JACK_OID);
PrismObject<ShadowType> jackUserAccount = repositoryService.getObject(ShadowType.class, accountRef, null, parentResult);
display("Jack's account: ", jackUserAccount.debugDump());
// WHEN REQUEST_USER_MODIFY_ADD_ACCOUNT_ALERADY_EXISTS_LINKED_OPENDJ_FILENAME
requestToExecuteChanges(REQUEST_USER_MODIFY_ASSIGN_ACCOUNT, USER_JACK2_OID, UserType.class, task, null, parentResult);
// THEN
//expected thet the dn and ri:uid will be jackie1 because jackie already exists and is liked to another user..
String accountOid = checkUser(USER_JACK2_OID, task, parentResult);
checkAccount(accountOid, "jackie1", "Jack", "Russel", "Jack Russel", task, parentResult);
}
@Test
public void test122AddAccountAlreadyExistUnlinked() throws Exception {
final String TEST_NAME = "test122AddAccountAlreadyExistUnlinked";
TestUtil.displayTestTile(TEST_NAME);
// GIVEN
OperationResult parentResult = new OperationResult("Add account already exist unlinked.");
Entry entry = openDJController.addEntryFromLdifFile(LDIF_WILL_FILENAME);
Entry searchResult = openDJController.searchByUid("wturner");
OpenDJController.assertAttribute(searchResult, "l", "Caribbean");
OpenDJController.assertAttribute(searchResult, "givenName", "Will");
OpenDJController.assertAttribute(searchResult, "sn", "Turner");
OpenDJController.assertAttribute(searchResult, "cn", "Will Turner");
OpenDJController.assertAttribute(searchResult, "mail", "will.turner@blackpearl.com");
OpenDJController.assertAttribute(searchResult, "telephonenumber", "+1 408 555 1234");
OpenDJController.assertAttribute(searchResult, "facsimiletelephonenumber", "+1 408 555 4321");
String dn = searchResult.getDN().toString();
assertEquals("DN attribute " + dn + " not equals", dn, "uid=wturner,ou=People,dc=example,dc=com");
testAddUserToRepo("add user - test015 account already exist unlinked", USER_WILL_FILENAME,
USER_WILL_OID);
assertUserNoAccountRef(USER_WILL_OID, parentResult);
Task task = taskManager.createTaskInstance();
//WHEN
TestUtil.displayWhen(TEST_NAME);
requestToExecuteChanges(REQUEST_USER_MODIFY_ASSIGN_ACCOUNT, USER_WILL_OID, UserType.class, task, null, parentResult);
// THEN
TestUtil.displayThen(TEST_NAME);
String accountOid = checkUser(USER_WILL_OID, task, parentResult);
// MidPointAsserts.assertAssignments(user, 1);
PrismObject<ShadowType> account = provisioningService.getObject(ShadowType.class,
accountOid, null, task, parentResult);
ResourceAttributeContainer attributes = ShadowUtil.getAttributesContainer(account);
assertEquals("shadow secondary identifier not equal with the account dn. ", dn, attributes
.findAttribute(getOpenDjSecondaryIdentifierQName()).getRealValue(String.class));
String identifier = attributes.getPrimaryIdentifier().getRealValue(String.class);
openDJController.searchAndAssertByEntryUuid(identifier);
}
//MID-1595, MID-1577
@Test
public void test124AddAccountDirectAlreadyExists() throws Exception {
final String TEST_NAME = "test124AddAccountDirectAlreadyExists";
TestUtil.displayTestTile(TEST_NAME);
OperationResult parentResult = new OperationResult(TEST_NAME);
Task task = taskManager.createTaskInstance();
SchemaHandlingType oldSchemaHandling = resourceTypeOpenDjrepo
.getSchemaHandling();
SynchronizationType oldSynchronization = resourceTypeOpenDjrepo
.getSynchronization();
try {
// we will reapply this schema handling after this test finish
ItemDefinition syncDef = resourceTypeOpenDjrepo.asPrismObject().getDefinition().findItemDefinition(ResourceType.F_SYNCHRONIZATION);
assertNotNull("null definition for sync delta", syncDef);
ObjectDeltaType omt = unmarshallValueFromFile(REQUEST_RESOURCE_MODIFY_SYNCHRONIZATION, ObjectDeltaType.class);
ObjectDelta objectDelta = DeltaConvertor.createObjectDelta(omt, prismContext);
repositoryService.modifyObject(ResourceType.class, RESOURCE_OPENDJ_OID, objectDelta.getModifications(), parentResult);
requestToExecuteChanges(REQUEST_RESOURCE_MODIFY_RESOURCE_SCHEMA,
RESOURCE_OPENDJ_OID, ResourceType.class, task, null,
parentResult);
PrismObject<ResourceType> res = repositoryService
.getObject(ResourceType.class, RESOURCE_OPENDJ_OID, null,
parentResult);
// LOGGER.trace("resource schema handling after modify: {}",
// prismContext.silentMarshalObject(res.asObjectable(), LOGGER));
repoAddObjectFromFile(USER_ABOMBA_FILENAME,
parentResult);
requestToExecuteChanges(REQUEST_USER_MODIFY_ADD_ACCOUNT_DIRECTLY,
USER_ABOMBA_OID, UserType.class, task, null, parentResult);
String abombaOid = assertUserOneAccountRef(USER_ABOMBA_OID);
ShadowType abombaShadow = repositoryService.getObject(
ShadowType.class, abombaOid, null, parentResult)
.asObjectable();
assertShadowName(abombaShadow,
"uid=abomba,OU=people,DC=example,DC=com");
repoAddObjectFromFile(USER_ABOM_FILENAME,
parentResult);
requestToExecuteChanges(REQUEST_USER_MODIFY_ADD_ACCOUNT_DIRECTLY,
USER_ABOM_OID, UserType.class, task, null, parentResult);
String abomOid = assertUserOneAccountRef(USER_ABOM_OID);
ShadowType abomShadow = repositoryService.getObject(
ShadowType.class, abomOid, null, parentResult)
.asObjectable();
assertShadowName(abomShadow,
"uid=abomba1,OU=people,DC=example,DC=com");
ReferenceDelta abombaDeleteAccDelta = ReferenceDelta
.createModificationDelete(ShadowType.class,
UserType.F_LINK_REF, prismContext,
new PrismReferenceValue(abombaOid));
ObjectDelta d = ObjectDelta.createModifyDelta(USER_ABOMBA_OID,
abombaDeleteAccDelta, UserType.class, prismContext);
modelService.executeChanges(MiscSchemaUtil.createCollection(d), null, task,
parentResult);
assertUserNoAccountRef(USER_ABOMBA_OID, parentResult);
repositoryService.getObject(ShadowType.class, abombaOid, null,
parentResult);
ReferenceDelta abomDeleteAccDelta = ReferenceDelta
.createModificationDelete(ShadowType.class,
UserType.F_LINK_REF, prismContext,
abomShadow.asPrismObject());
ObjectDelta d2 = ObjectDelta.createModifyDelta(USER_ABOM_OID,
abomDeleteAccDelta, UserType.class, prismContext);
modelService.executeChanges(MiscSchemaUtil.createCollection(d2), null, task,
parentResult);
assertUserNoAccountRef(USER_ABOM_OID, parentResult);
try {
repositoryService.getObject(ShadowType.class, abomOid, null,
parentResult);
fail("Expected that shadow abom does not exist, but it is");
} catch (ObjectNotFoundException ex) {
// this is expected
} catch (Exception ex) {
fail("Expected object not found exception but got " + ex);
}
LOGGER.info("starting second execution request for user abomba");
OperationResult result = new OperationResult("Add account already exist result.");
requestToExecuteChanges(REQUEST_USER_MODIFY_ADD_ACCOUNT_DIRECTLY,
USER_ABOMBA_OID, UserType.class, task, null, result);
String abombaOid2 = assertUserOneAccountRef(USER_ABOMBA_OID);
ShadowType abombaShadow2 = repositoryService.getObject(
ShadowType.class, abombaOid2, null, result)
.asObjectable();
assertShadowName(abombaShadow2,
"uid=abomba,OU=people,DC=example,DC=com");
result.computeStatus();
LOGGER.info("Displaying execute changes result");
display(result);
// return the previous changes of resource back
Collection<? extends ItemDelta> schemaHandlingDelta = ContainerDelta
.createModificationReplaceContainerCollection(
ResourceType.F_SCHEMA_HANDLING,
resourceTypeOpenDjrepo.asPrismObject()
.getDefinition(), oldSchemaHandling.asPrismContainerValue().clone());
PropertyDelta syncDelta = PropertyDelta
.createModificationReplaceProperty(
ResourceType.F_SYNCHRONIZATION,
resourceTypeOpenDjrepo.asPrismObject()
.getDefinition(), oldSynchronization);
((Collection) schemaHandlingDelta).add(syncDelta);
repositoryService.modifyObject(ResourceType.class,
RESOURCE_OPENDJ_OID, schemaHandlingDelta, parentResult);
} catch (Exception ex) {
LOGGER.info("error: " + ex.getMessage(), ex);
throw ex;
}
}
@Test
public void test130DeleteObjectNotFound() throws Exception {
final String TEST_NAME = "test130DeleteObjectNotFound";
TestUtil.displayTestTile(TEST_NAME);
OperationResult parentResult = new OperationResult(TEST_NAME);
repoAddShadowFromFile(ACCOUNT_GUYBRUSH_FILE, parentResult);
repoAddObjectFromFile(USER_GUYBRUSH_FILENAME, parentResult);
Task task = taskManager.createTaskInstance();
requestToExecuteChanges(REQUEST_USER_MODIFY_DELETE_ACCOUNT, USER_GUYBRUSH_OID, UserType.class, task, null, parentResult);
// WHEN
ObjectDelta deleteDelta = ObjectDelta.createDeleteDelta(ShadowType.class, ACCOUNT_GUYBRUSH_OID, prismContext);
Collection<ObjectDelta<? extends ObjectType>> deltas = MiscSchemaUtil.createCollection(deleteDelta);
modelService.executeChanges(deltas, null, task, parentResult);
try {
repositoryService.getObject(ShadowType.class, ACCOUNT_GUYBRUSH_OID, null, parentResult);
} catch (Exception ex) {
if (!(ex instanceof ObjectNotFoundException)) {
fail("Expected ObjectNotFoundException but got " + ex);
}
}
assertUserNoAccountRef(USER_GUYBRUSH_OID, parentResult);
repositoryService.deleteObject(UserType.class, USER_GUYBRUSH_OID, parentResult);
}
/**
* Modify account not found => reaction: Delete account
*/
@SuppressWarnings("unchecked")
@Test
public void test140ModifyObjectNotFound() throws Exception {
final String TEST_NAME = "test140ModifyObjectNotFound";
TestUtil.displayTestTile(TEST_NAME);
OperationResult result = new OperationResult(TEST_NAME);
repoAddShadowFromFile(ACCOUNT_GUYBRUSH_FILE, result);
repoAddObjectFromFile(USER_GUYBRUSH_FILENAME, result);
assertUserOneAccountRef(USER_GUYBRUSH_OID);
Task task = taskManager.createTaskInstance();
// WHEN
requestToExecuteChanges(REQUEST_ACCOUNT_MODIFY_NOT_FOUND_DELETE_ACCOUNT, ACCOUNT_GUYBRUSH_OID, ShadowType.class, task, null, result);
// THEN
try {
repositoryService.getObject(ShadowType.class, ACCOUNT_GUYBRUSH_OID, null, result);
fail("Expected ObjectNotFound but did not get one.");
} catch (Exception ex) {
if (!(ex instanceof ObjectNotFoundException)) {
fail("Expected ObjectNotFoundException but got " + ex);
}
}
assertUserNoAccountRef(USER_GUYBRUSH_OID, result);
repositoryService.deleteObject(UserType.class, USER_GUYBRUSH_OID, result);
}
/**
* Modify account not found => reaction: Re-create account, apply changes.
*/
@Test
public void test142ModifyObjectNotFoundAssignedAccount() throws Exception {
final String TEST_NAME = "test142ModifyObjectNotFoundAssignedAccount";
TestUtil.displayTestTile(TEST_NAME);
// GIVEN
OperationResult parentResult = new OperationResult(TEST_NAME);
repoAddShadowFromFile(ACCOUNT_GUYBRUSH_MODIFY_DELETE_FILE, parentResult);
repoAddObjectFromFile(USER_GUYBRUSH_NOT_FOUND_FILENAME, parentResult);
assertUserOneAccountRef(USER_GUYBRUSH_NOT_FOUND_OID);
Task task = taskManager.createTaskInstance();
//WHEN
TestUtil.displayWhen(TEST_NAME);
requestToExecuteChanges(REQUEST_ACCOUNT_MODIFY_NOT_FOUND_DELETE_ACCOUNT, ACCOUNT_GUYBRUSH_MODIFY_DELETE_OID, ShadowType.class, task, null, parentResult);
// THEN
TestUtil.displayThen(TEST_NAME);
String accountOid = assertUserOneAccountRef(USER_GUYBRUSH_NOT_FOUND_OID);
PrismObject<ShadowType> modifiedAccount = provisioningService.getObject(
ShadowType.class, accountOid, null, task, parentResult);
assertNotNull(modifiedAccount);
display("Modified shadow", modifiedAccount);
assertShadowName(modifiedAccount.asObjectable(), "uid=guybrush123,ou=people,dc=example,dc=com");
// PrismAsserts.assertEqualsPolyString("Wrong shadow name", "uid=guybrush123,ou=people,dc=example,dc=com", modifiedAccount.asObjectable().getName());
ResourceAttributeContainer attributeContainer = ShadowUtil
.getAttributesContainer(modifiedAccount);
assertAttribute(modifiedAccount.asObjectable(),
new QName(ResourceTypeUtil.getResourceNamespace(resourceTypeOpenDjrepo), "roomNumber"),
"cabin");
assertNotNull(attributeContainer.findProperty(new QName(ResourceTypeUtil
.getResourceNamespace(resourceTypeOpenDjrepo), "businessCategory")));
}
/**
* Get account not found => reaction: Re-create account, return re-created.
*/
@Test
public void test144GetObjectNotFoundAssignedAccount() throws Exception {
final String TEST_NAME = "test144GetObjectNotFoundAssignedAccount";
TestUtil.displayTestTile(TEST_NAME);
// GIVEN
OperationResult parentResult = new OperationResult(TEST_NAME);
repoAddShadowFromFile(ACCOUNT_HECTOR_FILE, parentResult);
repoAddObjectFromFile(USER_HECTOR_NOT_FOUND_FILENAME, parentResult);
assertUserOneAccountRef(USER_HECTOR_NOT_FOUND_OID);
Task task = taskManager.createTaskInstance();
//WHEN
PrismObject<UserType> modificatedUser = modelService.getObject(UserType.class, USER_HECTOR_NOT_FOUND_OID, null, task, parentResult);
// THEN
String accountOid = assertOneAccountRef(modificatedUser);
PrismObject<ShadowType> modifiedAccount = modelService.getObject(ShadowType.class, accountOid, null, task, parentResult);
assertNotNull(modifiedAccount);
assertShadowName(modifiedAccount.asObjectable(), "uid=hector,ou=people,dc=example,dc=com");
}
/**
* Recompute user => account not found => reaction: Re-create account
* MID-3093
*/
@Test
public void test150RecomputeUserAccountNotFound() throws Exception {
final String TEST_NAME = "test150RecomputeUserAccountNotFound";
TestUtil.displayTestTile(TEST_NAME);
// GIVEN
Task task = taskManager.createTaskInstance(TEST_NAME);
OperationResult result = task.getResult();
PrismObject<UserType> userGuybrushFromFile = PrismTestUtil.parseObject(new File(USER_GUYBRUSH_FILENAME));
userGuybrushFromFile.asObjectable().getLinkRef().clear();
repoAddObject(userGuybrushFromFile, result);
assignAccount(USER_GUYBRUSH_OID, RESOURCE_OPENDJ_OID, null);
PrismObject<UserType> userBefore = getUser(USER_GUYBRUSH_OID);
display("User before", userBefore);
String accountShadowOid = assertOneAccountRef(userBefore);
PrismObject<ShadowType> shadowBefore = getShadowModel(accountShadowOid);
display("Model Shadow before", shadowBefore);
String dn = ShadowUtil.getAttributeValue(shadowBefore, RESOURCE_OPENDJ_SECONDARY_IDENTIFIER);
openDJController.delete(dn);
PrismObject<ShadowType> repoShadowBefore = repositoryService.getObject(ShadowType.class, accountShadowOid, null, result);
assertNotNull("Repo shadow is gone!", repoShadowBefore);
display("Repository shadow before", repoShadowBefore);
assertTrue("Oh my! Shadow is dead!", repoShadowBefore.asObjectable().isDead() != Boolean.TRUE);
// WHEN
TestUtil.displayWhen(TEST_NAME);
recomputeUser(USER_GUYBRUSH_OID, task, result);
// THEN
TestUtil.displayThen(TEST_NAME);
result.computeStatus();
TestUtil.assertSuccess(result);
PrismObject<UserType> userAfter = getUser(USER_GUYBRUSH_OID);
display("User after", userAfter);
String accountShadowOidAfter = assertOneAccountRef(userAfter);
PrismObject<ShadowType> shadowAfter = getShadowModel(accountShadowOidAfter);
display("Shadow after", shadowAfter);
Entry entryAfter = openDJController.fetchEntry(dn);
display("Entry after", entryAfter);
}
/**
* Recompute user => account not found => reaction: Re-create account
* MID-3093
*/
@Test
public void test152RecomputeUserAccountAndShadowNotFound() throws Exception {
final String TEST_NAME = "test152RecomputeUserAccountAndShadowNotFound";
TestUtil.displayTestTile(TEST_NAME);
// GIVEN
Task task = taskManager.createTaskInstance(TEST_NAME);
OperationResult result = task.getResult();
PrismObject<UserType> userBefore = getUser(USER_GUYBRUSH_OID);
display("User before", userBefore);
String accountShadowOid = assertOneAccountRef(userBefore);
PrismObject<ShadowType> shadowBefore = getShadowModel(accountShadowOid);
display("Shadow before", shadowBefore);
String dn = ShadowUtil.getAttributeValue(shadowBefore, RESOURCE_OPENDJ_SECONDARY_IDENTIFIER);
openDJController.delete(dn);
repositoryService.deleteObject(ShadowType.class, accountShadowOid, result);
// WHEN
recomputeUser(USER_GUYBRUSH_OID, task, result);
// THEN
result.computeStatus();
TestUtil.assertSuccess(result);
PrismObject<UserType> userAfter = getUser(USER_GUYBRUSH_OID);
display("User after", userAfter);
String accountShadowOidAfter = assertOneAccountRef(userAfter);
PrismObject<ShadowType> shadowAfter = getShadowModel(accountShadowOidAfter);
display("Shadow after", shadowAfter);
Entry entryAfter = openDJController.fetchEntry(dn);
display("Entry after", entryAfter);
}
@Test
public void test159DeleteUSerGuybrush() throws Exception {
final String TEST_NAME = "test159DeleteUSerGuybrush";
TestUtil.displayTestTile(TEST_NAME);
// GIVEN
Task task = taskManager.createTaskInstance(TEST_NAME);
OperationResult result = task.getResult();
PrismObject<UserType> userBefore = getUser(USER_GUYBRUSH_OID);
display("User before", userBefore);
String accountShadowOid = assertOneAccountRef(userBefore);
PrismObject<ShadowType> shadowBefore = getShadowModel(accountShadowOid);
display("Shadow before", shadowBefore);
String dn = ShadowUtil.getAttributeValue(shadowBefore, RESOURCE_OPENDJ_SECONDARY_IDENTIFIER);
openDJController.delete(dn);
// WHEN
deleteObject(UserType.class, USER_GUYBRUSH_OID, task, result);
// THEN
result.computeStatus();
TestUtil.assertSuccess(result);
assertNoObject(UserType.class, USER_GUYBRUSH_OID, task, result);
// TODO: assert no shadow
// TODO: assert no entry
}
@Test
public void test200StopOpenDj() throws Exception {
final String TEST_NAME = "test200StopOpenDj";
TestUtil.displayTestTile(TEST_NAME);
openDJController.stop();
assertEquals("Resource is running", false, EmbeddedUtils.isRunning());
}
@Test
public void test210AddObjectCommunicationProblem() throws Exception {
final String TEST_NAME = "test210AddObjectCommunicationProblem";
TestUtil.displayTestTile(TEST_NAME);
// GIVEN
openDJController.assumeStopped();
Task task = taskManager.createTaskInstance(TEST_NAME);
OperationResult parentResult = task.getResult();
repoAddObjectFromFile(USER_E_FILENAME, parentResult);
assertUserNoAccountRef(USER_E_OID, parentResult);
//REQUEST_USER_MODIFY_ADD_ACCOUNT_COMMUNICATION_PROBLEM
requestToExecuteChanges(REQUEST_USER_MODIFY_ASSIGN_ACCOUNT, USER_E_OID, UserType.class, task, null, parentResult);
parentResult.computeStatus();
display("add object communication problem result: ", parentResult);
assertEquals("Expected handled error but got: " + parentResult.getStatus(), OperationResultStatus.HANDLED_ERROR, parentResult.getStatus());
String accountOid = checkRepoUser(USER_E_OID, parentResult);
checkPostponedAccountWithAttributes(accountOid, "e", "e", "e", "e", FailedOperationTypeType.ADD, false, task, parentResult);
}
@SuppressWarnings("unchecked")
@Test
public void test212AddModifyObjectCommunicationProblem() throws Exception {
final String TEST_NAME = "test212AddModifyObjectCommunicationProblem";
TestUtil.displayTestTile(TEST_NAME);
// GIVEN
openDJController.assumeStopped();
Task task = taskManager.createTaskInstance(TEST_NAME);
OperationResult parentResult = task.getResult();
String accountOid = assertUserOneAccountRef(USER_E_OID);
//WHEN
TestUtil.displayWhen(TEST_NAME);
requestToExecuteChanges(REQUEST_ACCOUNT_MODIFY_COMMUNICATION_PROBLEM, accountOid, ShadowType.class, task, null, parentResult);
//THEN
TestUtil.displayThen(TEST_NAME);
checkPostponedAccountWithAttributes(accountOid, "e", "Jackkk", "e", "e", "emp4321", FailedOperationTypeType.ADD, false, task, parentResult);
}
@Test
public void test214ModifyObjectCommunicationProblem() throws Exception {
final String TEST_NAME = "test214ModifyObjectCommunicationProblem";
TestUtil.displayTestTile(TEST_NAME);
// GIVEN
openDJController.assumeStopped();
OperationResult parentResult = new OperationResult(TEST_NAME);
String accountOid = assertUserOneAccountRef(USER_JACK_OID);
Task task = taskManager.createTaskInstance();
//WHEN
TestUtil.displayWhen(TEST_NAME);
requestToExecuteChanges(REQUEST_ACCOUNT_MODIFY_COMMUNICATION_PROBLEM, accountOid, ShadowType.class, task, null, parentResult);
//THEN
TestUtil.displayThen(TEST_NAME);
checkPostponedAccountBasic(accountOid, FailedOperationTypeType.MODIFY, true, parentResult);
}
@Test
public void test220DeleteObjectCommunicationProblem() throws Exception {
final String TEST_NAME = "test220DeleteObjectCommunicationProblem";
TestUtil.displayTestTile(TEST_NAME);
// GIVEN
openDJController.assumeStopped();
Task task = taskManager.createTaskInstance(TEST_NAME);
OperationResult parentResult = task.getResult();
String accountOid = assertUserOneAccountRef(USER_DENIELS_OID);
//WHEN
requestToExecuteChanges(REQUEST_USER_MODIFY_DELETE_ACCOUNT_COMMUNICATION_PROBLEM, USER_DENIELS_OID, UserType.class, task, null, parentResult);
assertUserNoAccountRef(USER_DENIELS_OID, parentResult);
ObjectDelta deleteDelta = ObjectDelta.createDeleteDelta(ShadowType.class, ACCOUNT_DENIELS_OID, prismContext);
Collection<ObjectDelta<? extends ObjectType>> deltas = MiscSchemaUtil.createCollection(deleteDelta);
modelService.executeChanges(deltas, null, task, parentResult);
// THEN
checkPostponedAccountBasic(accountOid, FailedOperationTypeType.DELETE, false, parentResult);
}
@Test
public void test230GetAccountCommunicationProblem() throws Exception {
final String TEST_NAME = "test230GetAccountCommunicationProblem";
TestUtil.displayTestTile(TEST_NAME);
// GIVEN
openDJController.assumeStopped();
OperationResult result = new OperationResult(TEST_NAME);
ShadowType account = modelService.getObject(ShadowType.class, ACCOUNT_DENIELS_OID,
null, null, result).asObjectable();
assertNotNull("Get method returned null account.", account);
assertNotNull("Fetch result was not set in the shadow.", account.getFetchResult());
}
@Test
public void test240AddObjectCommunicationProblemAlreadyExists() throws Exception{
final String TEST_NAME = "test240AddObjectCommunicationProblemAlreadyExists";
TestUtil.displayTestTile(this, TEST_NAME);
// GIVEN
openDJController.assumeRunning();
OperationResult parentResult = new OperationResult(TEST_NAME);
Entry entry = openDJController.addEntryFromLdifFile(LDIF_ELAINE_FILENAME);
Entry searchResult = openDJController.searchByUid("elaine");
OpenDJController.assertAttribute(searchResult, "l", "Caribbean");
OpenDJController.assertAttribute(searchResult, "givenName", "Elaine");
OpenDJController.assertAttribute(searchResult, "sn", "Marley");
OpenDJController.assertAttribute(searchResult, "cn", "Elaine Marley");
OpenDJController.assertAttribute(searchResult, "mail", "governor.marley@deep.in.the.caribbean.com");
OpenDJController.assertAttribute(searchResult, "employeeType", "governor");
OpenDJController.assertAttribute(searchResult, "title", "Governor");
String dn = searchResult.getDN().toString();
assertEquals("DN attribute " + dn + " not equals", dn, "uid=elaine,ou=people,dc=example,dc=com");
openDJController.stop();
testAddUserToRepo(TEST_NAME, USER_ELAINE_FILENAME,
USER_ELAINE_OID);
assertUserNoAccountRef(USER_ELAINE_OID, parentResult);
Task task = taskManager.createTaskInstance();
//WHEN REQUEST_USER_MODIFY_ADD_ACCOUNT_ALERADY_EXISTS_COMMUNICATION_PROBLEM_OPENDJ_FILENAME
requestToExecuteChanges(REQUEST_USER_MODIFY_ASSIGN_ACCOUNT, USER_ELAINE_OID, UserType.class, task, null, parentResult);
//THEN
String accountOid = assertUserOneAccountRef(USER_ELAINE_OID);
checkPostponedAccountWithAttributes(accountOid, "elaine", "Elaine", "Marley", "Elaine Marley", FailedOperationTypeType.ADD, false, task, parentResult);
}
@Test
public void test250ModifyObjectTwoTimesCommunicationProblem() throws Exception {
final String TEST_NAME = "test250ModifyObjectTwoTimesCommunicationProblem";
TestUtil.displayTestTile(this, TEST_NAME);
// GIVEN
openDJController.assumeStopped();
OperationResult parentResult = new OperationResult(TEST_NAME);
assertUserOneAccountRef(USER_JACK2_OID);
Collection<PropertyDelta> modifications = new ArrayList<PropertyDelta>();
PropertyDelta fullNameDelta = PropertyDelta.createModificationReplaceProperty(new ItemPath(UserType.F_FULL_NAME), getUserDefinition(), new PolyString("jackNew2"));
modifications.add(fullNameDelta);
PrismPropertyValue<ActivationStatusType> enabledUserAction = new PrismPropertyValue<ActivationStatusType>(ActivationStatusType.ENABLED, OriginType.USER_ACTION, null);
PropertyDelta<ActivationStatusType> enabledDelta = PropertyDelta.createDelta(SchemaConstants.PATH_ACTIVATION_ADMINISTRATIVE_STATUS, getUserDefinition());
enabledDelta.addValueToAdd(enabledUserAction);
modifications.add(enabledDelta);
ObjectDelta objectDelta = ObjectDelta.createModifyDelta(USER_JACK2_OID, modifications, UserType.class, prismContext);
Collection<ObjectDelta<? extends ObjectType>> deltas = MiscSchemaUtil.createCollection(objectDelta);
Task task = taskManager.createTaskInstance();
modelService.executeChanges(deltas, null, task, parentResult);
parentResult.computeStatus();
String accountOid = assertUserOneAccountRef(USER_JACK2_OID);
PrismObject<ShadowType> account = modelService.getObject(ShadowType.class, accountOid, null, task, parentResult);
assertNotNull(account);
ShadowType shadow = account.asObjectable();
assertNotNull(shadow.getObjectChange());
display("shadow after communication problem", shadow);
Collection<PropertyDelta> newModifications = new ArrayList<PropertyDelta>();
PropertyDelta fullNameDeltaNew = PropertyDelta.createModificationReplaceProperty(new ItemPath(UserType.F_FULL_NAME), getUserDefinition(), new PolyString("jackNew2a"));
newModifications.add(fullNameDeltaNew);
PropertyDelta givenNameDeltaNew = PropertyDelta.createModificationReplaceProperty(new ItemPath(UserType.F_GIVEN_NAME), getUserDefinition(), new PolyString("jackNew2a"));
newModifications.add(givenNameDeltaNew);
PrismPropertyValue<ActivationStatusType> enabledOutboundAction = new PrismPropertyValue<ActivationStatusType>(ActivationStatusType.ENABLED, OriginType.USER_ACTION, null);
PropertyDelta<ActivationStatusType> enabledDeltaNew = PropertyDelta.createDelta(SchemaConstants.PATH_ACTIVATION_ADMINISTRATIVE_STATUS, getUserDefinition());
enabledDeltaNew.addValueToAdd(enabledOutboundAction);
newModifications.add(enabledDeltaNew);
ObjectDelta newObjectDelta = ObjectDelta.createModifyDelta(USER_JACK2_OID, newModifications, UserType.class, prismContext);
Collection<ObjectDelta<? extends ObjectType>> newDeltas = MiscSchemaUtil.createCollection(newObjectDelta);
modelService.executeChanges(newDeltas, null, task, parentResult);
account = modelService.getObject(ShadowType.class, accountOid, null, task, parentResult);
assertNotNull(account);
shadow = account.asObjectable();
assertNotNull(shadow.getObjectChange());
display("shadow after communication problem", shadow);
// parentResult.computeStatus();
// assertEquals("expected handled error in the result", OperationResultStatus.HANDLED_ERROR, parentResult.getStatus());
}
/**
* this test simulates situation, when someone tries to add account while
* resource is down and this account is created by next get call on this
* account
*/
@Test
public void test260GetDiscoveryAddCommunicationProblem() throws Exception {
final String TEST_NAME = "test260GetDiscoveryAddCommunicationProblem";
TestUtil.displayTestTile(TEST_NAME);
// GIVEN
openDJController.assumeStopped();
display("OpenDJ stopped");
OperationResult parentResult = new OperationResult(TEST_NAME);
repoAddObjectFromFile(USER_ANGELIKA_FILENAME, parentResult);
assertUserNoAccountRef(USER_ANGELIKA_OID, parentResult);
Task task = taskManager.createTaskInstance();
// WHEN
TestUtil.displayWhen(TEST_NAME);
//REQUEST_USER_MODIFY_ADD_ACCOUNT_COMMUNICATION_PROBLEM
requestToExecuteChanges(REQUEST_USER_MODIFY_ASSIGN_ACCOUNT, USER_ANGELIKA_OID, UserType.class, task, null, parentResult);
// THEN
TestUtil.displayThen(TEST_NAME);
parentResult.computeStatus();
display("add object communication problem result: ", parentResult);
assertEquals("Expected handled error but got: " + parentResult.getStatus(), OperationResultStatus.HANDLED_ERROR, parentResult.getStatus());
String accountOid = assertUserOneAccountRef(USER_ANGELIKA_OID);
checkPostponedAccountWithAttributes(accountOid, "angelika", "angelika", "angelika", "angelika", FailedOperationTypeType.ADD, false, task, parentResult);
//start openDJ
openDJController.start();
//and set the resource availability status to UP
modifyResourceAvailabilityStatus(AvailabilityStatusType.UP, parentResult);
TestUtil.info("OpenDJ started, resource UP");
ShadowType shadowAfter = checkNormalizedShadowWithAttributes(accountOid, "angelika", "angelika", "angelika", "angelika", false, task, parentResult);
}
@Test
public void test262GetDiscoveryModifyCommunicationProblem() throws Exception {
final String TEST_NAME = "test262GetDiscoveryModifyCommunicationProblem";
TestUtil.displayTestTile(TEST_NAME);
// GIVEN
openDJController.assumeRunning();
Task task = taskManager.createTaskInstance(TEST_NAME);
OperationResult parentResult = task.getResult();
//prepare user
repoAddObjectFromFile(USER_ALICE_FILENAME, parentResult);
assertUserNoAccountRef(USER_ALICE_OID, parentResult);
//and add account to the user while resource is UP
//REQUEST_USER_MODIFY_ADD_ACCOUNT_COMMUNICATION_PROBLEM
requestToExecuteChanges(REQUEST_USER_MODIFY_ASSIGN_ACCOUNT, USER_ALICE_OID, UserType.class, task, null, parentResult);
//then stop openDJ
openDJController.stop();
String accountOid = assertUserOneAccountRef(USER_ALICE_OID);
//and make some modifications to the account while resource is DOWN
requestToExecuteChanges(REQUEST_ACCOUNT_MODIFY_COMMUNICATION_PROBLEM, accountOid, ShadowType.class, task, null, parentResult);
//check the state after execution
checkPostponedAccountBasic(accountOid, FailedOperationTypeType.MODIFY, true, parentResult);
//start openDJ
openDJController.start();
//and set the resource availability status to UP
modifyResourceAvailabilityStatus(AvailabilityStatusType.UP, parentResult);
//and then try to get account -> result is that the modifications will be applied to the account
ShadowType aliceAccount = checkNormalizedShadowWithAttributes(accountOid, "alice", "Jackkk", "alice", "alice", true, task, parentResult);
assertAttribute(aliceAccount, "employeeNumber", "emp4321");
}
@Test
public void test264GetDiscoveryModifyUserPasswordCommunicationProblem() throws Exception {
final String TEST_NAME = "test264GetDiscoveryModifyUserPasswordCommunicationProblem";
TestUtil.displayTestTile(TEST_NAME);
// GIVEN
openDJController.assumeStopped();
Task task = taskManager.createTaskInstance(TEST_NAME);
OperationResult parentResult = task.getResult();
String accountOid = assertUserOneAccountRef(USER_ALICE_OID);
// WHEN (down)
requestToExecuteChanges(REQUEST_USER_MODIFY_CHANGE_PASSWORD_1, USER_ALICE_OID, UserType.class, task, null, parentResult);
// THEN
//check the state after execution
checkPostponedAccountBasic(accountOid, FailedOperationTypeType.MODIFY, true, parentResult);
//start openDJ
openDJController.start();
modifyResourceAvailabilityStatus(AvailabilityStatusType.UP, parentResult);
// WHEN (restore)
//and then try to get account -> result is that the modifications will be applied to the account
ShadowType aliceAccount = checkNormalizedShadowWithAttributes(accountOid, "alice", "Jackkk", "alice", "alice", true, task, parentResult);
assertAttribute(aliceAccount, "employeeNumber", "emp4321");
PrismObject<UserType> userAliceAfter = getUser(USER_ALICE_OID);
assertPassword(userAliceAfter, "DEADmenTELLnoTALES");
aliceAccountDn = ShadowUtil.getAttributeValue(aliceAccount, getOpenDjSecondaryIdentifierQName());
openDJController.assertPassword(aliceAccountDn, "DEADmenTELLnoTALES");
}
/**
* Modify user password when resource is down. Bring resource up and run recon.
* Check that the password change is applied.
*/
@Test
public void test265ModifyUserPasswordCommunicationProblemRecon() throws Exception {
final String TEST_NAME = "test265ModifyUserPasswordCommunicationProblemRecon";
TestUtil.displayTestTile(TEST_NAME);
// GIVEN
openDJController.assumeStopped();
Task task = taskManager.createTaskInstance(TEST_NAME);
OperationResult result = task.getResult();
String accountOid = assertUserOneAccountRef(USER_ALICE_OID);
// WHEN (down)
TestUtil.displayWhen(TEST_NAME);
requestToExecuteChanges(REQUEST_USER_MODIFY_CHANGE_PASSWORD_2, USER_ALICE_OID, UserType.class, task, null, result);
// THEN
TestUtil.displayThen(TEST_NAME);
//check the state after execution
checkPostponedAccountBasic(accountOid, FailedOperationTypeType.MODIFY, true, result);
//start openDJ
openDJController.start();
modifyResourceAvailabilityStatus(AvailabilityStatusType.UP, result);
// WHEN (restore)
TestUtil.displayWhen(TEST_NAME);
reconcileUser(USER_ALICE_OID, task, result);
// THEN
TestUtil.displayThen(TEST_NAME);
openDJController.assertPassword(aliceAccountDn, "UNDEADmenTELLscaryTALES");
PrismObject<UserType> userAliceAfter = getUser(USER_ALICE_OID);
assertPassword(userAliceAfter, "UNDEADmenTELLscaryTALES");
// Do this as a last step so it will not interfere with the results
ShadowType aliceAccount = checkNormalizedShadowWithAttributes(accountOid, "alice", "Jackkk", "alice", "alice", true, task, result);
assertAttribute(aliceAccount, "employeeNumber", "emp4321");
}
/**
* this test simulates situation, when someone tries to add account while
* resource is down and this account is created by next get call on this
* account
*/
@Test
public void test270ModifyDiscoveryAddCommunicationProblem() throws Exception {
final String TEST_NAME = "test270ModifyDiscoveryAddCommunicationProblem";
TestUtil.displayTestTile(TEST_NAME);
// GIVEN
openDJController.assumeStopped();
OperationResult parentResult = new OperationResult(TEST_NAME);
// WHEN
repoAddObjectFromFile(USER_BOB_NO_GIVEN_NAME_FILENAME, parentResult);
assertUserNoAccountRef(USER_BOB_NO_GIVEN_NAME_OID, parentResult);
Task task = taskManager.createTaskInstance();
//REQUEST_USER_MODIFY_ADD_ACCOUNT_COMMUNICATION_PROBLEM
requestToExecuteChanges(REQUEST_USER_MODIFY_ASSIGN_ACCOUNT, USER_BOB_NO_GIVEN_NAME_OID, UserType.class, task, null, parentResult);
parentResult.computeStatus();
display("add object communication problem result: ", parentResult);
assertEquals("Expected handled error but got: " + parentResult.getStatus(), OperationResultStatus.HANDLED_ERROR, parentResult.getStatus());
String accountOid = assertUserOneAccountRef(USER_BOB_NO_GIVEN_NAME_OID);
checkPostponedAccountWithAttributes(accountOid, "bob", null, "Dylan", "Bob Dylan", FailedOperationTypeType.ADD, false, task, parentResult);
//start openDJ
openDJController.start();
//and set the resource availability status to UP
modifyResourceAvailabilityStatus(AvailabilityStatusType.UP, parentResult);
// WHEN
// This should not throw exception
modelService.getObject(ShadowType.class, accountOid, null, task, parentResult);
OperationResult modifyGivenNameResult = new OperationResult("execute changes -> modify user's given name");
LOGGER.trace("execute changes -> modify user's given name");
Collection<? extends ItemDelta> givenNameDelta = PropertyDelta.createModificationReplacePropertyCollection(UserType.F_GIVEN_NAME, getUserDefinition(), new PolyString("Bob"));
ObjectDelta familyNameD = ObjectDelta.createModifyDelta(USER_BOB_NO_GIVEN_NAME_OID, givenNameDelta, UserType.class, prismContext);
Collection<ObjectDelta<? extends ObjectType>> modifyFamilyNameDelta = MiscSchemaUtil.createCollection(familyNameD);
modelService.executeChanges(modifyFamilyNameDelta, null, task, modifyGivenNameResult);
modifyGivenNameResult.computeStatus();
display("add object communication problem result: ", modifyGivenNameResult);
assertEquals("Expected handled error but got: " + modifyGivenNameResult.getStatus(), OperationResultStatus.SUCCESS, modifyGivenNameResult.getStatus());
PrismObject<ShadowType> bobRepoAcc = repositoryService.getObject(ShadowType.class, accountOid, null, modifyGivenNameResult);
assertNotNull(bobRepoAcc);
ShadowType bobRepoAccount = bobRepoAcc.asObjectable();
displayJaxb("Shadow after discovery: ", bobRepoAccount, ShadowType.COMPLEX_TYPE);
assertNull("Bob's account after discovery must not have failed opertion.", bobRepoAccount.getFailedOperationType());
assertNull("Bob's account after discovery must not have result.", bobRepoAccount.getResult());
assertNotNull("Bob's account must contain reference on the resource", bobRepoAccount.getResourceRef());
checkNormalizedShadowWithAttributes(accountOid, "bob", "Bob", "Dylan", "Bob Dylan", false, task, parentResult);
}
@Test
public void test280ModifyObjectCommunicationProblemWeakMapping() throws Exception{
final String TEST_NAME = "test280ModifyObjectCommunicationProblemWeakMapping";
TestUtil.displayTestTile(TEST_NAME);
// GIVEN
openDJController.assumeRunning();
OperationResult parentResult = new OperationResult(TEST_NAME);
repoAddObjectFromFile(USER_JOHN_WEAK_FILENAME, parentResult);
assertUserNoAccountRef(USER_JOHN_WEAK_OID, parentResult);
Task task = taskManager.createTaskInstance();
//REQUEST_USER_MODIFY_ADD_ACCOUNT_COMMUNICATION_PROBLEM
requestToExecuteChanges(REQUEST_USER_MODIFY_ASSIGN_ACCOUNT, USER_JOHN_WEAK_OID, UserType.class, task, null, parentResult);
parentResult.computeStatus();
display("add object communication problem result: ", parentResult);
assertEquals("Expected success but got: " + parentResult.getStatus(), OperationResultStatus.SUCCESS, parentResult.getStatus());
String accountOid = assertUserOneAccountRef(USER_JOHN_WEAK_OID);
checkNormalizedShadowWithAttributes(accountOid, "john", "john", "weak", "john weak", "manager", false, task, parentResult);
//stop opendj and try to modify employeeType (weak mapping)
openDJController.stop();
LOGGER.info("start modifying user - account with weak mapping after stopping opendj.");
requestToExecuteChanges(REQUEST_USER_MODIFY_WEAK_MAPPING_COMMUNICATION_PROBLEM, USER_JOHN_WEAK_OID, UserType.class, task, null, parentResult);
// TODO: [RS] not 100% sure about this. But if you do not expect an error you should not set doNotDiscovery. Server is still not running.
checkNormalizedShadowBasic(accountOid, "john", true, null, task, parentResult);
// checkNormalizedShadowBasic(accountOid, "john", true, SelectorOptions.createCollection(GetOperationOptions.createDoNotDiscovery()), task, parentResult);
}
@Test
public void test282ModifyObjectCommunicationProblemWeakAndStrongMapping() throws Exception {
final String TEST_NAME = "test282ModifyObjectCommunicationProblemWeakAndStrongMapping";
TestUtil.displayTestTile(TEST_NAME);
// GIVEN
openDJController.assumeRunning();
OperationResult parentResult = new OperationResult(TEST_NAME);
repoAddObjectFromFile(USER_DONALD_FILENAME, parentResult);
assertUserNoAccountRef(USER_DONALD_OID, parentResult);
Task task = taskManager.createTaskInstance();
//REQUEST_USER_MODIFY_ADD_ACCOUNT_COMMUNICATION_PROBLEM
requestToExecuteChanges(REQUEST_USER_MODIFY_ASSIGN_ACCOUNT, USER_DONALD_OID, UserType.class, task, null, parentResult);
parentResult.computeStatus();
display("add object communication problem result: ", parentResult);
assertEquals("Expected success but got: " + parentResult.getStatus(), OperationResultStatus.SUCCESS, parentResult.getStatus());
String accountOid = assertUserOneAccountRef(USER_DONALD_OID);
ShadowType johnAccountType = checkNormalizedShadowWithAttributes(accountOid, "donald", "donald", "trump", "donald trump", false, task, parentResult);
assertAttribute(johnAccountType, "employeeType", "manager");
//stop opendj and try to modify employeeType (weak mapping)
openDJController.stop();
LOGGER.info("start modifying user - account with weak mapping after stopping opendj.");
requestToExecuteChanges(REQUEST_USER_MODIFY_WEAK_STRONG_MAPPING_COMMUNICATION_PROBLEM, USER_DONALD_OID, UserType.class, task, null, parentResult);
johnAccountType = checkPostponedAccountBasic(accountOid, FailedOperationTypeType.MODIFY, true, parentResult);
ObjectDelta deltaInAccount = DeltaConvertor.createObjectDelta(johnAccountType.getObjectChange(), prismContext);
assertTrue("Delta stored in account must contain given name modification", deltaInAccount.hasItemDelta(new ItemPath(ShadowType.F_ATTRIBUTES, new QName(resourceTypeOpenDjrepo.getNamespace(), "givenName"))));
assertFalse("Delta stored in account must not contain employeeType modification", deltaInAccount.hasItemDelta(new ItemPath(ShadowType.F_ATTRIBUTES, new QName(resourceTypeOpenDjrepo.getNamespace(), "employeeType"))));
assertNotNull("Donald's account must contain reference on the resource", johnAccountType.getResourceRef());
//TODO: check on user if it was processed successfully (add this check also to previous (30) test..
}
@Test
public void test283GetObjectNoFetchShadowAndRecompute() throws Exception {
final String TEST_NAME = "test283GetObjectNoFetchShadowAndRecompute";
TestUtil.displayTestTile(TEST_NAME);
// GIVEN
openDJController.assumeRunning();
OperationResult parentResult = new OperationResult(TEST_NAME);
String accountOid = assertUserOneAccountRef(USER_DONALD_OID);
Task task = taskManager.createTaskInstance();
// Get user's account with noFetch option - changes shouldn't be applied, bud should be still saved in shadow
PrismObject<ShadowType> johnAccount = modelService.getObject(ShadowType.class, accountOid, GetOperationOptions.createNoFetchCollection(), task, parentResult);
ShadowType johnAccountType = checkPostponedAccountBasic(johnAccount, FailedOperationTypeType.MODIFY, true, parentResult);
ObjectDelta deltaInAccount = DeltaConvertor.createObjectDelta(johnAccountType.getObjectChange(), prismContext);
assertTrue("Delta stored in account must contain given name modification", deltaInAccount.hasItemDelta(new ItemPath(ShadowType.F_ATTRIBUTES, new QName(resourceTypeOpenDjrepo.getNamespace(), "givenName"))));
assertFalse("Delta stored in account must not contain employeeType modification", deltaInAccount.hasItemDelta(new ItemPath(ShadowType.F_ATTRIBUTES, new QName(resourceTypeOpenDjrepo.getNamespace(), "employeeType"))));
assertNotNull("Donald's account must contain reference on the resource", johnAccountType.getResourceRef());
//THEN recompute the user - postponed changes should be applied
LOGGER.info("recompute user - account with weak mapping after stopping opendj.");
ObjectDelta<UserType> emptyDelta = ObjectDelta.createEmptyModifyDelta(UserType.class, USER_DONALD_OID, prismContext);
Collection<ObjectDelta<? extends ObjectType>> deltas = new ArrayList<>();
deltas.add(emptyDelta);
modelService.executeChanges(deltas, ModelExecuteOptions.createReconcile(), task, parentResult);
accountOid = assertUserOneAccountRef(USER_DONALD_OID);
johnAccountType = checkNormalizedShadowWithAttributes(accountOid, "donald", "don", "trump", "donald trump", false, task, parentResult);
//TODO: check on user if it was processed successfully (add this check also to previous (30) test..
}
@Test
public void test284ModifyObjectAssignToGroupCommunicationProblem() throws Exception {
final String TEST_NAME = "test284ModifyObjectAssignToGroupCommunicationProblem";
TestUtil.displayTestTile(TEST_NAME);
Task task = taskManager.createTaskInstance();
OperationResult parentResult = new OperationResult(TEST_NAME);
// GIVEN
openDJController.addEntriesFromLdifFile(LDIF_CREATE_ADMINS_GROUP_FILENAME);
ObjectQuery filter = ObjectQueryUtil.createResourceAndObjectClassQuery(RESOURCE_OPENDJ_OID, RESOURCE_OPENDJ_GROUP_OBJECTCLASS, prismContext);
SearchResultList<PrismObject<ShadowType>> shadows = modelService.searchObjects(ShadowType.class, filter, null, task, parentResult);
for (PrismObject<ShadowType> shadow : shadows) {
LOGGER.info("SHADOW ===> {}", shadow.debugDump() );
}
// WHEN
openDJController.assumeStopped();
String accountOid = assertUserOneAccountRef(USER_DONALD_OID);
requestToExecuteChanges(REQUEST_USER_MODIFY_ASSIGN_ROLE_ADMINS, USER_DONALD_OID, UserType.class, task, null, parentResult);
// Get user's account with noFetch option - changes shouldn't be applied, bud should be still saved in shadow
PrismObject<ShadowType> johnAccount = modelService.getObject(ShadowType.class, accountOid, GetOperationOptions.createNoFetchCollection(), task, parentResult);
ShadowType johnAccountType = checkPostponedAccountBasic(johnAccount, FailedOperationTypeType.MODIFY, true, parentResult);
ObjectDelta deltaInAccount = DeltaConvertor.createObjectDelta(johnAccountType.getObjectChange(), prismContext);
assertTrue("Delta stored in account must contain association modification", deltaInAccount.hasItemDelta(new ItemPath(ShadowType.F_ASSOCIATION)));
// assertFalse("Delta stored in account must not contain employeeType modification", deltaInAccount.hasItemDelta(new ItemPath(ShadowType.F_ATTRIBUTES, new QName(resourceTypeOpenDjrepo.getNamespace(), "employeeType"))));
assertNotNull("Donald's account must contain reference on the resource", johnAccountType.getResourceRef());
//THEN recompute the user - postponed changes should be applied
openDJController.assumeRunning();
LOGGER.info("recompute user - account with weak mapping after stopping opendj.");
ObjectDelta<UserType> emptyDelta = ObjectDelta.createEmptyModifyDelta(UserType.class, USER_DONALD_OID, prismContext);
Collection<ObjectDelta<? extends ObjectType>> deltas = new ArrayList<>();
deltas.add(emptyDelta);
modelService.executeChanges(deltas, ModelExecuteOptions.createReconcile(), task, parentResult);
accountOid = assertUserOneAccountRef(USER_DONALD_OID);
johnAccountType = checkNormalizedShadowWithAttributes(accountOid, "donald", "donalld", "trump", "donald trump", false, task, parentResult);
openDJController.assertUniqueMember("cn=admins,ou=groups,dc=example,dc=com", "uid=donald,ou=people,dc=example,dc=com");
//TODO: check on user if it was processed successfully (add this check also to previous (30) test..
}
//TODO: enable after notify failure will be implemented..
@Test(enabled = false)
public void test400GetDiscoveryAddCommunicationProblemAlreadyExists() throws Exception{
final String TEST_NAME = "test400GetDiscoveryAddCommunicationProblemAlreadyExists";
TestUtil.displayTestTile(TEST_NAME);
// GIVEN
openDJController.assumeStopped();
OperationResult parentResult = new OperationResult(TEST_NAME);
repoAddObjectFromFile(USER_DISCOVERY_FILENAME, parentResult);
assertUserNoAccountRef(USER_DISCOVERY_OID, parentResult);
Task task = taskManager.createTaskInstance();
//REQUEST_USER_MODIFY_ADD_ACCOUNT_COMMUNICATION_PROBLEM
requestToExecuteChanges(REQUEST_USER_MODIFY_ASSIGN_ACCOUNT, USER_DISCOVERY_OID, UserType.class, task, null, parentResult);
parentResult.computeStatus();
display("add object communication problem result: ", parentResult);
assertEquals("Expected success but got: " + parentResult.getStatus(), OperationResultStatus.HANDLED_ERROR, parentResult.getStatus());
String accountOid = assertUserOneAccountRef(USER_DISCOVERY_OID);
openDJController.start();
assertTrue(EmbeddedUtils.isRunning());
Entry entry = openDJController.addEntryFromLdifFile(LDIF_DISCOVERY_FILENAME);
Entry searchResult = openDJController.searchByUid("discovery");
OpenDJController.assertAttribute(searchResult, "l", "Caribbean");
OpenDJController.assertAttribute(searchResult, "givenName", "discovery");
OpenDJController.assertAttribute(searchResult, "sn", "discovery");
OpenDJController.assertAttribute(searchResult, "cn", "discovery");
OpenDJController.assertAttribute(searchResult, "mail", "discovery@deep.in.the.caribbean.com");
String dn = searchResult.getDN().toString();
assertEquals("DN attribute " + dn + " not equals", dn, "uid=discovery,ou=people,dc=example,dc=com");
modifyResourceAvailabilityStatus(AvailabilityStatusType.UP, parentResult);
modelService.getObject(ShadowType.class, accountOid, null, task, parentResult);
}
/**
* Adding a user (morgan) that has an OpenDJ assignment. But the equivalent account already exists on
* OpenDJ. The account should be linked.
*/
@Test
public void test500AddUserMorganWithAssignment() throws Exception {
final String TEST_NAME = "test500AddUserMorganWithAssignment";
TestUtil.displayTestTile(this, TEST_NAME);
// GIVEN
openDJController.assumeRunning();
Task task = taskManager.createTaskInstance(ConsistencyTest.class.getName() + "." + TEST_NAME);
OperationResult result = task.getResult();
dummyAuditService.clear();
Entry entry = openDJController.addEntryFromLdifFile(LDIF_MORGAN_FILENAME);
display("Entry from LDIF", entry);
PrismObject<UserType> user = PrismTestUtil.parseObject(new File(USER_MORGAN_FILENAME));
display("Adding user", user);
ObjectDelta<UserType> userDelta = ObjectDelta.createAddDelta(user);
Collection<ObjectDelta<? extends ObjectType>> deltas = MiscSchemaUtil.createCollection(userDelta);
// WHEN
TestUtil.displayWhen(TEST_NAME);
modelService.executeChanges(deltas, null, task, result);
// THEN
TestUtil.displayThen(TEST_NAME);
result.computeStatus();
// assertEquals("Expected handled error but got: " + result.getStatus(), OperationResultStatus.HANDLED_ERROR, result.getStatus());
PrismObject<UserType> userMorgan = modelService.getObject(UserType.class, USER_MORGAN_OID, null, task, result);
display("User morgan after", userMorgan);
UserType userMorganType = userMorgan.asObjectable();
assertEquals("Unexpected number of accountRefs", 1, userMorganType.getLinkRef().size());
ObjectReferenceType accountRefType = userMorganType.getLinkRef().get(0);
String accountOid = accountRefType.getOid();
assertFalse("No accountRef oid", StringUtils.isBlank(accountOid));
// Check shadow
PrismObject<ShadowType> accountShadow = repositoryService.getObject(ShadowType.class, accountOid, null, result);
assertShadowRepo(accountShadow, accountOid, "uid=morgan,ou=people,dc=example,dc=com", resourceTypeOpenDjrepo, RESOURCE_OPENDJ_ACCOUNT_OBJECTCLASS);
// Check account
PrismObject<ShadowType> accountModel = modelService.getObject(ShadowType.class, accountOid, null, task, result);
assertShadowModel(accountModel, accountOid, "uid=morgan,ou=people,dc=example,dc=com", resourceTypeOpenDjrepo, RESOURCE_OPENDJ_ACCOUNT_OBJECTCLASS);
// TODO: check OpenDJ Account
}
/**
* Adding a user (morgan) that has an OpenDJ assignment. But the equivalent account already exists on
* OpenDJ and there is also corresponding shadow in the repo. The account should be linked.
*/
@Test
public void test501AddUserChuckWithAssignment() throws Exception {
final String TEST_NAME = "test501AddUserChuckWithAssignment";
TestUtil.displayTestTile(this, TEST_NAME);
// GIVEN
openDJController.assumeRunning();
Task task = taskManager.createTaskInstance(ConsistencyTest.class.getName() + "." + TEST_NAME);
OperationResult result = task.getResult();
dummyAuditService.clear();
// Entry entry = openDJController.addEntryFromLdifFile(LDIF_MORGAN_FILENAME);
// display("Entry from LDIF", entry);
PrismObject<ShadowType> account = PrismTestUtil.parseObject(new File(ACCOUNT_CHUCK_FILENAME));
String accOid = provisioningService.addObject(account, null, null, task, result);
//
PrismObject<UserType> user = PrismTestUtil.parseObject(new File(USER_CHUCK_FILENAME));
display("Adding user", user);
ObjectDelta<UserType> userDelta = ObjectDelta.createAddDelta(user);
Collection<ObjectDelta<? extends ObjectType>> deltas = MiscSchemaUtil.createCollection(userDelta);
// WHEN
TestUtil.displayWhen(TEST_NAME);
modelService.executeChanges(deltas, null, task, result);
// THEN
TestUtil.displayThen(TEST_NAME);
result.computeStatus();
// assertEquals("Expected handled error but got: " + result.getStatus(), OperationResultStatus.HANDLED_ERROR, result.getStatus());
PrismObject<UserType> userMorgan = modelService.getObject(UserType.class, USER_CHUCK_OID, null, task, result);
display("User morgan after", userMorgan);
UserType userMorganType = userMorgan.asObjectable();
assertEquals("Unexpected number of accountRefs", 1, userMorganType.getLinkRef().size());
ObjectReferenceType accountRefType = userMorganType.getLinkRef().get(0);
String accountOid = accountRefType.getOid();
assertFalse("No accountRef oid", StringUtils.isBlank(accountOid));
assertEquals("old oid not used..", accOid, accountOid);
// Check shadow
PrismObject<ShadowType> accountShadow = repositoryService.getObject(ShadowType.class, accountOid, null, result);
assertShadowRepo(accountShadow, accountOid, "uid=chuck,ou=people,dc=example,dc=com", resourceTypeOpenDjrepo, RESOURCE_OPENDJ_ACCOUNT_OBJECTCLASS);
// Check account
PrismObject<ShadowType> accountModel = modelService.getObject(ShadowType.class, accountOid, null, task, result);
assertShadowModel(accountModel, accountOid, "uid=chuck,ou=people,dc=example,dc=com", resourceTypeOpenDjrepo, RESOURCE_OPENDJ_ACCOUNT_OBJECTCLASS);
ShadowType accountTypeModel = accountModel.asObjectable();
assertAttribute(accountTypeModel, "uid", "chuck");
assertAttribute(accountTypeModel, "givenName", "Chuck");
assertAttribute(accountTypeModel, "sn", "Norris");
assertAttribute(accountTypeModel, "cn", "Chuck Norris");
// TODO: check OpenDJ Account
}
/**
* Assigning accoun to user, account with the same identifier exist on the resource and there is also shadow in the repository. The account should be linked.
*/
@Test
public void test502AssignAccountToHerman() throws Exception {
final String TEST_NAME = "test502AssignAccountToHerman";
TestUtil.displayTestTile(this, TEST_NAME);
// GIVEN
openDJController.assumeRunning();
Task task = taskManager.createTaskInstance(ConsistencyTest.class.getName() + "." + TEST_NAME);
OperationResult result = task.getResult();
dummyAuditService.clear();
// Entry entry = openDJController.addEntryFromLdifFile(LDIF_MORGAN_FILENAME);
// display("Entry from LDIF", entry);
PrismObject<ShadowType> account = PrismTestUtil.parseObject(new File(ACCOUNT_HERMAN_FILENAME));
String accOid = provisioningService.addObject(account, null, null, task, result);
//
repoAddObjectFromFile(USER_HERMAN_FILENAME, result);
PrismObject<UserType> user = PrismTestUtil.parseObject(new File(USER_HERMAN_FILENAME));
display("Adding user", user);
//REQUEST_USER_MODIFY_ADD_ACCOUNT_COMMUNICATION_PROBLEM
requestToExecuteChanges(REQUEST_USER_MODIFY_ASSIGN_ACCOUNT, USER_HERMAN_OID, UserType.class, task, null, result);
// THEN
TestUtil.displayThen(TEST_NAME);
result.computeStatus();
// assertEquals("Expected handled error but got: " + result.getStatus(), OperationResultStatus.HANDLED_ERROR, result.getStatus());
PrismObject<UserType> userMorgan = modelService.getObject(UserType.class, USER_HERMAN_OID, null, task, result);
display("User morgan after", userMorgan);
UserType userMorganType = userMorgan.asObjectable();
assertEquals("Unexpected number of accountRefs", 1, userMorganType.getLinkRef().size());
ObjectReferenceType accountRefType = userMorganType.getLinkRef().get(0);
String accountOid = accountRefType.getOid();
assertFalse("No accountRef oid", StringUtils.isBlank(accountOid));
assertEquals("old oid not used..", accOid, accountOid);
assertEquals("old oid not used..", ACCOUNT_HERMAN_OID, accountOid);
// Check shadow
PrismObject<ShadowType> accountShadow = repositoryService.getObject(ShadowType.class, accountOid, null, result);
assertShadowRepo(accountShadow, accountOid, "uid=ht,ou=people,dc=example,dc=com", resourceTypeOpenDjrepo, RESOURCE_OPENDJ_ACCOUNT_OBJECTCLASS);
// Check account
PrismObject<ShadowType> accountModel = modelService.getObject(ShadowType.class, accountOid, null, task, result);
assertShadowModel(accountModel, accountOid, "uid=ht,ou=people,dc=example,dc=com", resourceTypeOpenDjrepo, RESOURCE_OPENDJ_ACCOUNT_OBJECTCLASS);
ShadowType accountTypeModel = accountModel.asObjectable();
// Check account's attributes
assertAttributes(accountTypeModel, "ht", "Herman", "Toothrot", "Herman Toothrot");
// TODO: check OpenDJ Account
}
/**
* Unlink account morgan, delete shadow and remove assignmnet from user morgan - preparation for the next test
*/
@Test
public void test510UnlinkAndUnassignAccountMorgan() throws Exception {
final String TEST_NAME = "test510UnlinkAndUnassignAccountMorgan";
TestUtil.displayTestTile(this, TEST_NAME);
// GIVEN
openDJController.assumeRunning();
Task task = taskManager.createTaskInstance(ConsistencyTest.class.getName() + "." + TEST_NAME);
OperationResult result = task.getResult();
dummyAuditService.clear();
PrismObject<UserType> user = repositoryService.getObject(UserType.class, USER_MORGAN_OID, null, result);
display("User Morgan: ", user);
List<PrismReferenceValue> linkRefs = user.findReference(UserType.F_LINK_REF).getValues();
assertEquals("Unexpected number of link refs", 1, linkRefs.size());
PrismReferenceValue linkRef = linkRefs.iterator().next();
ObjectDelta<UserType> userDelta = ObjectDelta.createModificationDeleteReference(UserType.class,
USER_MORGAN_OID, UserType.F_LINK_REF, prismContext, linkRef.clone());
Collection<ObjectDelta<? extends ObjectType>> deltas = MiscSchemaUtil.createCollection(userDelta);
// WHEN
TestUtil.displayWhen(TEST_NAME);
modelService.executeChanges(deltas, null, task, result);
///----user's link is removed, now, remove assignment
userDelta = ObjectDelta.createModificationDeleteContainer(UserType.class,
USER_MORGAN_OID, UserType.F_ASSIGNMENT, prismContext, user.findContainer(UserType.F_ASSIGNMENT).getValue().clone());
deltas = MiscSchemaUtil.createCollection(userDelta);
// WHEN
TestUtil.displayWhen(TEST_NAME);
modelService.executeChanges(deltas, null, task, result);
repositoryService.deleteObject(ShadowType.class, linkRef.getOid(), result);
// THEN
TestUtil.displayThen(TEST_NAME);
result.computeStatus();
// assertEquals("Expected handled error but got: " + result.getStatus(), OperationResultStatus.HANDLED_ERROR, result.getStatus());
PrismObject<UserType> userMorgan = modelService.getObject(UserType.class, USER_MORGAN_OID, null, task, result);
display("User morgan after", userMorgan);
UserType userMorganType = userMorgan.asObjectable();
assertEquals("Unexpected number of accountRefs", 0, userMorganType.getLinkRef().size());
// Check shadow
String accountOid = linkRef.getOid();
try {
PrismObject<ShadowType> accountShadow = repositoryService.getObject(ShadowType.class, accountOid, null, result);
assertAccountShadowRepo(accountShadow, accountOid, "uid=morgan,ou=people,dc=example,dc=com", resourceTypeOpenDjrepo);
fail("Unexpected shadow in repo. Shadow mut not exist");
} catch (ObjectNotFoundException ex){
//this is expected..shadow must not exist in repo
}
// Check account
try {
PrismObject<ShadowType> accountModel = modelService.getObject(ShadowType.class, accountOid, null, task, result);
assertAccountShadowModel(accountModel, accountOid, "uid=morgan,ou=people,dc=example,dc=com", resourceTypeOpenDjrepo);
fail("Unexpected shadow in repo. Shadow mut not exist");
} catch (ObjectNotFoundException ex){
//this is expected..shadow must not exist in repo
}
// TODO: check OpenDJ Account
}
/**
* assign account to the user morgan. Account with the same 'uid' (not dn, nut other secondary identifier already exists)
* account should be linked to the user.
* @throws Exception
*/
@Test
public void test511AssignAccountMorgan() throws Exception {
final String TEST_NAME = "test511AssignAccountMorgan";
TestUtil.displayTestTile(this, TEST_NAME);
// GIVEN
openDJController.assumeRunning();
Task task = taskManager.createTaskInstance(ConsistencyTest.class.getName() + "." + TEST_NAME);
OperationResult result = task.getResult();
dummyAuditService.clear();
//prepare new OU in opendj
Entry entry = openDJController.addEntryFromLdifFile(LDIF_CREATE_USERS_OU_FILENAME);
PrismObject<UserType> user = repositoryService.getObject(UserType.class, USER_MORGAN_OID, null, result);
display("User Morgan: ", user);
PrismReference linkRef = user.findReference(UserType.F_LINK_REF);
ExpressionType expression = new ExpressionType();
ObjectFactory of = new ObjectFactory();
RawType raw = new RawType(new PrimitiveXNode("uid=morgan,ou=users,dc=example,dc=com"), prismContext);
JAXBElement val = of.createValue(raw);
expression.getExpressionEvaluator().add(val);
MappingType mapping = new MappingType();
mapping.setExpression(expression);
ResourceAttributeDefinitionType attrDefType = new ResourceAttributeDefinitionType();
attrDefType.setRef(new ItemPathType(new ItemPath(getOpenDjSecondaryIdentifierQName())));
attrDefType.setOutbound(mapping);
ConstructionType construction = new ConstructionType();
construction.getAttribute().add(attrDefType);
construction.setResourceRef(ObjectTypeUtil.createObjectRef(resourceTypeOpenDjrepo));
AssignmentType assignment = new AssignmentType();
assignment.setConstruction(construction);
ObjectDelta<UserType> userDelta = ObjectDelta.createModificationAddContainer(UserType.class, USER_MORGAN_OID, UserType.F_ASSIGNMENT, prismContext, assignment.asPrismContainerValue());
Collection<ObjectDelta<? extends ObjectType>> deltas = MiscSchemaUtil.createCollection(userDelta);
// WHEN
TestUtil.displayWhen(TEST_NAME);
modelService.executeChanges(deltas, null, task, result);
// THEN
TestUtil.displayThen(TEST_NAME);
result.computeStatus();
// assertEquals("Expected handled error but got: " + result.getStatus(), OperationResultStatus.HANDLED_ERROR, result.getStatus());
PrismObject<UserType> userMorgan = modelService.getObject(UserType.class, USER_MORGAN_OID, null, task, result);
display("User morgan after", userMorgan);
UserType userMorganType = userMorgan.asObjectable();
assertEquals("Unexpected number of accountRefs", 1, userMorganType.getLinkRef().size());
String accountOid = userMorganType.getLinkRef().iterator().next().getOid();
// Check shadow
PrismObject<ShadowType> accountShadow = repositoryService.getObject(ShadowType.class, accountOid, null, result);
assertShadowRepo(accountShadow, accountOid, "uid=morgan,ou=people,dc=example,dc=com", resourceTypeOpenDjrepo, RESOURCE_OPENDJ_ACCOUNT_OBJECTCLASS);
// Check account
PrismObject<ShadowType> accountModel = modelService.getObject(ShadowType.class, accountOid, null, task, result);
assertShadowModel(accountModel, accountOid, "uid=morgan,ou=people,dc=example,dc=com", resourceTypeOpenDjrepo, RESOURCE_OPENDJ_ACCOUNT_OBJECTCLASS);
ResourceAttribute attributes = ShadowUtil.getAttribute(accountModel, new QName(resourceTypeOpenDjrepo.getNamespace(), "uid"));
assertEquals("morgan", attributes.getAnyRealValue());
// TODO: check OpenDJ Account
}
@Test
public void test600DeleteUserAlice() throws Exception {
String TEST_NAME = "test600DeleteUserAlice";
TestUtil.displayTestTile(TEST_NAME);
openDJController.assumeRunning();
Task task = taskManager.createTaskInstance(TEST_NAME);
OperationResult parentResult = task.getResult();
ObjectDelta<UserType> deleteAliceDelta = ObjectDelta.createDeleteDelta(UserType.class, USER_ALICE_OID, prismContext);
modelService.executeChanges(MiscSchemaUtil.createCollection(deleteAliceDelta), null, task, parentResult);
try {
modelService.getObject(UserType.class, USER_ALICE_OID, null, task, parentResult);
fail("Expected object not found error, but haven't got one. Something went wrong while deleting user alice");
} catch (ObjectNotFoundException ex){
//this is expected
}
}
@Test
public void test601GetDiscoveryModifyCommunicationProblemDirectAccount() throws Exception {
String TEST_NAME = "test601GetDiscoveryModifyCommunicationProblemDirectAccount";
TestUtil.displayTestTile(TEST_NAME);
openDJController.assumeRunning();
OperationResult parentResult = new OperationResult(TEST_NAME);
//prepare user
repoAddObjectFromFile(USER_ALICE_FILENAME, parentResult);
assertUserNoAccountRef(USER_ALICE_OID, parentResult);
Task task = taskManager.createTaskInstance();
//and add account to the user while resource is UP
//REQUEST_USER_MODIFY_ADD_ACCOUNT_COMMUNICATION_PROBLEM
requestToExecuteChanges(REQUEST_USER_MODIFY_ADD_ACCOUNT_DIRECTLY, USER_ALICE_OID, UserType.class, task, null, parentResult);
//then stop openDJ
openDJController.stop();
String accountOid = assertUserOneAccountRef(USER_ALICE_OID);
//and make some modifications to the account while resource is DOWN
requestToExecuteChanges(REQUEST_ACCOUNT_MODIFY_COMMUNICATION_PROBLEM, accountOid, ShadowType.class, task, null, parentResult);
//check the state after execution
checkPostponedAccountBasic(accountOid, FailedOperationTypeType.MODIFY, true, parentResult);
//start openDJ
openDJController.start();
//and set the resource availability status to UP
// modifyResourceAvailabilityStatus(AvailabilityStatusType.UP, parentResult);
ObjectDelta<UserType> emptyAliceDelta = ObjectDelta.createEmptyDelta(UserType.class, USER_ALICE_OID, prismContext, ChangeType.MODIFY);
modelService.executeChanges(MiscSchemaUtil.createCollection(emptyAliceDelta), ModelExecuteOptions.createReconcile(), task, parentResult);
accountOid = assertUserOneAccountRef(USER_ALICE_OID);
//and then try to get account -> result is that the modifications will be applied to the account
// ShadowType aliceAccount = checkNormalizedShadowWithAttributes(accountOid, "alice", "Jackkk", "alice", "alice", true, task, parentResult);
// assertAttribute(aliceAccount, resourceTypeOpenDjrepo, "employeeNumber", "emp4321");
//and finally stop openDJ
// openDJController.stop();
}
// This should run last. It starts a task that may interfere with other tests
@Test
public void test800Reconciliation() throws Exception {
final String TEST_NAME = "test800Reconciliation";
TestUtil.displayTestTile(this, TEST_NAME);
openDJController.assumeRunning();
final OperationResult result = new OperationResult(ConsistencyTest.class.getName() + "." + TEST_NAME);
// TODO: remove this if the previous test is enabled
// openDJController.start();
// rename eobject dirrectly on resource before the recon start ..it tests the rename + recon situation (MID-1594)
// precondition
assertTrue(EmbeddedUtils.isRunning());
UserType userJack = repositoryService.getObject(UserType.class, USER_JACK_OID, null, result).asObjectable();
display("Jack before", userJack);
LOGGER.info("start running task");
// WHEN
repoAddObjectFromFile(TASK_OPENDJ_RECONCILIATION_FILENAME, result);
verbose = true;
long started = System.currentTimeMillis();
waitForTaskNextRunAssertSuccess(TASK_OPENDJ_RECONCILIATION_OID, false, 120000);
LOGGER.info("Reconciliation task run took {} seconds", (System.currentTimeMillis()-started)/1000L);
// THEN
// STOP the task. We don't need it any more. Even if it's non-recurrent its safer to delete it
taskManager.deleteTask(TASK_OPENDJ_RECONCILIATION_OID, result);
// check if the account was added after reconciliation
UserType userE = repositoryService.getObject(UserType.class, USER_E_OID, null, result).asObjectable();
String accountOid = assertUserOneAccountRef(USER_E_OID);
ShadowType eAccount = checkNormalizedShadowWithAttributes(accountOid, "e", "Jackkk", "e", "e", true, null, result);
assertAttribute(eAccount, "employeeNumber", "emp4321");
ResourceAttributeContainer attributeContainer = ShadowUtil
.getAttributesContainer(eAccount);
Collection<ResourceAttribute<?>> identifiers = attributeContainer.getPrimaryIdentifiers();
assertNotNull(identifiers);
assertFalse(identifiers.isEmpty());
assertEquals(1, identifiers.size());
// check if the account was modified during reconciliation process
String jackAccountOid = assertUserOneAccountRef(USER_JACK_OID);
ShadowType modifiedAccount = checkNormalizedShadowBasic(jackAccountOid, "jack", true, SelectorOptions.createCollection(GetOperationOptions.createDoNotDiscovery()), null, result);
assertAttribute(modifiedAccount, "givenName", "Jackkk");
assertAttribute(modifiedAccount, "employeeNumber", "emp4321");
// check if the account was deleted during the reconciliation process
try {
modelService.getObject(ShadowType.class, ACCOUNT_DENIELS_OID, null, null, result);
fail("Expected ObjectNotFoundException but haven't got one.");
} catch (Exception ex) {
if (!(ex instanceof ObjectNotFoundException)) {
fail("Expected ObjectNotFoundException but got " + ex);
}
}
String elaineAccountOid = assertUserOneAccountRef(USER_ELAINE_OID);
modifiedAccount = checkNormalizedShadowBasic(elaineAccountOid, "elaine", true, SelectorOptions.createCollection(GetOperationOptions.createDoNotDiscovery()), null, result);
assertAttribute(modifiedAccount, getOpenDjSecondaryIdentifierQName(), "uid=elaine,ou=people,dc=example,dc=com");
accountOid = assertUserOneAccountRef(USER_JACK2_OID);
ShadowType jack2Shadow = checkNormalizedShadowBasic(accountOid, "jack2", true, SelectorOptions.createCollection(GetOperationOptions.createDoNotDiscovery()), null, result);
assertAttribute(jack2Shadow, "givenName", "jackNew2a");
assertAttribute(jack2Shadow, "cn", "jackNew2a");
}
@Test
public void test801TestReconciliationRename() throws Exception{
final String TEST_NAME = "test801TestReconciliationRename";
TestUtil.displayTestTile(this, TEST_NAME);
openDJController.assumeRunning();
final OperationResult result = new OperationResult(ConsistencyTest.class.getName() + "." + TEST_NAME);
LOGGER.info("starting rename");
openDJController.executeRenameChange(LDIF_MODIFY_RENAME_FILENAME);
LOGGER.info("rename ended");
// Entry res = openDJController.searchByUid("e");
// LOGGER.info("E OBJECT AFTER RENAME " + res.toString());
LOGGER.info("start running task");
// WHEN
long started = System.currentTimeMillis();
repoAddObjectFromFile(TASK_OPENDJ_RECONCILIATION_FILENAME, result);
waitForTaskFinish(TASK_OPENDJ_RECONCILIATION_OID, false, 120000);
LOGGER.info("Reconciliation task run took {} seconds", (System.currentTimeMillis()-started)/1000L);
// THEN
// STOP the task. We don't need it any more. Even if it's non-recurrent its safer to delete it
taskManager.deleteTask(TASK_OPENDJ_RECONCILIATION_OID, result);
// check if the account was added after reconciliation
UserType userE = repositoryService.getObject(UserType.class, USER_E_OID, null, result).asObjectable();
String accountOid = assertUserOneAccountRef(USER_E_OID);
ShadowType eAccount = checkNormalizedShadowWithAttributes(accountOid, "e123", "Jackkk", "e", "e", true, null, result);
assertAttribute(eAccount, "employeeNumber", "emp4321");
ResourceAttributeContainer attributeContainer = ShadowUtil
.getAttributesContainer(eAccount);
Collection<ResourceAttribute<?>> identifiers = attributeContainer.getPrimaryIdentifiers();
assertNotNull(identifiers);
assertFalse(identifiers.isEmpty());
assertEquals(1, identifiers.size());
ResourceAttribute icfNameAttr = attributeContainer.findAttribute(getOpenDjSecondaryIdentifierQName());
assertEquals("Wrong secondary indetifier.", "uid=e123,ou=people,dc=example,dc=com", icfNameAttr.getRealValue());
assertEquals("Wrong shadow name. ", "uid=e123,ou=people,dc=example,dc=com", eAccount.getName().getOrig());
PrismObject<ShadowType> repoShadow = repositoryService.getObject(ShadowType.class, accountOid, null, result);
provisioningService.applyDefinition(repoShadow, result);
ResourceAttributeContainer repoAttributeContainer = ShadowUtil.getAttributesContainer(repoShadow);
ResourceAttribute repoIcfNameAttr = repoAttributeContainer.findAttribute(getOpenDjSecondaryIdentifierQName());
assertEquals("Wrong secondary indetifier.", "uid=e123,ou=people,dc=example,dc=com", repoIcfNameAttr.getRealValue());
assertEquals("Wrong shadow name. ", "uid=e123,ou=people,dc=example,dc=com", repoShadow.asObjectable().getName().getOrig());
}
@Test
public void test999Shutdown() throws Exception {
taskManager.shutdown();
waitFor("waiting for task manager shutdown", new Checker() {
@Override
public boolean check() throws CommonException {
try {
return taskManager.getLocallyRunningTasks(new OperationResult("dummy")).isEmpty();
} catch (TaskManagerException e) {
throw new SystemException(e);
}
}
@Override
public void timeout() {
// No reaction, the test will fail right after return from this
}
}, 10000);
AssertJUnit.assertEquals("Some tasks left running after shutdown", new HashSet<Task>(),
taskManager.getLocallyRunningTasks(new OperationResult("dummy")));
}
private void checkRepoOpenDjResource() throws ObjectNotFoundException, SchemaException {
OperationResult result = new OperationResult(ConsistencyTest.class.getName()
+ ".checkRepoOpenDjResource");
PrismObject<ResourceType> resource = repositoryService.getObject(ResourceType.class,
RESOURCE_OPENDJ_OID, null, result);
checkOpenDjResource(resource.asObjectable(), "repository");
}
/**
* Checks if the resource is internally consistent, if it has everything it
* should have.
*
* @throws SchemaException
*/
private void checkOpenDjResource(ResourceType resource, String source) throws SchemaException {
assertNotNull("Resource from " + source + " is null", resource);
assertNotNull("Resource from " + source + " has null configuration", resource.getConnectorConfiguration());
assertNotNull("Resource from " + source + " has null schema", resource.getSchema());
checkOpenDjSchema(resource, source);
assertNotNull("Resource from " + source + " has null schemahandling", resource.getSchemaHandling());
assertNotNull("Resource from " + source + " has null capabilities", resource.getCapabilities());
if (!source.equals("repository")) {
// This is generated on the fly in provisioning
assertNotNull("Resource from " + source + " has null native capabilities",
resource.getCapabilities().getNative());
assertFalse("Resource from " + source + " has empty native capabilities", resource
.getCapabilities().getNative().getAny().isEmpty());
}
assertNotNull("Resource from " + source + " has null configured capabilities", resource.getCapabilities().getConfigured());
assertFalse("Resource from " + source + " has empty configured capabilities", resource.getCapabilities().getConfigured()
.getAny().isEmpty());
assertNotNull("Resource from " + source + " has null synchronization", resource.getSynchronization());
checkOpenDjConfiguration(resource.asPrismObject(), source);
}
private void checkOpenDjSchema(ResourceType resource, String source) throws SchemaException {
ResourceSchema schema = RefinedResourceSchemaImpl.getResourceSchema(resource, prismContext);
ObjectClassComplexTypeDefinition accountDefinition = schema.findObjectClassDefinition(RESOURCE_OPENDJ_ACCOUNT_OBJECTCLASS);
assertNotNull("Schema does not define any account (resource from " + source + ")", accountDefinition);
Collection<? extends ResourceAttributeDefinition> identifiers = accountDefinition.getPrimaryIdentifiers();
assertFalse("No account identifiers (resource from " + source + ")", identifiers == null
|| identifiers.isEmpty());
// TODO: check for naming attributes and display names, etc
ActivationCapabilityType capActivation = ResourceTypeUtil.getEffectiveCapability(resource,
ActivationCapabilityType.class);
if (capActivation != null && capActivation.getStatus() != null && capActivation.getStatus().getAttribute() != null) {
// There is simulated activation capability, check if the attribute is in schema.
QName enableAttrName = capActivation.getStatus().getAttribute();
ResourceAttributeDefinition enableAttrDef = accountDefinition.findAttributeDefinition(enableAttrName);
display("Simulated activation attribute definition", enableAttrDef);
assertNotNull("No definition for enable attribute " + enableAttrName + " in account (resource from " + source + ")", enableAttrDef);
assertTrue("Enable attribute " + enableAttrName + " is not ignored (resource from " + source + ")", enableAttrDef.isIgnored());
}
}
private void checkOpenDjConfiguration(PrismObject<ResourceType> resource, String source) {
checkOpenResourceConfiguration(resource, CONNECTOR_LDAP_NAMESPACE, "bindPassword", 8, source);
}
private void checkOpenResourceConfiguration(PrismObject<ResourceType> resource,
String connectorNamespace, String credentialsPropertyName, int numConfigProps, String source) {
PrismContainer<Containerable> configurationContainer = resource
.findContainer(ResourceType.F_CONNECTOR_CONFIGURATION);
assertNotNull("No configuration container in " + resource + " from " + source, configurationContainer);
PrismContainer<Containerable> configPropsContainer = configurationContainer
.findContainer(SchemaTestConstants.ICFC_CONFIGURATION_PROPERTIES);
assertNotNull("No configuration properties container in " + resource + " from " + source,
configPropsContainer);
List<? extends Item<?,?>> configProps = configPropsContainer.getValue().getItems();
assertEquals("Wrong number of config properties in " + resource + " from " + source, numConfigProps,
configProps.size());
PrismProperty<Object> credentialsProp = configPropsContainer.findProperty(new QName(
connectorNamespace, credentialsPropertyName));
if (credentialsProp == null) {
// The is the heisenbug we are looking for. Just dump the entire
// damn thing.
display("Configuration with the heisenbug", configurationContainer.debugDump());
}
assertNotNull("No credentials property in " + resource + " from " + source, credentialsProp);
assertEquals("Wrong number of credentials property value in " + resource + " from " + source, 1,
credentialsProp.getValues().size());
PrismPropertyValue<Object> credentialsPropertyValue = credentialsProp.getValues().iterator().next();
assertNotNull("No credentials property value in " + resource + " from " + source,
credentialsPropertyValue);
Object rawElement = credentialsPropertyValue.getRawElement();
}
private UserType testAddUserToRepo(String displayMessage, String fileName, String userOid)
throws IOException, ObjectNotFoundException, SchemaException, EncryptionException,
ObjectAlreadyExistsException, ExpressionEvaluationException, CommunicationException,
ConfigurationException, PolicyViolationException, SecurityViolationException {
checkRepoOpenDjResource();
assertNoRepoCache();
PrismObject<UserType> user = PrismTestUtil.parseObject(new File(fileName));
UserType userType = user.asObjectable();
PrismAsserts.assertParentConsistency(user);
protector.encrypt(userType.getCredentials().getPassword().getValue());
PrismAsserts.assertParentConsistency(user);
OperationResult result = new OperationResult("add user");
display("Adding user object", userType);
Task task = taskManager.createTaskInstance();
// WHEN
ObjectDelta delta = ObjectDelta.createAddDelta(user);
Collection<ObjectDelta<? extends ObjectType>> deltas = MiscSchemaUtil.createCollection(delta);
modelService.executeChanges(deltas, null, task, result);
// THEN
assertNoRepoCache();
return userType;
}
private String assertUserOneAccountRef(String userOid) throws Exception{
OperationResult parentResult = new OperationResult("getObject from repo");
PrismObject<UserType> repoUser = repositoryService.getObject(UserType.class, userOid,
null, parentResult);
UserType repoUserType = repoUser.asObjectable();
parentResult.computeStatus();
TestUtil.assertSuccess("getObject has failed", parentResult);
return assertOneAccountRef(repoUser);
}
private String assertOneAccountRef(PrismObject<UserType> user) throws Exception{
UserType repoUserType = user.asObjectable();
display("User (repository)", user);
List<ObjectReferenceType> accountRefs = repoUserType.getLinkRef();
assertEquals("No accountRefs", 1, accountRefs.size());
ObjectReferenceType accountRef = accountRefs.get(0);
return accountRef.getOid();
}
private void assertUserNoAccountRef(String userOid, OperationResult parentResult) throws Exception{
PrismObject<UserType> user = repositoryService
.getObject(UserType.class, userOid, null, parentResult);
assertEquals(0, user.asObjectable().getLinkRef().size());
}
private String checkRepoShadow(PrismObject<ShadowType> repoShadow) {
ShadowType repoShadowType = repoShadow.asObjectable();
String uid = null;
boolean hasOthers = false;
List<Object> xmlAttributes = repoShadowType.getAttributes().getAny();
for (Object element : xmlAttributes) {
if (getOpenDjPrimaryIdentifierQName().equals(JAXBUtil.getElementQName(element)) || getOpenDjPrimaryIdentifierQName().equals(JAXBUtil.getElementQName(element))) {
if (uid != null) {
AssertJUnit.fail("Multiple values for ICF UID in shadow attributes");
} else {
uid = ((Element) element).getTextContent();
}
} else if (SchemaConstants.ICFS_NAME.equals(JAXBUtil.getElementQName(element)) || getOpenDjSecondaryIdentifierQName().equals(JAXBUtil.getElementQName(element))) {
// This is OK
} else {
hasOthers = true;
}
}
assertFalse("Shadow "+repoShadow+" has unexpected elements", hasOthers);
assertNotNull(uid);
return uid;
}
private QName getOpenDjPrimaryIdentifierQName() {
return new QName(RESOURCE_OPENDJ_NS, RESOURCE_OPENDJ_PRIMARY_IDENTIFIER_LOCAL_NAME);
}
private QName getOpenDjSecondaryIdentifierQName() {
return new QName(RESOURCE_OPENDJ_NS, RESOURCE_OPENDJ_SECONDARY_IDENTIFIER_LOCAL_NAME);
}
private String checkUser(String userOid, Task task, OperationResult parentResult) throws Exception{
PrismObject<UserType> user = modelService.getObject(UserType.class, userOid, null, task, parentResult);
return checkUser(user);
}
private String checkRepoUser(String userOid, OperationResult parentResult) throws Exception{
PrismObject<UserType> user = repositoryService.getObject(UserType.class, userOid, null, parentResult);
return checkUser(user);
}
private String checkUser(PrismObject<UserType> user){
assertNotNull("User must not be null", user);
UserType userType = user.asObjectable();
assertEquals("User must have one link ref, ", 1, userType.getLinkRef().size());
MidPointAsserts.assertAssignments(user, 1);
String accountOid = userType.getLinkRef().get(0).getOid();
return accountOid;
}
private void checkAccount(String accountOid, String uid, String givenName, String sn, String cn, Task task, OperationResult parentResult) throws Exception{
PrismObject<ShadowType> newAccount = modelService.getObject(ShadowType.class, accountOid, null, task, parentResult);
assertNotNull("Shadow must not be null", newAccount);
ShadowType createdShadow = newAccount.asObjectable();
display("Created account: ", createdShadow);
AssertJUnit.assertNotNull(createdShadow);
AssertJUnit.assertEquals(RESOURCE_OPENDJ_OID, createdShadow.getResourceRef().getOid());
assertAttributeNotNull(createdShadow, getOpenDjPrimaryIdentifierQName());
assertAttributes(createdShadow, uid, givenName, sn, cn);
}
private void assertAttributes(ShadowType shadow, String uid, String givenName, String sn, String cn){
assertAttribute(shadow, "uid", uid);
if (givenName != null) {
assertAttribute(shadow, "givenName", givenName);
}
if (sn != null) {
assertAttribute(shadow, "sn", sn);
}
assertAttribute(shadow, "cn", cn);
}
private void checkPostponedAccountWithAttributes(String accountOid, String uid, String givenName, String sn, String cn, String employeeNumber, FailedOperationTypeType failedOperation, boolean modify, Task task, OperationResult parentResult) throws Exception{
ShadowType account = checkPostponedAccountWithAttributes(accountOid, uid, givenName, sn, cn, failedOperation, modify, task, parentResult);
display("account shadow (postponed operation)", account);
assertAttribute(account, "employeeNumber", employeeNumber);
}
private ShadowType checkPostponedAccountWithAttributes(String accountOid, String uid, String givenName, String sn, String cn, FailedOperationTypeType failedOperation, boolean modify, Task task, OperationResult parentResult) throws Exception{
ShadowType failedAccountType = checkPostponedAccountBasic(accountOid, failedOperation, modify, parentResult);
// assertNull(ResourceObjectShadowUtil.getAttributesContainer(faieldAccount).getIdentifier().getRealValue());
assertAttributes(failedAccountType, uid, givenName, sn, cn);
return failedAccountType;
}
private ShadowType checkPostponedAccountBasic(PrismObject<ShadowType> failedAccount, FailedOperationTypeType failedOperation, boolean modify, OperationResult parentResult) throws Exception{
display("Repository shadow (postponed operation expected)", failedAccount);
assertNotNull("Shadow must not be null", failedAccount);
ShadowType failedAccountType = failedAccount.asObjectable();
assertNotNull(failedAccountType);
// Too much noise
// displayJaxb("shadow from the repository: ", failedAccountType, ShadowType.COMPLEX_TYPE);
assertEquals("Failed operation saved with account differt from the expected value.",
failedOperation, failedAccountType.getFailedOperationType());
assertNotNull("Result of failed shadow must not be null.", failedAccountType.getResult());
assertNotNull("Shadow does not contain resource ref.", failedAccountType.getResourceRef());
assertEquals("Wrong resource ref in shadow", resourceTypeOpenDjrepo.getOid(), failedAccountType.getResourceRef().getOid());
if (modify){
assertNotNull("Null object change in shadow", failedAccountType.getObjectChange());
}
return failedAccountType;
}
private ShadowType checkPostponedAccountBasic(String accountOid, FailedOperationTypeType failedOperation, boolean modify, OperationResult parentResult) throws Exception{
PrismObject<ShadowType> faieldAccount = repositoryService.getObject(ShadowType.class, accountOid, null, parentResult);
return checkPostponedAccountBasic(faieldAccount, failedOperation, modify, parentResult);
}
private void requestToExecuteChanges(String requestFilename, String objectOid,
Class type, Task task, ModelExecuteOptions options, OperationResult parentResult)
throws Exception {
Collection<ObjectDelta<? extends ObjectType>> deltas = createDeltas(type, requestFilename, objectOid);
display("Executing deltas", deltas);
// WHEN
modelService.executeChanges(deltas, options, task, parentResult);
}
private Collection<ObjectDelta<? extends ObjectType>> createDeltas(Class type, String requestFilename, String objectOid) throws IOException, SchemaException, JAXBException{
try{
ObjectDeltaType objectChange = unmarshallValueFromFile(
requestFilename, ObjectDeltaType.class);
objectChange.setOid(objectOid);
ObjectDelta delta = DeltaConvertor.createObjectDelta(objectChange, prismContext);
Collection<ObjectDelta<? extends ObjectType>> deltas = MiscSchemaUtil.createCollection(delta);
return deltas;
} catch (Exception ex){
LOGGER.error("ERROR while unmarshalling: {}", ex);
throw ex;
}
}
private void modifyResourceAvailabilityStatus(AvailabilityStatusType status, OperationResult parentResult) throws Exception {
PropertyDelta resourceStatusDelta = PropertyDelta.createModificationReplaceProperty(new ItemPath(
ResourceType.F_OPERATIONAL_STATE, OperationalStateType.F_LAST_AVAILABILITY_STATUS),
resourceTypeOpenDjrepo.asPrismObject().getDefinition(), status);
Collection<PropertyDelta> modifications = new ArrayList<PropertyDelta>();
modifications.add(resourceStatusDelta);
repositoryService.modifyObject(ResourceType.class, resourceTypeOpenDjrepo.getOid(), modifications, parentResult);
}
private void checkNormalizedShadowWithAttributes(String accountOid, String uid, String givenName, String sn, String cn, String employeeType, boolean modify, Task task, OperationResult parentResult) throws Exception{
ShadowType resourceAccount = checkNormalizedShadowBasic(accountOid, uid, modify, null, task, parentResult);
assertAttributes(resourceAccount, uid, givenName, sn, cn);
assertAttribute(resourceAccount, "employeeType", employeeType);
}
private ShadowType checkNormalizedShadowWithAttributes(String accountOid, String uid, String givenName, String sn, String cn, boolean modify, Task task, OperationResult parentResult) throws Exception{
ShadowType resourceAccount = checkNormalizedShadowBasic(accountOid, uid, modify, null, task, parentResult);
assertAttributes(resourceAccount, uid, givenName, sn, cn);
return resourceAccount;
}
private ShadowType checkNormalizedShadowBasic(String accountOid, String name, boolean modify, Collection<SelectorOptions<GetOperationOptions>> options,Task task, OperationResult parentResult) throws Exception{
PrismObject<ShadowType> account = modelService.getObject(ShadowType.class, accountOid, options, task, parentResult);
assertNotNull(account);
ShadowType accountType = account.asObjectable();
display("Shadow after discovery", account);
assertNull(name + "'s account after discovery must not have failed opertion.", accountType.getFailedOperationType());
assertNull(name + "'s account after discovery must not have result.", accountType.getResult());
assertNotNull(name + "'s account must contain reference on the resource", accountType.getResourceRef());
assertEquals(resourceTypeOpenDjrepo.getOid(), accountType.getResourceRef().getOid());
if (modify){
assertNull(name + "'s account must not have object change", accountType.getObjectChange());
}
return accountType;
// assertNotNull("Identifier in the angelica's account after discovery must not be null.",ResourceObjectShadowUtil.getAttributesContainer(faieldAccount).getIdentifier().getRealValue());
}
protected <T> void assertAttribute(ShadowType shadowType, String attrName, T... expectedValues) {
assertAttribute(resourceTypeOpenDjrepo, shadowType, attrName, expectedValues);
}
protected <T> void assertAttribute(PrismObject<ShadowType> shadow, String attrName, T... expectedValues) {
assertAttribute(resourceTypeOpenDjrepo, shadow.asObjectable(), attrName, expectedValues);
}
protected <T> void assertAttribute(ShadowType shadowType, QName attrName, T... expectedValues) {
assertAttribute(resourceTypeOpenDjrepo, shadowType, attrName, expectedValues);
}
}