Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[LDAP-45] Add better control to paged searching #33

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
93 changes: 63 additions & 30 deletions src/main/java/net/tirasa/connid/bundles/ldap/LdapConfiguration.java
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,10 @@ public enum SearchScope {

private Class<? extends LdapConnection> connectionClass = LdapConnection.class;

private int pageSize = 100;

private boolean usePaging = true;

/**
* The SearchScope for user objects
*/
Expand Down Expand Up @@ -359,9 +363,7 @@ public void validate() {

checkNotBlank(changeNumberAttribute, "changeNumberAttribute.notBlank");

if (changeLogBlockSize <= 0) {
failValidation("changeLogBlockSize.legalValue");
}
checkPositive(changeLogBlockSize, "changeLogBLockSize.legalValue");

checkNotBlank(changeLogContext, "changeLogContext.notBlank");

Expand All @@ -373,6 +375,14 @@ public void validate() {

checkNotBlank(syncStrategy, "syncStrategy.notBlank");
checkLdapSyncStrategy();

checkPositive(pageSize, "pageSize.legalValue");
}

protected void checkPositive(int value, String errorMessage) {
if (value <= 0) {
failValidation(errorMessage);
}
}

protected void checkNotBlank(String value, String errorMessage) {
Expand Down Expand Up @@ -751,6 +761,28 @@ public void setRespectResourcePasswordPolicyChangeAfterReset(boolean respectReso
}

@ConfigurationProperty(order = 26,
displayMessageKey = "usePaging.display",
helpMessageKey = "usePaging.help")
public boolean isUsePaging() {
return usePaging;
}

public void setUsePaging(boolean usePaging) {
this.usePaging = usePaging;
}

@ConfigurationProperty(order = 27,
displayMessageKey = "pageSize.display",
helpMessageKey = "pageSize.help")
public int getPageSize() {
return pageSize;
}

public void setPageSize(int pageSize) {
this.pageSize = pageSize;
}

@ConfigurationProperty(order = 28,
displayMessageKey = "useVlvControls.display",
helpMessageKey = "useVlvControls.help")
public boolean isUseVlvControls() {
Expand All @@ -761,7 +793,7 @@ public void setUseVlvControls(boolean useVlvControls) {
this.useVlvControls = useVlvControls;
}

@ConfigurationProperty(order = 27,
@ConfigurationProperty(order = 29,
displayMessageKey = "vlvSortAttribute.display",
helpMessageKey = "vlvSortAttribute.help")
public String getVlvSortAttribute() {
Expand All @@ -772,7 +804,7 @@ public void setVlvSortAttribute(String vlvSortAttribute) {
this.vlvSortAttribute = vlvSortAttribute;
}

@ConfigurationProperty(order = 28,
@ConfigurationProperty(order = 30,
displayMessageKey = "uidAttribute.display",
helpMessageKey = "uidAttribute.help")
public String getUidAttribute() {
Expand All @@ -783,7 +815,7 @@ public void setUidAttribute(final String uidAttribute) {
this.uidAttribute = uidAttribute;
}

@ConfigurationProperty(order = 29,
@ConfigurationProperty(order = 31,
displayMessageKey = "gidAttribute.display",
helpMessageKey = "gidAttribute.help")
public String getGidAttribute() {
Expand All @@ -794,7 +826,7 @@ public void setGidAttribute(final String gidAttribute) {
this.gidAttribute = gidAttribute;
}

@ConfigurationProperty(order = 30,
@ConfigurationProperty(order = 32,
displayMessageKey = "aoidAttribute.display",
helpMessageKey = "aoidAttribute.help")
public String getAoidAttribute() {
Expand All @@ -805,7 +837,7 @@ public void setAoidAttribute(final String aoidAttribute) {
this.aoidAttribute = aoidAttribute;
}

@ConfigurationProperty(order = 31,
@ConfigurationProperty(order = 33,
displayMessageKey = "readSchema.display",
helpMessageKey = "readSchema.help")
public boolean isReadSchema() {
Expand All @@ -817,7 +849,7 @@ public void setReadSchema(boolean readSchema) {
}

// Sync properties getters and setters.
@ConfigurationProperty(order = 32, operations = { SyncOp.class },
@ConfigurationProperty(order = 34, operations = { SyncOp.class },
displayMessageKey = "baseContextsToSynchronize.display",
helpMessageKey = "baseContextsToSynchronize.help")
public String[] getBaseContextsToSynchronize() {
Expand All @@ -828,7 +860,7 @@ public void setBaseContextsToSynchronize(String... baseContextsToSynchronize) {
this.baseContextsToSynchronize = baseContextsToSynchronize.clone();
}

@ConfigurationProperty(order = 33, operations = { SyncOp.class },
@ConfigurationProperty(order = 35, operations = { SyncOp.class },
displayMessageKey = "objectClassesToSynchronize.display",
helpMessageKey = "objectClassesToSynchronize.help")
public String[] getObjectClassesToSynchronize() {
Expand All @@ -839,7 +871,7 @@ public void setObjectClassesToSynchronize(String... objectClassesToSynchronize)
this.objectClassesToSynchronize = objectClassesToSynchronize.clone();
}

@ConfigurationProperty(order = 34, operations = { SyncOp.class },
@ConfigurationProperty(order = 36, operations = { SyncOp.class },
displayMessageKey = "attributesToSynchronize.display",
helpMessageKey = "attributesToSynchronize.help")
public String[] getAttributesToSynchronize() {
Expand All @@ -850,7 +882,7 @@ public void setAttributesToSynchronize(String... attributesToSynchronize) {
this.attributesToSynchronize = attributesToSynchronize.clone();
}

@ConfigurationProperty(order = 35, operations = { SyncOp.class },
@ConfigurationProperty(order = 37, operations = { SyncOp.class },
displayMessageKey = "modifiersNamesToFilterOut.display",
helpMessageKey = "modifiersNamesToFilterOut.help")
public String[] getModifiersNamesToFilterOut() {
Expand All @@ -861,7 +893,7 @@ public void setModifiersNamesToFilterOut(String... modifiersNamesToFilterOut) {
this.modifiersNamesToFilterOut = modifiersNamesToFilterOut.clone();
}

@ConfigurationProperty(order = 36, operations = { SyncOp.class },
@ConfigurationProperty(order = 38, operations = { SyncOp.class },
displayMessageKey = "accountSynchronizationFilter.display",
helpMessageKey = "accountSynchronizationFilter.help")
public String getAccountSynchronizationFilter() {
Expand All @@ -872,7 +904,7 @@ public void setAccountSynchronizationFilter(String accountSynchronizationFilter)
this.accountSynchronizationFilter = accountSynchronizationFilter;
}

@ConfigurationProperty(order = 37, operations = { SyncOp.class },
@ConfigurationProperty(order = 39, operations = { SyncOp.class },
displayMessageKey = "changeLogBlockSize.display",
helpMessageKey = "changeLogBlockSize.help")
public int getChangeLogBlockSize() {
Expand All @@ -883,7 +915,7 @@ public void setChangeLogBlockSize(int changeLogBlockSize) {
this.changeLogBlockSize = changeLogBlockSize;
}

@ConfigurationProperty(order = 38, operations = { SyncOp.class },
@ConfigurationProperty(order = 40, operations = { SyncOp.class },
displayMessageKey = "changeNumberAttribute.display",
helpMessageKey = "changeNumberAttribute.help")
public String getChangeNumberAttribute() {
Expand All @@ -894,7 +926,7 @@ public void setChangeNumberAttribute(String changeNumberAttribute) {
this.changeNumberAttribute = changeNumberAttribute;
}

@ConfigurationProperty(order = 39, operations = { SyncOp.class },
@ConfigurationProperty(order = 41, operations = { SyncOp.class },
displayMessageKey = "changeLogContext.display",
helpMessageKey = "changeNumberAttribute.help")
public String getChangeLogContext() {
Expand All @@ -905,7 +937,7 @@ public void setChangeLogContext(String changeLogContext) {
this.changeLogContext = changeLogContext;
}

@ConfigurationProperty(order = 40, operations = { SyncOp.class },
@ConfigurationProperty(order = 42, operations = { SyncOp.class },
displayMessageKey = "changeLogPagingSupport.display",
helpMessageKey = "changeLogPagingSupport.help")
public boolean getChangeLogPagingSupport() {
Expand All @@ -916,7 +948,7 @@ public void setChangeLogPagingSupport(boolean changeLogPagingSupport) {
this.changeLogPagingSupport = changeLogPagingSupport;
}

@ConfigurationProperty(order = 41, operations = { SyncOp.class },
@ConfigurationProperty(order = 43, operations = { SyncOp.class },
displayMessageKey = "filterWithOrInsteadOfAnd.display",
helpMessageKey = "filterWithOrInsteadOfAnd.help")
public boolean isFilterWithOrInsteadOfAnd() {
Expand All @@ -927,7 +959,7 @@ public void setFilterWithOrInsteadOfAnd(boolean filterWithOrInsteadOfAnd) {
this.filterWithOrInsteadOfAnd = filterWithOrInsteadOfAnd;
}

@ConfigurationProperty(order = 42, operations = { SyncOp.class },
@ConfigurationProperty(order = 44, operations = { SyncOp.class },
displayMessageKey = "removeLogEntryObjectClassFromFilter.display",
helpMessageKey = "removeLogEntryObjectClassFromFilter.help")
public boolean isRemoveLogEntryObjectClassFromFilter() {
Expand All @@ -938,7 +970,7 @@ public void setRemoveLogEntryObjectClassFromFilter(boolean removeLogEntryObjectC
this.removeLogEntryObjectClassFromFilter = removeLogEntryObjectClassFromFilter;
}

@ConfigurationProperty(order = 43, operations = { SyncOp.class },
@ConfigurationProperty(order = 45, operations = { SyncOp.class },
displayMessageKey = "synchronizePasswords.display",
helpMessageKey = "synchronizePasswords.help")
public boolean isSynchronizePasswords() {
Expand All @@ -949,7 +981,7 @@ public void setSynchronizePasswords(boolean synchronizePasswords) {
this.synchronizePasswords = synchronizePasswords;
}

@ConfigurationProperty(order = 44, operations = { SyncOp.class },
@ConfigurationProperty(order = 46, operations = { SyncOp.class },
displayMessageKey = "passwordAttributeToSynchronize.display",
helpMessageKey = "passwordAttributeToSynchronize.help")
public String getPasswordAttributeToSynchronize() {
Expand All @@ -960,7 +992,7 @@ public void setPasswordAttributeToSynchronize(String passwordAttributeToSynchron
this.passwordAttributeToSynchronize = passwordAttributeToSynchronize;
}

@ConfigurationProperty(order = 45, operations = { SyncOp.class }, confidential = true,
@ConfigurationProperty(order = 47, operations = { SyncOp.class }, confidential = true,
displayMessageKey = "passwordDecryptionKey.display",
helpMessageKey = "passwordDecryptionKey.help")
public GuardedByteArray getPasswordDecryptionKey() {
Expand All @@ -972,7 +1004,7 @@ public void setPasswordDecryptionKey(GuardedByteArray passwordDecryptionKey) {
copy() : null;
}

@ConfigurationProperty(order = 46, operations = { SyncOp.class }, confidential = true,
@ConfigurationProperty(order = 48, operations = { SyncOp.class }, confidential = true,
displayMessageKey = "passwordDecryptionInitializationVector.display",
helpMessageKey = "passwordDecryptionInitializationVector.help")
public GuardedByteArray getPasswordDecryptionInitializationVector() {
Expand All @@ -984,7 +1016,7 @@ public void setPasswordDecryptionInitializationVector(GuardedByteArray passwordD
? passwordDecryptionInitializationVector.copy() : null;
}

@ConfigurationProperty(order = 47,
@ConfigurationProperty(order = 49,
displayMessageKey = "statusManagementClass.display",
helpMessageKey = "statusManagementClass.help")
public String getStatusManagementClass() {
Expand All @@ -995,7 +1027,7 @@ public void setStatusManagementClass(String statusManagementClass) {
this.statusManagementClass = statusManagementClass;
}

@ConfigurationProperty(order = 48,
@ConfigurationProperty(order = 50,
displayMessageKey = "retrievePasswordsWithSearch.display",
helpMessageKey = "retrievePasswordsWithSearch.help")
public boolean getRetrievePasswordsWithSearch() {
Expand All @@ -1006,7 +1038,7 @@ public void setRetrievePasswordsWithSearch(boolean retrievePasswordsWithSearch)
this.retrievePasswordsWithSearch = retrievePasswordsWithSearch;
}

@ConfigurationProperty(order = 49,
@ConfigurationProperty(order = 51,
displayMessageKey = "dnAttribute.display",
helpMessageKey = "dnAttribute.help")
public String getDnAttribute() {
Expand All @@ -1017,7 +1049,7 @@ public void setDnAttribute(String dnAttribute) {
this.dnAttribute = dnAttribute;
}

@ConfigurationProperty(order = 50,
@ConfigurationProperty(order = 52,
displayMessageKey = "groupSearchFilter.display",
helpMessageKey = "groupSearchFilter.help")
public String getGroupSearchFilter() {
Expand All @@ -1028,7 +1060,7 @@ public void setGroupSearchFilter(String groupSearchFilter) {
this.groupSearchFilter = groupSearchFilter;
}

@ConfigurationProperty(order = 51,
@ConfigurationProperty(order = 53,
displayMessageKey = "readTimeout.display",
helpMessageKey = "readTimeout.help")
public long getReadTimeout() {
Expand All @@ -1039,7 +1071,7 @@ public void setReadTimeout(long readTimeout) {
this.readTimeout = readTimeout;
}

@ConfigurationProperty(order = 52,
@ConfigurationProperty(order = 54,
displayMessageKey = "connectTimeout.display",
helpMessageKey = "connectTimeout.help")
public long getConnectTimeout() {
Expand All @@ -1050,7 +1082,7 @@ public void setConnectTimeout(long connectTimeout) {
this.connectTimeout = connectTimeout;
}

@ConfigurationProperty(order = 53,
@ConfigurationProperty(order = 55,
displayMessageKey = "syncStrategy.display",
helpMessageKey = "syncStrategy.help")
public String getSyncStrategy() {
Expand Down Expand Up @@ -1189,6 +1221,7 @@ protected EqualsHashCodeBuilder createHashCodeBuilder() {
builder.append(groupSearchFilter);
builder.append(connectTimeout);
builder.append(readTimeout);
builder.append(pageSize);
return builder;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -406,13 +406,13 @@ protected List<String> getBaseDNs() {

protected LdapSearchStrategy getSearchStrategy() {
LdapSearchStrategy result = conn.getConfiguration().newDefaultSearchStrategy(false);
if (options.getPageSize() != null) {
if (conn.getConfiguration().isUsePaging()) {
if (conn.getConfiguration().isUseVlvControls() && conn.supportsControl(VirtualListViewControl.OID)) {
String vlvSortAttr = conn.getConfiguration().getVlvSortAttribute();
result = new VlvIndexSearchStrategy(vlvSortAttr, options.getPageSize());
result = new VlvIndexSearchStrategy(vlvSortAttr, conn.getConfiguration().getPageSize());
} else if (conn.supportsControl(PagedResultsControl.OID)) {
result = new PagedSearchStrategy(
options.getPageSize(),
conn.getConfiguration().getPageSize(),
options.getPagedResultsCookie(),
options.getPagedResultsOffset(),
handler instanceof SearchResultsHandler ? (SearchResultsHandler) handler : null,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ protected static String searchControlsToString(final SearchControls controls) {

public static Class<? extends LdapSearchStrategy> getSearchStrategy(LdapConnection conn, OperationOptions options) {
Class<? extends LdapSearchStrategy> clazz = DefaultSearchStrategy.class;
if (options.getPageSize() != null) {
if (conn.getConfiguration().isUsePaging()) {
if (conn.getConfiguration().isUseVlvControls() && conn.supportsControl(VirtualListViewControl.OID)) {
clazz = VlvIndexSearchStrategy.class;
} else if (conn.supportsControl(PagedResultsControl.OID)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,16 +107,28 @@ public void doSearch(final LdapContext initCtx, final List<String> baseDNs, fina
for (int i = 0; i < sortKeys.length; i++) {
skis[i] = new javax.naming.ldap.SortKey(sortKeys[i].getField(), sortKeys[i].isAscendingOrder(),
null);
if (LOG.isOk()) {
LOG.ok("Adding '{0}' as a requested sort key", sortKeys[i].getField());
}
}
// We don't want to make this critical... better return unsorted results than nothing.
sortControl = new SortControl(skis, Control.NONCRITICAL);
}

if (LOG.isOk()) {
if (cookie != null) {
LOG.ok("Setting paged request control with page size '{0}' and cookie '{1}'",
pageSize - records,
cookie != null ? Base64.getEncoder().encodeToString(cookie) : "");
}
}
PagedResultsControl pagedResultsControl = new PagedResultsControl(pageSize - records, cookie,
Control.CRITICAL);
if (sortControl == null) {
ctx.setRequestControls(new Control[] {
new PagedResultsControl(pageSize - records, cookie, Control.CRITICAL) });
ctx.setRequestControls(new Control[] { pagedResultsControl });
} else {
ctx.setRequestControls(new Control[] {
new PagedResultsControl(pageSize - records, cookie, Control.CRITICAL), sortControl
pagedResultsControl, sortControl
});
}

Expand All @@ -139,6 +151,15 @@ public void doSearch(final LdapContext initCtx, final List<String> baseDNs, fina
PagedResultsResponseControl pagedControl = getPagedControl(ctx.getResponseControls());
if (pagedControl != null) {
cookie = pagedControl.getCookie();
if (LOG.isOk())
{
if (cookie != null) {
LOG.ok("Server returned a paged results control with cookie '{0}'",
Base64.getEncoder().encodeToString(cookie));
}

}

if (pagedControl.getResultSize() > 0) {
remainingResults = pagedControl.getResultSize();
}
Expand Down
Loading