From 0db2c7673dc25470930390c4664f7caf9be77088 Mon Sep 17 00:00:00 2001 From: "Endi S. Dewata" Date: Tue, 7 Jun 2016 10:02:30 +0200 Subject: Fixed TPS VLV sort orders. The TPS VLVs for tokens and activities has been modified to sort the results by date in reverse order. The DBRegistry.getLDAPAttributes() was modified to support reverse sort order by recognizing the "-" prefix in the list of sort keys and pass it to LDAP. The DBVirtualList.setSortKey() was modified to ignore bubble up the exceptions that happen during LDAP attribute mapping. https://fedorahosted.org/pki/ticket/2263 https://fedorahosted.org/pki/ticket/2269 --- .../src/com/netscape/certsrv/dbs/IDBSSession.java | 19 +++++++- .../src/com/netscape/cmscore/dbs/DBRegistry.java | 54 +++++++++++++--------- .../com/netscape/cmscore/dbs/DBVirtualList.java | 51 +++++++++----------- .../src/com/netscape/cmscore/dbs/LDAPDatabase.java | 6 +-- .../cmscore/dbs/DBSSessionDefaultStub.java | 9 +++- base/tps/shared/conf/vlv.ldif | 4 +- .../dogtagpki/server/tps/rest/ActivityService.java | 2 +- .../dogtagpki/server/tps/rest/TokenService.java | 3 +- 8 files changed, 87 insertions(+), 61 deletions(-) (limited to 'base') diff --git a/base/common/src/com/netscape/certsrv/dbs/IDBSSession.java b/base/common/src/com/netscape/certsrv/dbs/IDBSSession.java index 1a1f58d60..656950570 100644 --- a/base/common/src/com/netscape/certsrv/dbs/IDBSSession.java +++ b/base/common/src/com/netscape/certsrv/dbs/IDBSSession.java @@ -17,11 +17,11 @@ // --- END COPYRIGHT BLOCK --- package com.netscape.certsrv.dbs; -import netscape.ldap.LDAPSearchResults; - import com.netscape.certsrv.base.EBaseException; import com.netscape.certsrv.base.ISubsystem; +import netscape.ldap.LDAPSearchResults; + /** * An interface represents the database session. Operations * can be performed with a session. @@ -194,6 +194,21 @@ public interface IDBSSession extends AutoCloseable { String attrs[], String sortKey, int pageSize) throws EBaseException; + /** + * Retrieves a list of objects. + * + * @param base starting point of the search + * @param filter search filter + * @param attrs selected attributes + * @param sortKeys keys used to sort the list + * @param pageSize page size in the virtual list + * @return search results in virtual list + * @exception EBaseException failed to search + */ + public IDBVirtualList createVirtualList(String base, String filter, + String attrs[], String sortKeys[], int pageSize) + throws EBaseException; + /** * Retrieves a list of objects. * diff --git a/base/server/cmscore/src/com/netscape/cmscore/dbs/DBRegistry.java b/base/server/cmscore/src/com/netscape/cmscore/dbs/DBRegistry.java index 6e6f83750..2ee3312f2 100644 --- a/base/server/cmscore/src/com/netscape/cmscore/dbs/DBRegistry.java +++ b/base/server/cmscore/src/com/netscape/cmscore/dbs/DBRegistry.java @@ -20,11 +20,10 @@ package com.netscape.cmscore.dbs; import java.util.Enumeration; import java.util.Hashtable; import java.util.Iterator; +import java.util.LinkedHashSet; +import java.util.Set; import java.util.Vector; -import netscape.ldap.LDAPAttribute; -import netscape.ldap.LDAPAttributeSet; - import com.netscape.certsrv.apps.CMS; import com.netscape.certsrv.base.EBaseException; import com.netscape.certsrv.base.IConfigStore; @@ -37,6 +36,9 @@ import com.netscape.certsrv.dbs.IDBRegistry; import com.netscape.certsrv.dbs.IFilterConverter; import com.netscape.certsrv.logging.ILogger; +import netscape.ldap.LDAPAttribute; +import netscape.ldap.LDAPAttributeSet; + /** * A class represents a registry where all the * schema (object classes and attribute) information @@ -362,21 +364,31 @@ public class DBRegistry implements IDBRegistry, ISubsystem { */ public String[] getLDAPAttributes(String attrs[]) throws EBaseException { - IDBAttrMapper mapper; if (attrs == null) return null; - Vector v = new Vector(); + + // ignore duplicates, maintain order + Set v = new LinkedHashSet(); for (int i = 0; i < attrs.length; i++) { - if (attrs[i].equals("objectclass")) { - v.addElement("objectclass"); + String attr = attrs[i]; + String prefix = ""; + + // check reverse sort order + if (attr.startsWith("-")) { + attr = attr.substring(1); + prefix = "-"; + } + + if (attr.equalsIgnoreCase("objectclass")) { + v.add(prefix + attr); continue; } - if (isAttributeRegistered(attrs[i])) { - mapper = mAttrufNames.get(attrs[i].toLowerCase()); + if (isAttributeRegistered(attr)) { + IDBAttrMapper mapper = mAttrufNames.get(attr.toLowerCase()); if (mapper == null) { throw new EDBException(CMS.getUserMessage("CMS_DBS_INVALID_ATTRS")); } @@ -384,24 +396,23 @@ public class DBRegistry implements IDBRegistry, ISubsystem { while (e.hasMoreElements()) { String s = e.nextElement(); - - if (!v.contains(s)) { - v.addElement(s); - } + v.add(prefix + s); } + } else { IDBDynAttrMapper matchingDynAttrMapper = null; // check if a dynamic mapper can handle the attribute for (Iterator dynMapperIter = mDynAttrMappers.iterator(); dynMapperIter.hasNext();) { - IDBDynAttrMapper dynAttrMapper = - dynMapperIter.next(); - if (dynAttrMapper.supportsLDAPAttributeName(attrs[i])) { + IDBDynAttrMapper dynAttrMapper = dynMapperIter.next(); + if (dynAttrMapper.supportsLDAPAttributeName(attr)) { matchingDynAttrMapper = dynAttrMapper; break; } } + if (matchingDynAttrMapper != null) { - v.addElement(attrs[i]); + v.add(prefix + attr); + } else { /*LogDoc * @@ -410,17 +421,18 @@ public class DBRegistry implements IDBRegistry, ISubsystem { * @message DBRegistry: is not registered */ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_DB, - ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_DBS_ATTR_NOT_REGISTER", attrs[i])); - throw new EDBException(CMS.getLogMessage("CMSCORE_DBS_ATTR_NOT_REGISTER", attrs[i])); + ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_DBS_ATTR_NOT_REGISTER", attr)); + throw new EDBException(CMS.getLogMessage("CMSCORE_DBS_ATTR_NOT_REGISTER", attr)); } } - } + if (v.size() == 0) return null; + String ldapAttrs[] = new String[v.size()]; + v.toArray(ldapAttrs); - v.copyInto(ldapAttrs); return ldapAttrs; } diff --git a/base/server/cmscore/src/com/netscape/cmscore/dbs/DBVirtualList.java b/base/server/cmscore/src/com/netscape/cmscore/dbs/DBVirtualList.java index fde67c663..38646bbfb 100644 --- a/base/server/cmscore/src/com/netscape/cmscore/dbs/DBVirtualList.java +++ b/base/server/cmscore/src/com/netscape/cmscore/dbs/DBVirtualList.java @@ -20,6 +20,13 @@ package com.netscape.cmscore.dbs; import java.util.Arrays; import java.util.Vector; +import com.netscape.certsrv.apps.CMS; +import com.netscape.certsrv.base.EBaseException; +import com.netscape.certsrv.dbs.IDBRegistry; +import com.netscape.certsrv.dbs.IDBVirtualList; +import com.netscape.certsrv.dbs.IElementProcessor; +import com.netscape.certsrv.logging.ILogger; + import netscape.ldap.LDAPConnection; import netscape.ldap.LDAPControl; import netscape.ldap.LDAPEntry; @@ -30,13 +37,6 @@ import netscape.ldap.controls.LDAPSortControl; import netscape.ldap.controls.LDAPVirtualListControl; import netscape.ldap.controls.LDAPVirtualListResponse; -import com.netscape.certsrv.apps.CMS; -import com.netscape.certsrv.base.EBaseException; -import com.netscape.certsrv.dbs.IDBRegistry; -import com.netscape.certsrv.dbs.IDBVirtualList; -import com.netscape.certsrv.dbs.IElementProcessor; -import com.netscape.certsrv.logging.ILogger; - /** * A class represents a virtual list of search results. * Note that this class must be used with DS4.0. @@ -305,36 +305,29 @@ public class DBVirtualList implements IDBVirtualList { * @param sortKey the attributes to sort by */ public void setSortKey(String[] sortKeys) throws EBaseException { + if (sortKeys == null) throw new EBaseException("sort keys cannot be null"); - try { - mKeys = new LDAPSortKey[sortKeys.length]; - String la[] = null; - synchronized (this) { - la = mRegistry.getLDAPAttributes(sortKeys); - } - for (int j = 0; j < sortKeys.length; j++) { - mKeys[j] = new LDAPSortKey(la[j]); - } - } catch (Exception e) { + mKeys = new LDAPSortKey[sortKeys.length]; + String la[] = null; + synchronized (this) { + la = mRegistry.getLDAPAttributes(sortKeys); + } - /*LogDoc - * - * @phase local ldap search - * @reason Failed at setSortKey. - * @message DBVirtualList: - */ - mLogger.log(ILogger.EV_SYSTEM, ILogger.S_DB, ILogger.LL_FAILURE, - CMS.getLogMessage("OPERATION_ERROR", e.toString())); + if (la == null) + throw new EBaseException("sort keys cannot be null"); + + for (int i = 0; i < sortKeys.length; i++) { + mKeys[i] = new LDAPSortKey(la[i]); } + // Paged results also require a sort control - if (mKeys != null) { - mPageControls[0] = - new LDAPSortControl(mKeys, true); - } else { + if (mKeys == null) { throw new EBaseException("sort keys cannot be null"); } + + mPageControls[0] = new LDAPSortControl(mKeys, true); } /** diff --git a/base/server/cmscore/src/com/netscape/cmscore/dbs/LDAPDatabase.java b/base/server/cmscore/src/com/netscape/cmscore/dbs/LDAPDatabase.java index 48d15950e..8773423ca 100644 --- a/base/server/cmscore/src/com/netscape/cmscore/dbs/LDAPDatabase.java +++ b/base/server/cmscore/src/com/netscape/cmscore/dbs/LDAPDatabase.java @@ -142,7 +142,7 @@ public abstract class LDAPDatabase extends Database { } public IDBVirtualList findRecords(String keyword, Map attributes, - String sortKey, int pageSize) throws Exception { + String[] sortKeys, int pageSize) throws Exception { CMS.debug("LDAPDatabase: findRecords()"); @@ -154,8 +154,8 @@ public abstract class LDAPDatabase extends Database { return session.createVirtualList( baseDN, ldapFilter, - null, - sortKey, + (String[]) null, + sortKeys, pageSize); } } diff --git a/base/server/test/com/netscape/cmscore/dbs/DBSSessionDefaultStub.java b/base/server/test/com/netscape/cmscore/dbs/DBSSessionDefaultStub.java index 09a2e1498..e4e715724 100644 --- a/base/server/test/com/netscape/cmscore/dbs/DBSSessionDefaultStub.java +++ b/base/server/test/com/netscape/cmscore/dbs/DBSSessionDefaultStub.java @@ -1,7 +1,5 @@ package com.netscape.cmscore.dbs; -import netscape.ldap.LDAPSearchResults; - import com.netscape.certsrv.base.EBaseException; import com.netscape.certsrv.base.ISubsystem; import com.netscape.certsrv.dbs.EDBException; @@ -11,6 +9,8 @@ import com.netscape.certsrv.dbs.IDBSearchResults; import com.netscape.certsrv.dbs.IDBVirtualList; import com.netscape.certsrv.dbs.ModificationSet; +import netscape.ldap.LDAPSearchResults; + /** * A default stub ojbect for tests to extend. */ @@ -72,6 +72,11 @@ public class DBSSessionDefaultStub implements IDBSSession { return null; } + public IDBVirtualList createVirtualList(String base, String filter, String attrs[], String sortKeys[], int pageSize) + throws EBaseException { + return null; + } + public IDBVirtualList createVirtualList(String base, String filter, String attrs[], String startFrom, String sortKey, int pageSize) throws EBaseException { return null; diff --git a/base/tps/shared/conf/vlv.ldif b/base/tps/shared/conf/vlv.ldif index e3063984b..39a5f051c 100644 --- a/base/tps/shared/conf/vlv.ldif +++ b/base/tps/shared/conf/vlv.ldif @@ -38,12 +38,12 @@ dn: cn=listTokensIndex,cn=listTokens,cn={database},cn=ldbm database,cn=plugins,c cn: listTokensIndex objectClass: top objectClass: vlvindex -vlvSort: dateOfModify +vlvSort: -dateOfModify -dateOfCreate vlvUses: 0 dn: cn=listActivitiesIndex,cn=listActivities,cn={database},cn=ldbm database,cn=plugins,cn=config cn: listActivitiesIndex objectClass: top objectClass: vlvindex -vlvSort: dateOfCreate +vlvSort: -dateOfCreate vlvUses: 0 diff --git a/base/tps/src/org/dogtagpki/server/tps/rest/ActivityService.java b/base/tps/src/org/dogtagpki/server/tps/rest/ActivityService.java index 5fb3d1956..dbf5f8d63 100644 --- a/base/tps/src/org/dogtagpki/server/tps/rest/ActivityService.java +++ b/base/tps/src/org/dogtagpki/server/tps/rest/ActivityService.java @@ -121,7 +121,7 @@ public class ActivityService extends PKIService implements ActivityResource { TPSSubsystem subsystem = (TPSSubsystem)CMS.getSubsystem(TPSSubsystem.ID); ActivityDatabase database = subsystem.getActivityDatabase(); - IDBVirtualList list = database.findRecords(filter, null, "date", size); + IDBVirtualList list = database.findRecords(filter, null, new String[] { "-date" }, size); int total = list.getSize(); ActivityCollection response = new ActivityCollection(); diff --git a/base/tps/src/org/dogtagpki/server/tps/rest/TokenService.java b/base/tps/src/org/dogtagpki/server/tps/rest/TokenService.java index 1c4285ed7..8e508aac8 100644 --- a/base/tps/src/org/dogtagpki/server/tps/rest/TokenService.java +++ b/base/tps/src/org/dogtagpki/server/tps/rest/TokenService.java @@ -268,7 +268,8 @@ public class TokenService extends PKIService implements TokenResource { TPSSubsystem subsystem = (TPSSubsystem) CMS.getSubsystem(TPSSubsystem.ID); TokenDatabase database = subsystem.getTokenDatabase(); - IDBVirtualList list = database.findRecords(filter, null, "modifyTimestamp", size); + IDBVirtualList list = database.findRecords( + filter, null, new String[] { "-modifyTimestamp", "-createTimestamp" }, size); int total = list.getSize(); TokenCollection response = new TokenCollection(); -- cgit