/*
* Copyright (c) 2010-2013 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.ItemDefinition;
import com.evolveum.midpoint.prism.Objectable;
import com.evolveum.midpoint.prism.PrismObject;
import com.evolveum.midpoint.prism.PrismReferenceValue;
import com.evolveum.midpoint.prism.delta.builder.DeltaBuilder;
import com.evolveum.midpoint.prism.path.ItemPath;
import com.evolveum.midpoint.prism.query.ObjectPaging;
import com.evolveum.midpoint.prism.query.ObjectQuery;
import com.evolveum.midpoint.prism.query.OrderDirection;
import com.evolveum.midpoint.prism.query.builder.QueryBuilder;
import com.evolveum.midpoint.prism.util.PrismTestUtil;
import com.evolveum.midpoint.schema.*;
import com.evolveum.midpoint.schema.constants.SchemaConstants;
import com.evolveum.midpoint.schema.result.OperationResult;
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.*;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ContextConfiguration;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import javax.xml.namespace.QName;
import java.io.File;
import java.util.*;
import static org.testng.AssertJUnit.assertEquals;
import static org.testng.AssertJUnit.assertTrue;
import static org.testng.AssertJUnit.fail;
/**
* @author lazyman
*/
@ContextConfiguration(locations = {"../../../../../ctx-test.xml"})
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
public class SearchTest extends BaseSQLRepoTest {
private static final Trace LOGGER = TraceManager.getTrace(SearchTest.class);
@BeforeClass
public void beforeClass() throws Exception {
super.beforeClass();
PrismTestUtil.resetPrismContext(MidPointPrismContextFactory.FACTORY);
FullTextSearchConfigurationType fullTextConfig = new FullTextSearchConfigurationType();
FullTextSearchIndexedItemsConfigurationType entry = new FullTextSearchIndexedItemsConfigurationType();
entry.getItem().add(new ItemPath(ObjectType.F_NAME).asItemPathType());
entry.getItem().add(new ItemPath(ObjectType.F_DESCRIPTION).asItemPathType());
fullTextConfig.getIndexed().add(entry);
repositoryService.applyFullTextSearchConfiguration(fullTextConfig);
LOGGER.info("Applying full text search configuration: {}", fullTextConfig);
List<PrismObject<? extends Objectable>> objects = prismContext.parserFor(new File(FOLDER_BASIC, "objects.xml")).parseObjects();
objects.addAll(prismContext.parserFor(new File(FOLDER_BASIC, "objects-2.xml")).parseObjects());
OperationResult result = new OperationResult("add objects");
for (PrismObject object : objects) {
repositoryService.addObject(object, null, result);
}
result.recomputeStatus();
assertTrue(result.isSuccess());
}
@Test
public void iterateEmptySet() throws Exception {
OperationResult result = new OperationResult("search empty");
ResultHandler handler = (object, parentResult) -> {
fail();
return false;
};
ObjectQuery query = QueryBuilder.queryFor(UserType.class, prismContext)
.item(UserType.F_NAME).eqPoly("asdf", "asdf").matchingStrict()
.build();
repositoryService.searchObjectsIterative(UserType.class, query, handler, null, false, result);
result.recomputeStatus();
assertTrue(result.isSuccess());
}
@Test
public void iterateSet() throws Exception {
OperationResult result = new OperationResult("search set");
final List<PrismObject> objects = new ArrayList<>();
ResultHandler handler = (object, parentResult) -> {
objects.add(object);
return true;
};
repositoryService.searchObjectsIterative(UserType.class, null, handler, null, false, result);
result.recomputeStatus();
assertTrue(result.isSuccess());
assertEquals(3, objects.size());
}
@Test
public void iterateSetWithPaging() throws Exception {
iterateGeneral(0, 2, 2, "atestuserX00002", "atestuserX00003");
iterateGeneral(0, 2, 1, "atestuserX00002", "atestuserX00003");
iterateGeneral(0, 1, 10, "atestuserX00002");
iterateGeneral(0, 1, 1, "atestuserX00002");
iterateGeneral(1, 1, 1, "atestuserX00003");
}
private void iterateGeneral(int offset, int size, int batch, final String... names) throws Exception {
OperationResult result = new OperationResult("search general");
final List<PrismObject> objects = new ArrayList<PrismObject>();
ResultHandler handler = new ResultHandler() {
int index = 0;
@Override
public boolean handle(PrismObject object, OperationResult parentResult) {
objects.add(object);
assertEquals("Incorrect object name was read", names[index++], object.asObjectable().getName().getOrig());
return true;
}
};
SqlRepositoryConfiguration config = ((SqlRepositoryServiceImpl) repositoryService).getConfiguration();
int oldbatch = config.getIterativeSearchByPagingBatchSize();
config.setIterativeSearchByPagingBatchSize(batch);
LOGGER.trace(">>>>>> iterateGeneral: offset = " + offset + ", size = " + size + ", batch = " + batch + " <<<<<<");
ObjectQuery query = new ObjectQuery();
query.setPaging(ObjectPaging.createPaging(offset, size, ObjectType.F_NAME, OrderDirection.ASCENDING));
repositoryService.searchObjectsIterative(UserType.class, query, handler, null, false, result);
result.recomputeStatus();
config.setIterativeSearchByPagingBatchSize(oldbatch);
assertTrue(result.isSuccess());
assertEquals(size, objects.size());
}
@Test
public void caseSensitiveSearchTest() throws Exception {
final String existingNameOrig = "Test UserX00003";
final String nonExistingNameOrig = "test UserX00003";
final String nameNorm = "test userx00003";
ObjectQuery query = QueryBuilder.queryFor(UserType.class, prismContext)
.item(UserType.F_FULL_NAME).eqPoly(existingNameOrig, nameNorm).matchingOrig()
.build();
OperationResult result = new OperationResult("search");
List<PrismObject<UserType>> users = repositoryService.searchObjects(UserType.class, query, null, result);
result.recomputeStatus();
assertTrue(result.isSuccess());
assertEquals("Should find one user", 1, users.size());
query = QueryBuilder.queryFor(UserType.class, prismContext)
.item(UserType.F_FULL_NAME).eqPoly(nonExistingNameOrig, nameNorm).matchingOrig()
.build();
users = repositoryService.searchObjects(UserType.class, query, null, result);
result.recomputeStatus();
assertTrue(result.isSuccess());
assertEquals("Found user (shouldn't) because case insensitive search was used", 0, users.size());
}
@Test
public void roleMembershipSearchTest() throws Exception {
PrismReferenceValue r456 = new PrismReferenceValue("r456", RoleType.COMPLEX_TYPE);
r456.setRelation(SchemaConstants.ORG_DEFAULT);
ObjectQuery query = QueryBuilder.queryFor(UserType.class, prismContext)
.item(UserType.F_ROLE_MEMBERSHIP_REF).ref(r456)
.build();
OperationResult result = new OperationResult("search");
List<PrismObject<UserType>> users = repositoryService.searchObjects(UserType.class, query, null, result);
result.recomputeStatus();
assertTrue(result.isSuccess());
assertEquals("Should find one user", 1, users.size());
assertEquals("Wrong user name", "atestuserX00003", users.get(0).getName().getOrig());
PrismReferenceValue r123 = new PrismReferenceValue("r123", RoleType.COMPLEX_TYPE);
query = QueryBuilder.queryFor(UserType.class, prismContext)
.item(UserType.F_ROLE_MEMBERSHIP_REF).ref(r123)
.build();
users = repositoryService.searchObjects(UserType.class, query, null, result);
result.recomputeStatus();
assertTrue(result.isSuccess());
assertEquals("Should find two users", 2, users.size());
PrismReferenceValue r123approver = new PrismReferenceValue("r123", RoleType.COMPLEX_TYPE);
r123approver.setRelation(SchemaConstants.ORG_APPROVER);
query = QueryBuilder.queryFor(UserType.class, prismContext)
.item(UserType.F_ROLE_MEMBERSHIP_REF).ref(r123approver)
.build();
users = repositoryService.searchObjects(UserType.class, query, null, result);
result.recomputeStatus();
assertTrue(result.isSuccess());
assertEquals("Should find no users", 0, users.size());
}
@Test
public void delegatedSearchTest() throws Exception {
PrismReferenceValue r789 = new PrismReferenceValue("r789", RoleType.COMPLEX_TYPE);
// intentionally without relation (meaning "member")
ObjectQuery query = QueryBuilder.queryFor(UserType.class, prismContext)
.item(UserType.F_DELEGATED_REF).ref(r789)
.build();
OperationResult result = new OperationResult("search");
List<PrismObject<UserType>> users = repositoryService.searchObjects(UserType.class, query, null, result);
result.recomputeStatus();
assertTrue(result.isSuccess());
assertEquals("Should find one user", 1, users.size());
assertEquals("Wrong user name", "atestuserX00003", users.get(0).getName().getOrig());
PrismReferenceValue r123 = new PrismReferenceValue("r123", RoleType.COMPLEX_TYPE);
query = QueryBuilder.queryFor(UserType.class, prismContext)
.item(UserType.F_DELEGATED_REF).ref(r123)
.build();
users = repositoryService.searchObjects(UserType.class, query, null, result);
result.recomputeStatus();
assertTrue(result.isSuccess());
assertEquals("Should find no users", 0, users.size());
}
@Test
public void personaSearchTest() throws Exception {
PrismReferenceValue u000 = new PrismReferenceValue("u000", UserType.COMPLEX_TYPE);
ObjectQuery query = QueryBuilder.queryFor(UserType.class, prismContext)
.item(UserType.F_PERSONA_REF).ref(u000)
.build();
OperationResult result = new OperationResult("search");
List<PrismObject<UserType>> users = repositoryService.searchObjects(UserType.class, query, null, result);
result.recomputeStatus();
assertTrue(result.isSuccess());
assertEquals("Should find one user", 1, users.size());
assertEquals("Wrong user name", "atestuserX00003", users.get(0).getName().getOrig());
PrismReferenceValue r789 = new PrismReferenceValue("r789", RoleType.COMPLEX_TYPE);
query = QueryBuilder.queryFor(UserType.class, prismContext)
.item(UserType.F_PERSONA_REF).ref(r789)
.build();
users = repositoryService.searchObjects(UserType.class, query, null, result);
result.recomputeStatus();
assertTrue(result.isSuccess());
assertEquals("Should find no users", 0, users.size());
}
@Test
public void assignmentOrgRefSearchTest() throws Exception {
PrismReferenceValue o123456 = new PrismReferenceValue("o123456", OrgType.COMPLEX_TYPE);
ObjectQuery query = QueryBuilder.queryFor(UserType.class, prismContext)
.item(UserType.F_ASSIGNMENT, AssignmentType.F_ORG_REF).ref(o123456)
.build();
OperationResult result = new OperationResult("search");
List<PrismObject<UserType>> users = repositoryService.searchObjects(UserType.class, query, null, result);
result.recomputeStatus();
assertTrue(result.isSuccess());
assertEquals("Should find one user", 1, users.size());
assertEquals("Wrong user name", "atestuserX00002", users.get(0).getName().getOrig());
PrismReferenceValue o999 = new PrismReferenceValue("o999", RoleType.COMPLEX_TYPE);
query = QueryBuilder.queryFor(UserType.class, prismContext)
.item(UserType.F_ASSIGNMENT, AssignmentType.F_ORG_REF).ref(o999)
.build();
users = repositoryService.searchObjects(UserType.class, query, null, result);
result.recomputeStatus();
assertTrue(result.isSuccess());
assertEquals("Should find zero users", 0, users.size());
}
@Test
public void assignmentResourceRefSearchTest() throws Exception {
PrismReferenceValue resourceRef = new PrismReferenceValue("10000000-0000-0000-0000-000000000004", ResourceType.COMPLEX_TYPE);
ObjectQuery query = QueryBuilder.queryFor(RoleType.class, prismContext)
.item(RoleType.F_ASSIGNMENT, AssignmentType.F_CONSTRUCTION, ConstructionType.F_RESOURCE_REF).ref(resourceRef)
.build();
OperationResult result = new OperationResult("search");
List<PrismObject<RoleType>> roles = repositoryService.searchObjects(RoleType.class, query, null, result);
result.recomputeStatus();
assertTrue(result.isSuccess());
assertEquals("Should find one role", 1, roles.size());
assertEquals("Wrong role name", "Judge", roles.get(0).getName().getOrig());
PrismReferenceValue resourceRef2 = new PrismReferenceValue("FFFFFFFF-0000-0000-0000-000000000004", ResourceType.COMPLEX_TYPE);
query = QueryBuilder.queryFor(RoleType.class, prismContext)
.item(RoleType.F_ASSIGNMENT, AssignmentType.F_CONSTRUCTION, ConstructionType.F_RESOURCE_REF).ref(resourceRef2)
.build();
roles = repositoryService.searchObjects(RoleType.class, query, null, result);
result.recomputeStatus();
assertTrue(result.isSuccess());
assertEquals("Should find zero roles", 0, roles.size());
}
@Test
public void roleAssignmentSearchTest() throws Exception {
PrismReferenceValue r456 = new PrismReferenceValue("r123", RoleType.COMPLEX_TYPE);
ObjectQuery query = QueryBuilder.queryFor(UserType.class, prismContext)
.item(UserType.F_ASSIGNMENT, AssignmentType.F_TARGET_REF).ref(r456)
.build();
OperationResult result = new OperationResult("search");
List<PrismObject<UserType>> users = repositoryService.searchObjects(UserType.class, query, null, result);
result.recomputeStatus();
assertTrue(result.isSuccess());
assertEquals("Should find one user", 1, users.size());
assertEquals("Wrong user name", "atestuserX00002", users.get(0).getName().getOrig());
}
@Test
public void orgAssignmentSearchTest() throws Exception {
PrismReferenceValue org = new PrismReferenceValue("00000000-8888-6666-0000-100000000085", OrgType.COMPLEX_TYPE);
ObjectQuery query = QueryBuilder.queryFor(UserType.class, prismContext)
.item(UserType.F_ASSIGNMENT, AssignmentType.F_TARGET_REF).ref(org)
.build();
OperationResult result = new OperationResult("search");
List<PrismObject<UserType>> users = repositoryService.searchObjects(UserType.class, query, null, result);
result.recomputeStatus();
assertTrue(result.isSuccess());
assertEquals("Should find one user", 1, users.size());
assertEquals("Wrong user name", "atestuserX00002", users.get(0).getName().getOrig());
}
@Test
public void roleAndOrgAssignmentSearchTest() throws Exception {
PrismReferenceValue r123 = new PrismReferenceValue("r123", RoleType.COMPLEX_TYPE);
PrismReferenceValue org = new PrismReferenceValue("00000000-8888-6666-0000-100000000085", OrgType.COMPLEX_TYPE);
ObjectQuery query = QueryBuilder.queryFor(UserType.class, prismContext)
.item(UserType.F_ASSIGNMENT, AssignmentType.F_TARGET_REF).ref(r123)
.and().item(UserType.F_ASSIGNMENT, AssignmentType.F_TARGET_REF).ref(org)
.build();
OperationResult result = new OperationResult("search");
List<PrismObject<UserType>> users = repositoryService.searchObjects(UserType.class, query, null, result);
result.recomputeStatus();
assertTrue(result.isSuccess());
assertEquals("Should find one user", 1, users.size());
assertEquals("Wrong user name", "atestuserX00002", users.get(0).getName().getOrig());
}
@Test
public void notBusinessRoleTypeSearchTest() throws Exception {
ObjectQuery query = QueryBuilder.queryFor(RoleType.class, prismContext)
.not().item(RoleType.F_ROLE_TYPE).eq("business")
.build();
OperationResult result = new OperationResult("search");
List<PrismObject<RoleType>> roles = repositoryService.searchObjects(RoleType.class, query, null, result);
result.recomputeStatus();
assertTrue(result.isSuccess());
assertEquals("Should find two roles", 2, roles.size());
int judge = roles.get(0).getName().getOrig().startsWith("J") ? 0 : 1;
assertEquals("Wrong role1 name", "Judge", roles.get(judge).getName().getOrig());
assertEquals("Wrong role2 name", "Admin-owned role", roles.get(1-judge).getName().getOrig());
}
@Test
public void businessRoleTypeSearchTest() throws Exception {
ObjectQuery query = QueryBuilder.queryFor(RoleType.class, prismContext)
.item(RoleType.F_ROLE_TYPE).eq("business")
.build();
OperationResult result = new OperationResult("search");
List<PrismObject<RoleType>> roles = repositoryService.searchObjects(RoleType.class, query, null, result);
result.recomputeStatus();
assertTrue(result.isSuccess());
assertEquals("Should find one role", 1, roles.size());
assertEquals("Wrong role name", "Pirate", roles.get(0).getName().getOrig());
}
@Test
public void emptyRoleTypeSearchTest() throws Exception {
ObjectQuery query = QueryBuilder.queryFor(RoleType.class, prismContext)
.item(RoleType.F_ROLE_TYPE).isNull()
.build();
OperationResult result = new OperationResult("search");
List<PrismObject<RoleType>> roles = repositoryService.searchObjects(RoleType.class, query, null, result);
result.recomputeStatus();
assertTrue(result.isSuccess());
assertEquals("Should find two roles", 2, roles.size());
int judge = roles.get(0).getName().getOrig().startsWith("J") ? 0 : 1;
assertEquals("Wrong role1 name", "Judge", roles.get(judge).getName().getOrig());
assertEquals("Wrong role2 name", "Admin-owned role", roles.get(1-judge).getName().getOrig());
}
@Test
public void nonEmptyRoleTypeSearchTest() throws Exception {
ObjectQuery query = QueryBuilder.queryFor(RoleType.class, prismContext)
.not().item(RoleType.F_ROLE_TYPE).isNull()
.build();
OperationResult result = new OperationResult("search");
List<PrismObject<RoleType>> roles = repositoryService.searchObjects(RoleType.class, query, null, result);
result.recomputeStatus();
assertTrue(result.isSuccess());
assertEquals("Should find one role", 1, roles.size());
assertEquals("Wrong role name", "Pirate", roles.get(0).getName().getOrig());
}
@Test
public void testIndividualOwnerRef() throws Exception {
testOwnerRef(RoleType.class, SystemObjectsType.USER_ADMINISTRATOR.value(), "Admin-owned role");
testOwnerRef(RoleType.class, null, "Judge", "Pirate");
testOwnerRef(RoleType.class, "123");
testOwnerRef(OrgType.class, SystemObjectsType.USER_ADMINISTRATOR.value(), "Admin-owned org");
testOwnerRef(OrgType.class, null, "F0085");
testOwnerRef(OrgType.class, "123");
testOwnerRef(TaskType.class, SystemObjectsType.USER_ADMINISTRATOR.value(), "Synchronization: Embedded Test OpenDJ");
testOwnerRef(TaskType.class, null, "Task with no owner");
testOwnerRef(TaskType.class, "123");
testOwnerRef(AccessCertificationCampaignType.class, SystemObjectsType.USER_ADMINISTRATOR.value(), "All user assignments 1");
testOwnerRef(AccessCertificationCampaignType.class, null, "No-owner campaign");
testOwnerRef(AccessCertificationCampaignType.class, "123");
testOwnerRef(AccessCertificationDefinitionType.class, SystemObjectsType.USER_ADMINISTRATOR.value(), "Admin-owned definition");
testOwnerRef(AccessCertificationDefinitionType.class, null);
testOwnerRef(AccessCertificationDefinitionType.class, "123");
}
@Test
public void testOwnerRefWithTypeRestriction() throws Exception {
testOwnerRefWithTypeRestriction(RoleType.class, SystemObjectsType.USER_ADMINISTRATOR.value(), "Admin-owned role");
testOwnerRefWithTypeRestriction(RoleType.class, null, "Judge", "Pirate");
testOwnerRefWithTypeRestriction(RoleType.class, "123");
testOwnerRefWithTypeRestriction(OrgType.class, SystemObjectsType.USER_ADMINISTRATOR.value(), "Admin-owned org");
testOwnerRefWithTypeRestriction(OrgType.class, null, "F0085");
testOwnerRefWithTypeRestriction(OrgType.class, "123");
testOwnerRefWithTypeRestriction(TaskType.class, SystemObjectsType.USER_ADMINISTRATOR.value(), "Synchronization: Embedded Test OpenDJ");
testOwnerRefWithTypeRestriction(TaskType.class, null, "Task with no owner");
testOwnerRefWithTypeRestriction(TaskType.class, "123");
testOwnerRefWithTypeRestriction(AccessCertificationCampaignType.class, SystemObjectsType.USER_ADMINISTRATOR.value(), "All user assignments 1");
testOwnerRefWithTypeRestriction(AccessCertificationCampaignType.class, null, "No-owner campaign");
testOwnerRefWithTypeRestriction(AccessCertificationCampaignType.class, "123");
testOwnerRefWithTypeRestriction(AccessCertificationDefinitionType.class, SystemObjectsType.USER_ADMINISTRATOR.value(), "Admin-owned definition");
testOwnerRefWithTypeRestriction(AccessCertificationDefinitionType.class, null);
testOwnerRefWithTypeRestriction(AccessCertificationDefinitionType.class, "123");
}
private void testOwnerRef(Class<? extends ObjectType> clazz, String oid, String... names) throws SchemaException {
ObjectQuery query = QueryBuilder.queryFor(clazz, prismContext)
.item(new QName(SchemaConstants.NS_C, "ownerRef")).ref(oid)
.build();
checkResult(clazz, clazz, oid, query, names);
}
private void testOwnerRefWithTypeRestriction(Class<? extends ObjectType> clazz, String oid, String... names) throws SchemaException {
ObjectQuery query = QueryBuilder.queryFor(ObjectType.class, prismContext)
.type(clazz)
.item(new QName(SchemaConstants.NS_C, "ownerRef")).ref(oid)
.build();
checkResult(ObjectType.class, clazz, oid, query, names);
}
private void checkResult(Class<? extends ObjectType> queryClass, Class<? extends ObjectType> realClass, String oid, ObjectQuery query, String[] names)
throws SchemaException {
OperationResult result = new OperationResult("search");
SearchResultList<? extends PrismObject<? extends ObjectType>> objects = repositoryService.searchObjects(queryClass, query, null, result);
System.out.println(realClass.getSimpleName() + " owned by " + oid + ": " + objects.size());
assertEquals("Wrong # of found objects", names.length, objects.size());
Set<String> expectedNames = new HashSet<>(Arrays.asList(names));
Set<String> realNames = new HashSet<>();
for (PrismObject<? extends ObjectType> object : objects) {
realNames.add(object.asObjectable().getName().getOrig());
}
assertEquals("Wrong names of found objects", expectedNames, realNames);
}
@Test
public void testWildOwnerRef() throws SchemaException {
final String oid = SystemObjectsType.USER_ADMINISTRATOR.value();
ItemDefinition<?> ownerRefDef = prismContext.getSchemaRegistry().findObjectDefinitionByCompileTimeClass(RoleType.class).findItemDefinition(RoleType.F_OWNER_REF);
ObjectQuery query = QueryBuilder.queryFor(ObjectType.class, prismContext)
.item(new ItemPath(new QName(SchemaConstants.NS_C, "ownerRef")), ownerRefDef).ref(oid)
.build();
OperationResult result = new OperationResult("search");
try {
repositoryService.searchObjects(ObjectType.class, query, null, result);
fail("Ambiguous searchObjects succeeded even if it should have failed.");
} catch (SystemException e) {
assertTrue("Wrong exception message: " + e.getMessage(), e.getMessage().contains("Unable to determine root entity for ownerRef"));
}
}
@Test
public void testResourceUp() throws SchemaException {
ObjectQuery query = QueryBuilder.queryFor(ResourceType.class, prismContext)
.item(ResourceType.F_OPERATIONAL_STATE, OperationalStateType.F_LAST_AVAILABILITY_STATUS).eq(AvailabilityStatusType.UP)
.build();
OperationResult result = new OperationResult("search");
List<PrismObject<ResourceType>> resources = repositoryService.searchObjects(ResourceType.class, query, null, result);
result.recomputeStatus();
assertTrue(result.isSuccess());
assertEquals("Should find one resource", 1, resources.size());
}
@Test
public void testMultivaluedExtensionPropertySubstringQualified() throws SchemaException {
ObjectQuery query = QueryBuilder.queryFor(GenericObjectType.class, prismContext)
.item(ObjectType.F_EXTENSION, new QName("http://example.com/p", "multivalued")).contains("slava")
.build();
OperationResult result = new OperationResult("search");
List<PrismObject<GenericObjectType>> resources = repositoryService.searchObjects(GenericObjectType.class, query, null, result);
result.recomputeStatus();
assertTrue(result.isSuccess());
assertEquals("Should find one object", 1, resources.size());
}
@Test
public void testMultivaluedExtensionPropertyEqualsQualified() throws SchemaException {
ObjectQuery query = QueryBuilder.queryFor(GenericObjectType.class, prismContext)
.item(ObjectType.F_EXTENSION, new QName("http://example.com/p", "multivalued")).eq("Bratislava")
.build();
OperationResult result = new OperationResult("search");
List<PrismObject<GenericObjectType>> resources = repositoryService.searchObjects(GenericObjectType.class, query, null, result);
result.recomputeStatus();
assertTrue(result.isSuccess());
assertEquals("Should find one object", 1, resources.size());
}
@Test
public void testMultivaluedExtensionPropertySubstringUnqualified() throws SchemaException {
ObjectQuery query = QueryBuilder.queryFor(GenericObjectType.class, prismContext)
.item(ObjectType.F_EXTENSION, new QName("multivalued")).contains("slava")
.build();
OperationResult result = new OperationResult("search");
List<PrismObject<GenericObjectType>> resources = repositoryService.searchObjects(GenericObjectType.class, query, null, result);
result.recomputeStatus();
assertTrue(result.isSuccess());
assertEquals("Should find one object", 1, resources.size());
}
@Test
public void testMultivaluedExtensionPropertyEqualsUnqualified() throws SchemaException {
ObjectQuery query = QueryBuilder.queryFor(GenericObjectType.class, prismContext)
.item(ObjectType.F_EXTENSION, new QName("multivalued")).eq("Bratislava")
.build();
OperationResult result = new OperationResult("search");
List<PrismObject<GenericObjectType>> resources = repositoryService.searchObjects(GenericObjectType.class, query, null, result);
result.recomputeStatus();
assertTrue(result.isSuccess());
assertEquals("Should find one object", 1, resources.size());
}
@Test
public void testRoleAttributes() throws SchemaException {
ObjectQuery query = QueryBuilder.queryFor(RoleType.class, prismContext)
.item(RoleType.F_RISK_LEVEL).eq("critical")
.and().item(RoleType.F_IDENTIFIER).eq("123")
.and().item(RoleType.F_DISPLAY_NAME).eqPoly("The honest one", "").matchingOrig()
.build();
OperationResult result = new OperationResult("search");
List<PrismObject<RoleType>> roles = repositoryService.searchObjects(RoleType.class, query, null, result);
result.recomputeStatus();
assertTrue(result.isSuccess());
assertEquals("Should find one object", 1, roles.size());
}
// testing MID-3568
@Test
public void caseInsensitiveSearchTest() throws Exception {
final String existingNameNorm = "test userx00003";
final String existingNameOrig = "Test UserX00003";
final String emailLowerCase = "testuserx00003@example.com";
final String emailVariousCase = "TeStUsErX00003@EXAmPLE.com";
assertUsersFound(QueryBuilder.queryFor(UserType.class, prismContext)
.item(UserType.F_FULL_NAME).eqPoly(existingNameNorm).matchingNorm()
.build(),
false, 1);
assertUsersFound(QueryBuilder.queryFor(UserType.class, prismContext)
.item(UserType.F_FULL_NAME).eqPoly(existingNameOrig).matchingNorm()
.build(),
false, 1);
assertUsersFound(QueryBuilder.queryFor(UserType.class, prismContext)
.item(UserType.F_EMAIL_ADDRESS).eq(emailLowerCase).matchingCaseIgnore()
.build(),
false, 1);
assertUsersFound(QueryBuilder.queryFor(UserType.class, prismContext)
.item(UserType.F_EMAIL_ADDRESS).eq(emailVariousCase).matchingCaseIgnore()
.build(),
false, 1);
// comparing polystrings, but providing plain String
assertUsersFound(QueryBuilder.queryFor(UserType.class, prismContext)
.item(UserType.F_FULL_NAME).eq(existingNameNorm).matchingNorm()
.build(),
false, 1);
assertUsersFound(QueryBuilder.queryFor(UserType.class, prismContext)
.item(UserType.F_FULL_NAME).eq(existingNameOrig).matchingNorm()
.build(),
false, 1);
assertUsersFound(QueryBuilder.queryFor(UserType.class, prismContext)
.item(UserType.F_FULL_NAME).containsPoly(existingNameNorm).matchingNorm()
.build(),
false, 1);
assertUsersFound(QueryBuilder.queryFor(UserType.class, prismContext)
.item(UserType.F_FULL_NAME).containsPoly(existingNameOrig).matchingNorm()
.build(),
false, 1);
assertUsersFound(QueryBuilder.queryFor(UserType.class, prismContext)
.item(UserType.F_EMAIL_ADDRESS).contains(emailLowerCase).matchingCaseIgnore()
.build(),
false, 1);
assertUsersFound(QueryBuilder.queryFor(UserType.class, prismContext)
.item(UserType.F_EMAIL_ADDRESS).contains(emailVariousCase).matchingCaseIgnore()
.build(),
false, 1);
// comparing polystrings, but providing plain String
assertUsersFound(QueryBuilder.queryFor(UserType.class, prismContext)
.item(UserType.F_FULL_NAME).contains(existingNameNorm).matchingNorm()
.build(),
false, 1);
assertUsersFound(QueryBuilder.queryFor(UserType.class, prismContext)
.item(UserType.F_FULL_NAME).contains(existingNameOrig).matchingNorm()
.build(),
false, 1);
}
@Test
public void fullTextSearch() throws Exception {
OperationResult result = new OperationResult("fullTextSearch");
Collection<SelectorOptions<GetOperationOptions>> distinct = distinct();
assertUsersFound(QueryBuilder.queryFor(UserType.class, prismContext)
.fullText("atestuserX00003")
.build(),
false, 1);
List<PrismObject<UserType>> users = assertUsersFound(QueryBuilder.queryFor(UserType.class, prismContext)
.fullText("Pellentesque")
.build(),
true, 1);
assertUsersFound(QueryBuilder.queryFor(UserType.class, prismContext)
.fullText("sollicitudin")
.build(),
true, 0);
String newDescription = "\n"
+ "\t\t\tUt pellentesque massa elit, in varius justo pellentesque ac. Vivamus gravida lectus non odio tempus iaculis sed quis\n"
+ "\t\t\tenim. Praesent sed ante nunc. Etiam euismod urna sit amet mi commodo luctus. Morbi dictum suscipit mauris ac\n"
+ "\t\t\tfacilisis. Phasellus congue luctus nibh, eu gravida sem iaculis in. Fusce bibendum quam sit amet tortor venenatis\n"
+ "\t\t\tmalesuada. Nam non varius nibh. Ut porta sit amet dui ut mollis. Etiam tincidunt ex viverra purus condimentum\n"
+ "\t\t\tinterdum. Sed ornare lacinia finibus. Pellentesque ac tortor scelerisque, sagittis diam nec, vehicula ligula.\n"
+ "\t\t\tPhasellus sodales felis quis fermentum volutpat. Orci varius natoque penatibus et magnis dis parturient montes,\n"
+ "\t\t\tnascetur ridiculus mus. Suspendisse mattis efficitur ligula et pharetra. Morbi risus erat, mollis nec suscipit vel,\n"
+ "\t\t\tconvallis eu ex.\n"
+ "\n"
+ "\t\t\tPellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Curabitur cursus\n"
+ "\t\t\tplacerat nisl, quis egestas ante semper at. Aenean semper nulla in elit tincidunt fringilla. Proin tristique sapien ac\n"
+ "\t\t\tenim blandit, a faucibus dui maximus. Curabitur sodales eget nulla eget mattis. Sed mollis blandit sapien. Aenean\n"
+ "\t\t\tpulvinar condimentum condimentum. Ut et venenatis arcu. Nam a nisl at nibh aliquam luctus. Phasellus eleifend non\n"
+ "\t\t\ttellus eget varius.\n"
+ "\n"
+ "\t\t\tNunc tincidunt sed lacus congue iaculis. Donec vel orci nulla. Phasellus fringilla, erat ac elementum lacinia, ex enim\n"
+ "\t\t\tdictum magna, accumsan dignissim elit mauris vel quam. Fusce vel tellus magna. Quisque sed tellus lectus. Donec id\n"
+ "\t\t\tnibh a lorem rutrum pharetra. Vestibulum vehicula leo ac eros pulvinar, eget tristique purus porta. Aliquam cursus\n"
+ "\t\t\tturpis sed libero eleifend interdum. Sed ac nisi a turpis finibus consectetur. Sed a velit vel nisi semper commodo.\n"
+ "\t\t\tVestibulum vel pulvinar ligula, vitae rutrum leo. Sed efficitur dignissim augue in placerat. Aliquam dapibus mauris\n"
+ "\t\t\teget diam pharetra molestie. Morbi vitae nulla sollicitudin, dignissim tellus a, tincidunt neque.\n";
LOGGER.info("## changing description ##");
repositoryService.modifyObject(UserType.class, users.get(0).getOid(),
DeltaBuilder.deltaFor(UserType.class, prismContext)
.item(UserType.F_DESCRIPTION).replace(newDescription)
.asItemDeltas(),
result);
// just to see SQL used
LOGGER.info("## changing telephoneNumber ##");
repositoryService.modifyObject(UserType.class, users.get(0).getOid(),
DeltaBuilder.deltaFor(UserType.class, prismContext)
.item(UserType.F_TELEPHONE_NUMBER).replace("123456")
.asItemDeltas(),
result);
assertUsersFoundBySearch(QueryBuilder.queryFor(UserType.class, prismContext)
.fullText("sollicitudin")
.build(),
distinct, 1);
assertUsersFoundBySearch(QueryBuilder.queryFor(UserType.class, prismContext)
.fullText("sollicitudin")
.asc(UserType.F_FULL_NAME)
.maxSize(100)
.build(),
distinct, 1);
}
private Collection<SelectorOptions<GetOperationOptions>> distinct() {
return SelectorOptions.createCollection(GetOperationOptions.createDistinct());
}
@Test
public void testShadowPendingOperation() throws SchemaException {
ObjectQuery query = QueryBuilder.queryFor(ShadowType.class, prismContext)
.exists(ShadowType.F_PENDING_OPERATION)
.build();
OperationResult result = new OperationResult("search");
List<PrismObject<ShadowType>> shadows = repositoryService.searchObjects(ShadowType.class, query, null, result);
result.recomputeStatus();
assertTrue(result.isSuccess());
assertEquals("Should find one object", 1, shadows.size());
}
@SuppressWarnings("SameParameterValue")
private List<PrismObject<UserType>> assertUsersFound(ObjectQuery query, boolean distinct, int expectedCount) throws Exception {
Collection<SelectorOptions<GetOperationOptions>> options = distinct ? distinct() : null;
assertObjectsFoundByCount(query, options, expectedCount);
return assertUsersFoundBySearch(query, options, expectedCount);
}
private List<PrismObject<UserType>> assertUsersFoundBySearch(ObjectQuery query,
Collection<SelectorOptions<GetOperationOptions>> options, int expectedCount) throws Exception {
OperationResult result = new OperationResult("search");
List<PrismObject<UserType>> users = repositoryService.searchObjects(UserType.class, query, options, result);
result.recomputeStatus();
assertTrue(result.isSuccess());
assertEquals("Wrong # of results found: " + query, expectedCount, users.size());
return users;
}
private void assertObjectsFoundByCount(ObjectQuery query, Collection<SelectorOptions<GetOperationOptions>> options,
int expectedCount) throws Exception {
OperationResult result = new OperationResult("count");
int count = repositoryService.countObjects(UserType.class, query, options, result);
result.recomputeStatus();
assertTrue(result.isSuccess());
assertEquals("Wrong # of results found: " + query, expectedCount, count);
}
@Test
public void testOperationExecutionAny() throws SchemaException {
ObjectQuery query = QueryBuilder.queryFor(CaseType.class, prismContext)
.item(ObjectType.F_OPERATION_EXECUTION, OperationExecutionType.F_STATUS).eq(OperationResultStatusType.FATAL_ERROR)
.build();
OperationResult result = new OperationResult("search");
List<PrismObject<CaseType>> cases = repositoryService.searchObjects(CaseType.class, query, null, result);
result.recomputeStatus();
assertTrue(result.isSuccess());
assertEquals("Should find one object", 1, cases.size());
}
@Test
public void testOperationExecutionWithTask() throws SchemaException {
ObjectQuery query = QueryBuilder.queryFor(CaseType.class, prismContext)
.exists(ObjectType.F_OPERATION_EXECUTION)
.block()
.item(OperationExecutionType.F_TASK_REF).ref("task-oid-2")
.and().item(OperationExecutionType.F_STATUS).eq(OperationResultStatusType.SUCCESS)
.endBlock()
.build();
OperationResult result = new OperationResult("search");
List<PrismObject<CaseType>> cases = repositoryService.searchObjects(CaseType.class, query, null, result);
result.recomputeStatus();
assertTrue(result.isSuccess());
assertEquals("Should find one object", 1, cases.size());
}
@Test
public void testOperationExecutionWithTask2() throws SchemaException {
ObjectQuery query = QueryBuilder.queryFor(CaseType.class, prismContext)
.exists(ObjectType.F_OPERATION_EXECUTION)
.block()
.item(OperationExecutionType.F_TASK_REF).ref("task-oid-2")
.and().item(OperationExecutionType.F_STATUS).eq(OperationResultStatusType.FATAL_ERROR)
.endBlock()
.build();
OperationResult result = new OperationResult("search");
List<PrismObject<CaseType>> cases = repositoryService.searchObjects(CaseType.class, query, null, result);
result.recomputeStatus();
assertTrue(result.isSuccess());
assertEquals("Should find no object", 0, cases.size());
}
@Test
public void testExtensionReference() throws SchemaException {
ObjectQuery query = QueryBuilder.queryFor(GenericObjectType.class, prismContext)
.item(ObjectType.F_EXTENSION, new QName("referenceType"))
.ref("12345678-1234-1234-1234-123456789012")
.build();
OperationResult result = new OperationResult("search");
List<PrismObject<GenericObjectType>> cases = repositoryService.searchObjects(GenericObjectType.class, query, null, result);
result.recomputeStatus();
assertTrue(result.isSuccess());
assertEquals("Should find 1 object", 1, cases.size());
}
@Test
public void testExtensionReferenceNotMatching() throws SchemaException {
ObjectQuery query = QueryBuilder.queryFor(GenericObjectType.class, prismContext)
.item(ObjectType.F_EXTENSION, new QName("referenceType"))
.ref("12345678-1234-1234-1234-123456789xxx")
.build();
OperationResult result = new OperationResult("search");
List<PrismObject<GenericObjectType>> cases = repositoryService.searchObjects(GenericObjectType.class, query, null, result);
result.recomputeStatus();
assertTrue(result.isSuccess());
assertEquals("Should find no object", 0, cases.size());
}
@Test
public void testExtensionReferenceNull() throws SchemaException {
ObjectQuery query = QueryBuilder.queryFor(GenericObjectType.class, prismContext)
.item(ObjectType.F_EXTENSION, new QName("referenceType"))
.isNull()
.build();
OperationResult result = new OperationResult("search");
List<PrismObject<GenericObjectType>> cases = repositoryService.searchObjects(GenericObjectType.class, query, null, result);
result.recomputeStatus();
assertTrue(result.isSuccess());
assertEquals("Should find no object", 0, cases.size());
}
@Test
public void testExtensionReferenceNonNull() throws SchemaException {
ObjectQuery query = QueryBuilder.queryFor(GenericObjectType.class, prismContext)
.not().item(ObjectType.F_EXTENSION, new QName("referenceType"))
.isNull()
.build();
OperationResult result = new OperationResult("search");
List<PrismObject<GenericObjectType>> cases = repositoryService.searchObjects(GenericObjectType.class, query, null, result);
result.recomputeStatus();
assertTrue(result.isSuccess());
assertEquals("Should find 1 object", 1, cases.size());
}
}