/* * Copyright (c) 2010-2015 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.repo.sql; import com.evolveum.midpoint.prism.PrismObject; import com.evolveum.midpoint.prism.polystring.PolyString; import com.evolveum.midpoint.prism.util.PrismTestUtil; import com.evolveum.midpoint.schema.MidPointPrismContextFactory; import com.evolveum.midpoint.schema.ResultHandler; import com.evolveum.midpoint.schema.result.OperationResult; 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.SystemException; import com.evolveum.midpoint.util.logging.Trace; import com.evolveum.midpoint.util.logging.TraceManager; import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType; import com.evolveum.prism.xml.ns._public.types_3.PolyStringType; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ContextConfiguration; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; import java.util.ArrayList; import java.util.List; import static org.testng.AssertJUnit.assertEquals; import static org.testng.AssertJUnit.assertFalse; import static org.testng.AssertJUnit.assertTrue; /** * @author mederly */ @ContextConfiguration(locations = {"../../../../../ctx-test.xml"}) @DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS) public class SearchIterativeTest extends BaseSQLRepoTest { private static final Trace LOGGER = TraceManager.getTrace(SearchIterativeTest.class); private static final int BASE = 100000; private static final int COUNT = 500; @BeforeClass public void beforeClass() throws Exception { super.beforeClass(); PrismTestUtil.resetPrismContext(MidPointPrismContextFactory.FACTORY); createObjects(); } protected void createObjects() throws com.evolveum.midpoint.util.exception.ObjectAlreadyExistsException, com.evolveum.midpoint.util.exception.SchemaException { OperationResult result = new OperationResult("add objects"); for (int i = BASE; i < BASE + COUNT; i++) { UserType user = prismContext.getSchemaRegistry().findObjectDefinitionByCompileTimeClass(UserType.class).instantiate().asObjectable(); user.setOid("user-" + i + "-00"); user.setName(new PolyStringType(new PolyString("user-"+i))); user.setCostCenter(String.valueOf(i)); repositoryService.addObject(user.asPrismObject(), null, result); } result.recomputeStatus(); assertTrue(result.isSuccess()); } @Test public void test100SimpleIteration() throws Exception { OperationResult result = new OperationResult("test100SimpleIteration"); final List<PrismObject<UserType>> objects = new ArrayList<>(); ResultHandler handler = new ResultHandler() { @Override public boolean handle(PrismObject object, OperationResult parentResult) { objects.add(object); return true; } }; repositoryService.searchObjectsIterative(UserType.class, null, handler, null, true, result); result.recomputeStatus(); assertTrue(result.isSuccess()); assertObjects(objects, COUNT); } @Test public void test105SimpleIterationNoSequence() throws Exception { OperationResult result = new OperationResult("test105SimpleIterationNoSequence"); final List<PrismObject<UserType>> objects = new ArrayList<>(); ResultHandler handler = new ResultHandler() { @Override public boolean handle(PrismObject object, OperationResult parentResult) { objects.add(object); return true; } }; repositoryService.searchObjectsIterative(UserType.class, null, handler, null, false, result); result.recomputeStatus(); assertTrue(result.isSuccess()); assertObjects(objects, COUNT); } private boolean[] assertObjects(List<PrismObject<UserType>> objects, Integer count) { if (count != null) { assertEquals("Wrong # of objects", count.intValue(), objects.size()); } boolean[] numbers = new boolean[COUNT]; for (PrismObject<UserType> user : objects) { UserType userType = user.asObjectable(); int number = Integer.parseInt(userType.getCostCenter()) - BASE; if (number >= 0) { if (numbers[number]) { throw new IllegalStateException("User number " + number + " was processed more than once"); } else { numbers[number] = true; } } } return numbers; } @Test public void test110DeleteAll() throws Exception { OperationResult result = new OperationResult("test110DeleteAll"); final List<PrismObject<UserType>> objects = new ArrayList<>(); ResultHandler handler = new ResultHandler() { @Override public boolean handle(PrismObject object, OperationResult parentResult) { objects.add(object); try { repositoryService.deleteObject(UserType.class, object.getOid(), parentResult); } catch (ObjectNotFoundException e) { throw new SystemException(e); } return true; } }; repositoryService.searchObjectsIterative(UserType.class, null, handler, null, true, result); result.recomputeStatus(); assertTrue(result.isSuccess()); assertObjects(objects, COUNT); int count = repositoryService.countObjects(UserType.class, null, result); assertEquals("Wrong # of objects after operation", 0, count); } @Test public void test120DeleteHalf() throws Exception { OperationResult result = new OperationResult("test120DeleteHalf"); createObjects(); final List<PrismObject<UserType>> objects = new ArrayList<>(); ResultHandler handler = new ResultHandler() { @Override public boolean handle(PrismObject object, OperationResult parentResult) { objects.add(object); try { int number = Integer.parseInt(((UserType) object.asObjectable()).getCostCenter()); if (number % 2 == 0) { repositoryService.deleteObject(UserType.class, object.getOid(), parentResult); } } catch (ObjectNotFoundException e) { throw new SystemException(e); } return true; } }; repositoryService.searchObjectsIterative(UserType.class, null, handler, null, true, result); result.recomputeStatus(); assertTrue(result.isSuccess()); assertObjects(objects, COUNT); int count = repositoryService.countObjects(UserType.class, null, result); assertEquals("Wrong # of objects after operation", COUNT/2, count); } @Test public void test130AddOneForOne() throws Exception { OperationResult result = new OperationResult("test130AddOneForOne"); final List<PrismObject<UserType>> objects = new ArrayList<>(); ResultHandler handler = new ResultHandler() { @Override public boolean handle(PrismObject object, OperationResult parentResult) { objects.add(object); System.out.print("Got object " + object.getOid()); try { int number = Integer.parseInt(((UserType) object.asObjectable()).getCostCenter()); if (number >= 0) { UserType user = prismContext.getSchemaRegistry().findObjectDefinitionByCompileTimeClass(UserType.class).instantiate().asObjectable(); user.setOid("user-" + (2*BASE + COUNT - number) + "-FF"); user.setName(new PolyStringType(new PolyString("user-new-" + number))); user.setCostCenter(String.valueOf(-number)); repositoryService.addObject(user.asPrismObject(), null, parentResult); System.out.print(" ... creating object " + user.getOid()); } } catch (ObjectAlreadyExistsException|SchemaException e) { throw new SystemException(e); } System.out.println(); return true; } }; repositoryService.searchObjectsIterative(UserType.class, null, handler, null, true, result); result.recomputeStatus(); assertTrue(result.isSuccess()); boolean[] map = assertObjects(objects, null); for (int i = 0; i < COUNT; i++) { if (i % 2 == 0) { assertFalse("Object " + (BASE+i) + " does exist but it should not", map[i]); } else { assertTrue("Object " + (BASE+i) + " does not exist but it should", map[i]); } } System.out.println("Object processed: " + objects.size()); int count = repositoryService.countObjects(UserType.class, null, result); assertEquals("Wrong # of objects after operation", COUNT, count); } }