Skip to content

Commit

Permalink
Tests for association shortcut, support for additional connector capa…
Browse files Browse the repository at this point in the history
…bilities (paging), support for allowPartialResults.
  • Loading branch information
semancik committed Mar 17, 2015
1 parent 7e0f53e commit 77ba61b
Show file tree
Hide file tree
Showing 10 changed files with 293 additions and 8 deletions.
Expand Up @@ -45,6 +45,8 @@ public class InternalMonitor {
private static boolean traceConnectorOperation = false;
private static long connectorOperationCount = 0;

private static long connectorSimulatedPagingSearchCount = 0;

private static long shadowFetchOperationCount = 0;
private static boolean traceShadowFetchOperation = false;

Expand Down Expand Up @@ -181,7 +183,18 @@ public static long getConnectorOperationCount() {
public static void recordConnectorOperation(String name) {
connectorOperationCount++;
if (traceConnectorOperation) {
traceOperation("connector "+name, shadowFetchOperationCount);
traceOperation("connector "+name, connectorOperationCount);
}
}

public static long getConnectorSimulatedPagingSearchCount() {
return connectorSimulatedPagingSearchCount;
}

public static void recordConnectorSimulatedPagingSearchCount() {
connectorSimulatedPagingSearchCount++;
if (traceConnectorOperation) {
traceOperation("simulated paged search", connectorSimulatedPagingSearchCount);
}
}

Expand Down
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2010-2013 Evolveum
* 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.
Expand Down Expand Up @@ -30,6 +30,7 @@ public class ObjectQuery implements DebugDumpable, Serializable {

private ObjectFilter filter;
private ObjectPaging paging;
private boolean allowPartialResults = false;

public ObjectFilter getFilter() {
return filter;
Expand All @@ -47,6 +48,14 @@ public ObjectPaging getPaging() {
return paging;
}

public boolean isAllowPartialResults() {
return allowPartialResults;
}

public void setAllowPartialResults(boolean allowPartialResults) {
this.allowPartialResults = allowPartialResults;
}

public static ObjectQuery createObjectQuery(ObjectFilter filter) {
ObjectQuery query = new ObjectQuery();
query.setFilter(filter);
Expand Down Expand Up @@ -119,6 +128,12 @@ public String debugDump(int indent) {
sb.append("paging: ").append(paging.debugDump(0));
}

if (allowPartialResults) {
sb.append("\n");
DebugUtil.indentDebugDump(sb, indent);
sb.append("Allow partial results");
}

return sb.toString();
}

Expand All @@ -138,6 +153,9 @@ public String toString() {
} else {
sb.append("null paging");
}
if (allowPartialResults) {
sb.append(",partial");
}
return sb.toString();
}

Expand Down
Expand Up @@ -72,6 +72,7 @@
import org.identityconnectors.framework.common.objects.ConnectorObject;
import org.identityconnectors.framework.common.objects.ObjectClass;
import org.identityconnectors.framework.common.objects.ObjectClassInfo;
import org.identityconnectors.framework.common.objects.OperationOptionInfo;
import org.identityconnectors.framework.common.objects.OperationOptions;
import org.identityconnectors.framework.common.objects.OperationOptionsBuilder;
import org.identityconnectors.framework.common.objects.OperationalAttributes;
Expand Down Expand Up @@ -166,6 +167,7 @@
import com.evolveum.midpoint.xml.ns._public.resource.capabilities_3.ActivationLockoutStatusCapabilityType;
import com.evolveum.midpoint.xml.ns._public.resource.capabilities_3.ActivationStatusCapabilityType;
import com.evolveum.midpoint.xml.ns._public.resource.capabilities_3.ActivationValidityCapabilityType;
import com.evolveum.midpoint.xml.ns._public.resource.capabilities_3.CapabilityType;
import com.evolveum.midpoint.xml.ns._public.resource.capabilities_3.CreateCapabilityType;
import com.evolveum.midpoint.xml.ns._public.resource.capabilities_3.CredentialsCapabilityType;
import com.evolveum.midpoint.xml.ns._public.resource.capabilities_3.DeleteCapabilityType;
Expand Down Expand Up @@ -898,6 +900,29 @@ private void parseResourceSchema(org.identityconnectors.framework.common.objects
}
capabilities.add(capabilityObjectFactory.createScript(capScript));
}

boolean canPageSize = false;
boolean canPageOffset = false;
boolean canSort = false;
for (OperationOptionInfo searchOption: icfSchema.getSupportedOptionsByOperation(SearchApiOp.class)) {
switch (searchOption.getName()) {
case OperationOptions.OP_PAGE_SIZE:
canPageSize = true;
break;
case OperationOptions.OP_PAGED_RESULTS_OFFSET:
canPageOffset = true;
break;
case OperationOptions.OP_SORT_KEYS:
canSort = true;
break;
}

}

if (canPageSize || canPageOffset || canSort) {
PagedSearchCapabilityType capPage = new PagedSearchCapabilityType();
capabilities.add(capabilityObjectFactory.createPagedSearch(capPage));
}

}

Expand Down Expand Up @@ -932,6 +957,18 @@ private boolean shouldBeGenerated(List<QName> generateObjectClasses,

return false;
}

private <C extends CapabilityType> C getCapability(Class<C> capClass) {
if (capabilities == null) {
return null;
}
for (Object cap: capabilities) {
if (capClass.isAssignableFrom(cap.getClass())) {
return (C) cap;
}
}
return null;
}

@Override
public <T extends ShadowType> PrismObject<T> fetchObject(Class<T> type,
Expand Down Expand Up @@ -981,6 +1018,7 @@ public <T extends ShadowType> PrismObject<T> fetchObject(Class<T> type,
if (attributesToGet != null) {
optionsBuilder.setAttributesToGet(attributesToGet);
}
optionsBuilder.setAllowPartialResults(true);
OperationOptions options = optionsBuilder.build();

ConnectorObject co = null;
Expand Down Expand Up @@ -1927,7 +1965,15 @@ public <T extends ShadowType> SearchResultMetadata search(ObjectClassComplexType
}
final PrismObjectDefinition<T> objectDefinition = toShadowDefinition(objectClassDefinition);

if (pagedSearchCapabilityType == null) {
pagedSearchCapabilityType = getCapability(PagedSearchCapabilityType.class);
}

final boolean useConnectorPaging = pagedSearchCapabilityType != null;
if (!useConnectorPaging && query.getPaging() != null &&
(query.getPaging().getOffset() != null || query.getPaging().getMaxSize() != null)) {
InternalMonitor.recordConnectorSimulatedPagingSearchCount();
}

final Holder<Integer> countHolder = new Holder<>(0);

Expand Down Expand Up @@ -1971,6 +2017,9 @@ public boolean handle(ConnectorObject connectorObject) {
if (attributesToGet != null) {
optionsBuilder.setAttributesToGet(attributesToGet);
}
if (query != null && query.isAllowPartialResults()) {
optionsBuilder.setAllowPartialResults(query.isAllowPartialResults());
}
// preparing paging-related options
if (useConnectorPaging && query != null && query.getPaging() != null) {
ObjectPaging paging = query.getPaging();
Expand Down Expand Up @@ -2065,7 +2114,7 @@ public boolean handle(ConnectorObject connectorObject) {
return metadata;
}

@Override
@Override
public int count(ObjectClassComplexTypeDefinition objectClassDefinition, final ObjectQuery query,
PagedSearchCapabilityType pagedSearchCapabilityType, OperationResult parentResult)
throws CommunicationException, GenericFrameworkException, SchemaException, UnsupportedOperationException {
Expand Down
Expand Up @@ -116,6 +116,7 @@
import com.evolveum.midpoint.xml.ns._public.resource.capabilities_3.CreateCapabilityType;
import com.evolveum.midpoint.xml.ns._public.resource.capabilities_3.CredentialsCapabilityType;
import com.evolveum.midpoint.xml.ns._public.resource.capabilities_3.DeleteCapabilityType;
import com.evolveum.midpoint.xml.ns._public.resource.capabilities_3.PagedSearchCapabilityType;
import com.evolveum.midpoint.xml.ns._public.resource.capabilities_3.ReadCapabilityType;
import com.evolveum.midpoint.xml.ns._public.resource.capabilities_3.ScriptCapabilityType;
import com.evolveum.midpoint.xml.ns._public.resource.capabilities_3.ScriptCapabilityType.Host;
Expand Down Expand Up @@ -330,6 +331,9 @@ public void test005Capabilities() throws ObjectNotFoundException, CommunicationE
capAct = ResourceTypeUtil.getEffectiveCapability(resource, ActivationCapabilityType.class);
assertNotNull("activation capability not found",capAct);

PagedSearchCapabilityType capPage = ResourceTypeUtil.getEffectiveCapability(resource, PagedSearchCapabilityType.class);
assertNotNull("paged search capability not present", capPage);

assertShadows(1);
}

Expand Down Expand Up @@ -1307,6 +1311,9 @@ public void test201SearchObjects() throws Exception {
QueryType queryType = PrismTestUtil.parseAtomicValue(new File("src/test/resources/impl/query-filter-all-accounts.xml"),
QueryType.COMPLEX_TYPE);
ObjectQuery query = QueryJaxbConvertor.createObjectQuery(ShadowType.class, queryType, prismContext);

rememberConnectorOperationCount();
rememberConnectorSimulatedPagingSearchCount();

// WHEN
List<PrismObject<ShadowType>> searchResults =
Expand All @@ -1318,6 +1325,9 @@ public void test201SearchObjects() throws Exception {
display("Search resutls", searchResults);

assertEquals("Unexpected number of search results", 14, searchResults.size());

assertConnectorOperationIncrement(1);
assertConnectorSimulatedPagingSearchIncrement(0);
}

@Test
Expand All @@ -1331,16 +1341,24 @@ public void test202SearchObjectsCompexFilter() throws Exception {
QueryType.COMPLEX_TYPE);
ObjectQuery query = QueryJaxbConvertor.createObjectQuery(ShadowType.class, queryType, prismContext);

rememberConnectorOperationCount();
rememberConnectorSimulatedPagingSearchCount();

// WHEN
List<PrismObject<ShadowType>> objListType =
provisioningService.searchObjects(ShadowType.class, query, null, result);

// THEN
for (PrismObject<ShadowType> objType : objListType) {
if (objType == null) {
System.out.println("Object not found in repository.");
} else {
System.out.println("found object: " + objType.asObjectable().getName());
}
}

assertConnectorOperationIncrement(1);
assertConnectorSimulatedPagingSearchIncrement(0);
}

@Test
Expand All @@ -1356,6 +1374,9 @@ public void test230SearchObjectsPagedNoOffset() throws Exception {

ObjectPaging paging = ObjectPaging.createPaging(null, 3);
query.setPaging(paging);

rememberConnectorOperationCount();
rememberConnectorSimulatedPagingSearchCount();

// WHEN
List<PrismObject<ShadowType>> searchResults =
Expand All @@ -1367,6 +1388,9 @@ public void test230SearchObjectsPagedNoOffset() throws Exception {
display("Search resutls", searchResults);

assertSearchResults(searchResults, "cook", "drake", "hbarbossa" );

assertConnectorOperationIncrement(1);
assertConnectorSimulatedPagingSearchIncrement(0);
}

@Test
Expand All @@ -1382,6 +1406,9 @@ public void test231SearchObjectsPagedOffsetZero() throws Exception {

ObjectPaging paging = ObjectPaging.createPaging(0, 4);
query.setPaging(paging);

rememberConnectorOperationCount();
rememberConnectorSimulatedPagingSearchCount();

// WHEN
List<PrismObject<ShadowType>> searchResults =
Expand All @@ -1393,6 +1420,9 @@ public void test231SearchObjectsPagedOffsetZero() throws Exception {
display("Search resutls", searchResults);

assertSearchResults(searchResults, "drake", "hbarbossa", "idm", "jbeckett");

assertConnectorOperationIncrement(1);
assertConnectorSimulatedPagingSearchIncrement(0);
}

@Test
Expand All @@ -1408,6 +1438,9 @@ public void test232SearchObjectsPagedOffset() throws Exception {

ObjectPaging paging = ObjectPaging.createPaging(2, 5);
query.setPaging(paging);

rememberConnectorOperationCount();
rememberConnectorSimulatedPagingSearchCount();

// WHEN
List<PrismObject<ShadowType>> searchResults =
Expand All @@ -1419,6 +1452,9 @@ public void test232SearchObjectsPagedOffset() throws Exception {
display("Search resutls", searchResults);

assertSearchResults(searchResults, "hbarbossa", "idm", "jbeckett", "jbond", "jgibbs" );

assertConnectorOperationIncrement(1);
assertConnectorSimulatedPagingSearchIncrement(0);
}

private void assertSearchResults(List<PrismObject<ShadowType>> searchResults, String... expectedUids) {
Expand Down
Expand Up @@ -52,6 +52,7 @@
import com.evolveum.midpoint.util.logging.TraceManager;
import com.evolveum.midpoint.xml.ns._public.common.common_3.*;
import com.evolveum.midpoint.xml.ns._public.resource.capabilities_3.CredentialsCapabilityType;
import com.evolveum.midpoint.xml.ns._public.resource.capabilities_3.PagedSearchCapabilityType;
import com.evolveum.prism.xml.ns._public.types_3.ItemDeltaType;
import com.evolveum.prism.xml.ns._public.types_3.ItemPathType;
import com.evolveum.prism.xml.ns._public.types_3.ModificationTypeType;
Expand Down Expand Up @@ -587,7 +588,9 @@ public void testCapabilities() throws Exception {
CredentialsCapabilityType capCred = CapabilityUtil.getCapability(capabilities,
CredentialsCapabilityType.class);
assertNotNull("password capability not present", capCred.getPassword());


PagedSearchCapabilityType capPage = CapabilityUtil.getCapability(capabilities, PagedSearchCapabilityType.class);
assertNotNull("paged search capability not present", capPage);
}

@Test
Expand Down
Expand Up @@ -40,6 +40,7 @@
<icfcldap:pagingStrategy>auto</icfcldap:pagingStrategy>
<icfcldap:vlvSortAttribute>entryUUID</icfcldap:vlvSortAttribute>
<icfcldap:operationalAttributes>ds-pwp-account-disabled</icfcldap:operationalAttributes>
<icfcldap:operationalAttributes>isMemberOf</icfcldap:operationalAttributes>
</icfc:configurationProperties>

<icfc:connectorPoolConfiguration>
Expand Down Expand Up @@ -89,6 +90,11 @@
<ref>icfs:name</ref>
<matchingRule>mr:stringIgnoreCase</matchingRule>
</attribute>
<attribute>
<ref>ri:isMemberOf</ref>
<matchingRule>mr:stringIgnoreCase</matchingRule>
<fetchStrategy>explicit</fetchStrategy>
</attribute>
<association>
<ref>ri:group</ref>
<displayName>LDAP Group Membership</displayName>
Expand All @@ -97,6 +103,8 @@
<direction>objectToSubject</direction>
<associationAttribute>ri:uniqueMember</associationAttribute>
<valueAttribute>icfs:name</valueAttribute>
<shortcutAssociationAttribute>ri:isMemberOf</shortcutAssociationAttribute>
<shortcutValueAttribute>icfs:name</shortcutValueAttribute>
<explicitReferentialIntegrity>true</explicitReferentialIntegrity>
</association>
<protected>
Expand Down
Expand Up @@ -134,6 +134,7 @@ public abstract class AbstractIntegrationTest extends AbstractTestNGSpringContex
private long lastScriptCompileCount = 0;
private long lastScriptExecutionCount = 0;
private long lastConnectorOperationCount = 0;
private long lastConnectorSimulatedPagingSearchCount = 0;

@Autowired(required = true)
@Qualifier("cacheRepositoryService")
Expand Down Expand Up @@ -705,8 +706,16 @@ protected void assertConnectorOperationIncrement(int expectedIncrement) {
lastConnectorOperationCount = currentCount;
}



protected void rememberConnectorSimulatedPagingSearchCount() {
lastConnectorSimulatedPagingSearchCount = InternalMonitor.getConnectorSimulatedPagingSearchCount();
}

protected void assertConnectorSimulatedPagingSearchIncrement(int expectedIncrement) {
long currentCount = InternalMonitor.getConnectorSimulatedPagingSearchCount();
long actualIncrement = currentCount - lastConnectorSimulatedPagingSearchCount;
assertEquals("Unexpected increment in connector simulated paged search count", (long)expectedIncrement, actualIncrement);
lastConnectorSimulatedPagingSearchCount = currentCount;
}

protected void rememberResourceCacheStats() {
lastResourceCacheStats = InternalMonitor.getResourceCacheStats().clone();
Expand Down

0 comments on commit 77ba61b

Please sign in to comment.