/* * Copyright (c) 2013-2017 Evolveum * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.evolveum.midpoint.provisioning.impl.dummy; import static com.evolveum.midpoint.test.IntegrationTestTools.display; import static org.testng.AssertJUnit.assertEquals; import static org.testng.AssertJUnit.assertNotNull; import java.io.File; import java.io.IOException; import java.util.List; import javax.xml.namespace.QName; import com.evolveum.midpoint.prism.PrismPropertyDefinitionImpl; import com.evolveum.midpoint.prism.query.builder.QueryBuilder; import com.evolveum.midpoint.schema.util.ObjectTypeUtil; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ContextConfiguration; import org.testng.annotations.Test; import com.evolveum.icf.dummy.resource.ConflictException; import com.evolveum.icf.dummy.resource.DummyAccount; import com.evolveum.icf.dummy.resource.SchemaViolationException; import com.evolveum.midpoint.prism.PrismObject; import com.evolveum.midpoint.prism.PrismPropertyDefinition; import com.evolveum.midpoint.prism.PrismPropertyValue; import com.evolveum.midpoint.prism.path.ItemPath; import com.evolveum.midpoint.prism.query.AndFilter; import com.evolveum.midpoint.prism.query.EqualFilter; import com.evolveum.midpoint.prism.query.ObjectFilter; import com.evolveum.midpoint.prism.query.ObjectQuery; import com.evolveum.midpoint.prism.query.RefFilter; import com.evolveum.midpoint.prism.util.PrismAsserts; import com.evolveum.midpoint.provisioning.impl.ProvisioningTestUtil; import com.evolveum.midpoint.schema.constants.SchemaConstants; import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.task.api.Task; import com.evolveum.midpoint.test.util.TestUtil; import com.evolveum.midpoint.util.DOMUtil; import com.evolveum.midpoint.util.exception.CommunicationException; import com.evolveum.midpoint.util.exception.ConfigurationException; import com.evolveum.midpoint.util.exception.ObjectAlreadyExistsException; import com.evolveum.midpoint.util.exception.ObjectNotFoundException; import com.evolveum.midpoint.util.exception.SchemaException; import com.evolveum.midpoint.util.exception.SecurityViolationException; import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowKindType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowType; /** * Almost the same as TestDummy but this is using a UUID as ICF UID. * * @author Radovan Semancik * */ @ContextConfiguration(locations = "classpath:ctx-provisioning-test-main.xml") @DirtiesContext public class TestDummyUuidNonUniqueName extends TestDummyUuid { public static final File TEST_DIR = new File("src/test/resources/impl/dummy-uuid-nonunique-name/"); public static final File RESOURCE_DUMMY_FILE = new File(TEST_DIR, "resource-dummy.xml"); public static final String ACCOUNT_FETTUCINI_NAME = "fettucini"; public static final File ACCOUNT_FETTUCINI_ALFREDO_FILE = new File(TEST_DIR, "account-alfredo-fettucini.xml"); public static final String ACCOUNT_FETTUCINI_ALFREDO_OID = "c0c010c0-d34d-b44f-f11d-444400009ffa"; public static final String ACCOUNT_FETTUCINI_ALFREDO_FULLNAME = "Alfredo Fettucini"; public static final File ACCOUNT_FETTUCINI_BILL_FILE = new File(TEST_DIR, "account-bill-fettucini.xml"); public static final String ACCOUNT_FETTUCINI_BILL_OID = "c0c010c0-d34d-b44f-f11d-444400009ffb"; public static final String ACCOUNT_FETTUCINI_BILL_FULLNAME = "Bill Fettucini"; public static final String ACCOUNT_FETTUCINI_CARLO_FULLNAME = "Carlo Fettucini"; @Override protected File getResourceDummyFilename() { return RESOURCE_DUMMY_FILE; } @Override protected boolean isNameUnique() { return false; } @Test public void test770AddAccountFettuciniAlfredo() throws Exception { final String TEST_NAME = "test770AddAccountFettuciniAlfredo"; TestUtil.displayTestTile(TEST_NAME); addFettucini(TEST_NAME, ACCOUNT_FETTUCINI_ALFREDO_FILE, ACCOUNT_FETTUCINI_ALFREDO_OID, ACCOUNT_FETTUCINI_ALFREDO_FULLNAME); searchFettucini(1); } @Test public void test772AddAccountFettuciniBill() throws Exception { final String TEST_NAME = "test772AddAccountFettuciniBill"; TestUtil.displayTestTile(TEST_NAME); addFettucini(TEST_NAME, ACCOUNT_FETTUCINI_BILL_FILE, ACCOUNT_FETTUCINI_BILL_OID, ACCOUNT_FETTUCINI_BILL_FULLNAME); searchFettucini(2); } /** * Add directly on resource. Therefore provisioning must create the shadow during search. */ @Test public void test774AddAccountFettuciniCarlo() throws Exception { final String TEST_NAME = "test774AddAccountFettuciniCarlo"; TestUtil.displayTestTile(TEST_NAME); dummyResourceCtl.addAccount(ACCOUNT_FETTUCINI_NAME, ACCOUNT_FETTUCINI_CARLO_FULLNAME); searchFettucini(3); } @Override @Test public void test600AddAccountAlreadyExist() throws Exception { // DO nothing. This test is meaningless in non-unique environment } private String addFettucini(final String TEST_NAME, File file, String oid, String expectedFullName) throws SchemaException, ObjectAlreadyExistsException, CommunicationException, ObjectNotFoundException, ConfigurationException, SecurityViolationException, IOException, SchemaViolationException, ConflictException { // GIVEN Task task = taskManager.createTaskInstance(TestDummy.class.getName() + "." + TEST_NAME); OperationResult result = new OperationResult(TestDummy.class.getName() + "." + TEST_NAME); syncServiceMock.reset(); PrismObject<ShadowType> account = prismContext.parseObject(file); account.checkConsistence(); display("Adding shadow", account); // WHEN String addedObjectOid = provisioningService.addObject(account, null, null, task, result); // THEN result.computeStatus(); display("add object result", result); TestUtil.assertSuccess("addObject has failed (result)", result); assertEquals(oid, addedObjectOid); account.checkConsistence(); PrismObject<ShadowType> accountRepo = repositoryService.getObject(ShadowType.class, oid, null, result); display("Account repo", accountRepo); ShadowType accountTypeRepo = accountRepo.asObjectable(); PrismAsserts.assertEqualsPolyString("Name not equal", ACCOUNT_FETTUCINI_NAME, accountTypeRepo.getName()); assertEquals("Wrong kind (repo)", ShadowKindType.ACCOUNT, accountTypeRepo.getKind()); assertAttribute(accountRepo, SchemaConstants.ICFS_NAME, ACCOUNT_FETTUCINI_NAME); String icfUid = getIcfUid(accountRepo); syncServiceMock.assertNotifySuccessOnly(); PrismObject<ShadowType> accountProvisioning = provisioningService.getObject(ShadowType.class, oid, null, task, result); display("Account provisioning", accountProvisioning); ShadowType accountTypeProvisioning = accountProvisioning.asObjectable(); display("account from provisioning", accountTypeProvisioning); PrismAsserts.assertEqualsPolyString("Name not equal", ACCOUNT_FETTUCINI_NAME, accountTypeProvisioning.getName()); assertEquals("Wrong kind (provisioning)", ShadowKindType.ACCOUNT, accountTypeProvisioning.getKind()); assertAttribute(accountProvisioning, SchemaConstants.ICFS_NAME, ACCOUNT_FETTUCINI_NAME); assertAttribute(accountProvisioning, SchemaConstants.ICFS_UID, icfUid); // Check if the account was created in the dummy resource DummyAccount dummyAccount = getDummyAccountAssert(ACCOUNT_FETTUCINI_NAME, icfUid); assertNotNull("No dummy account", dummyAccount); assertEquals("Fullname is wrong", expectedFullName, dummyAccount.getAttributeValue("fullname")); // Check if the shadow is still in the repo (e.g. that the consistency or sync haven't removed it) PrismObject<ShadowType> shadowFromRepo = repositoryService.getObject(ShadowType.class, addedObjectOid, null, result); assertNotNull("Shadow was not created in the repository", shadowFromRepo); display("Repository shadow", shadowFromRepo.debugDump()); ProvisioningTestUtil.checkRepoAccountShadow(shadowFromRepo); checkConsistency(accountProvisioning); assertSteadyResource(); return icfUid; } private void searchFettucini(int expectedNumberOfFettucinis) throws SchemaException, ObjectNotFoundException, CommunicationException, ConfigurationException, SecurityViolationException { OperationResult result = new OperationResult(TestDummy.class.getName() + ".searchFettucini"); ObjectQuery query = QueryBuilder.queryFor(ShadowType.class, prismContext) .item(ShadowType.F_RESOURCE_REF).ref(resource.getOid()) .and().item(ShadowType.F_OBJECT_CLASS).eq(new QName(dummyResourceCtl.getNamespace(), "AccountObjectClass")) .and().itemWithDef(getIcfNameDefinition(), ShadowType.F_ATTRIBUTES, getIcfNameDefinition().getName()).eq(ACCOUNT_FETTUCINI_NAME) .build(); // WHEN List<PrismObject<ShadowType>> shadows = provisioningService.searchObjects(ShadowType.class, query, null, null, result); assertEquals("Wrong number of Fettucinis found", expectedNumberOfFettucinis, shadows.size()); } private PrismPropertyDefinition<String> getIcfNameDefinition() { return new PrismPropertyDefinitionImpl<>(SchemaConstants.ICFS_NAME, DOMUtil.XSD_STRING, prismContext); } }