From f63df7552789ff0b3d21ca355cf7fc5e4e3f932c Mon Sep 17 00:00:00 2001 From: remillet Date: Fri, 15 Dec 2017 15:12:01 -0800 Subject: [PATCH] DRYD-181: Adding paging info to Roles and Permissions resources. Also fixed 'totalItems' bug showing incorrect results for Accounts paging info. --- services/authorization-mgt/jaxb/.gitignore | 1 + services/authorization-mgt/jaxb/pom.xml | 62 +++++++++++++++++++ .../jaxb/src/test/resources/log4j.properties | 25 ++++++++ .../storage/RoleDocumentHandler.java | 48 ++++++++++---- .../jaxb/src/main/resources/roles_list.xsd | 5 ++ .../storage/PermissionDocumentHandler.java | 38 ++++++++++-- .../common/document/DocumentFilter.java | 19 ++++++ .../storage/jpa/JpaDocumentHandler.java | 2 +- .../storage/jpa/JpaStorageClientImpl.java | 30 ++++++++- .../src/main/resources/permissions_list.xsd | 5 ++ 10 files changed, 217 insertions(+), 18 deletions(-) create mode 100644 services/authorization-mgt/jaxb/.gitignore create mode 100644 services/authorization-mgt/jaxb/pom.xml create mode 100644 services/authorization-mgt/jaxb/src/test/resources/log4j.properties diff --git a/services/authorization-mgt/jaxb/.gitignore b/services/authorization-mgt/jaxb/.gitignore new file mode 100644 index 000000000..b83d22266 --- /dev/null +++ b/services/authorization-mgt/jaxb/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/services/authorization-mgt/jaxb/pom.xml b/services/authorization-mgt/jaxb/pom.xml new file mode 100644 index 000000000..45e66d033 --- /dev/null +++ b/services/authorization-mgt/jaxb/pom.xml @@ -0,0 +1,62 @@ + + + + org.collectionspace.services + org.collectionspace.services.authorization-mgt + 5.0-SNAPSHOT + + + 4.0.0 + org.collectionspace.services.authorization-mgt.jaxb + services.authorization-mgt.jaxb + + + + + com.sun.xml.bind + jaxb-core + + + org.jvnet.jaxb2-commons + property-listener-injector + + + javax.persistence + persistence-api + + + org.hibernate + hibernate-entitymanager + + + org.jvnet.hyperjaxb3 + hyperjaxb3-ejb-runtime + + + org.collectionspace.services + org.collectionspace.services.jaxb + ${project.version} + + + org.collectionspace.services + org.collectionspace.services.hyperjaxb + ${project.version} + + + + + collectionspace-services-authorization-mgt-jaxb + install + + + + org.jvnet.hyperjaxb3 + maven-hyperjaxb3-plugin + + + + + + diff --git a/services/authorization-mgt/jaxb/src/test/resources/log4j.properties b/services/authorization-mgt/jaxb/src/test/resources/log4j.properties new file mode 100644 index 000000000..53720a742 --- /dev/null +++ b/services/authorization-mgt/jaxb/src/test/resources/log4j.properties @@ -0,0 +1,25 @@ +log4j.rootLogger=debug, stdout, R + +log4j.appender.stdout=org.apache.log4j.ConsoleAppender +log4j.appender.stdout.layout=org.apache.log4j.PatternLayout + +# Pattern to output the caller's file name and line number. +log4j.appender.stdout.layout.ConversionPattern=%d %-5p [%t] [%c:%L] %m%n + +log4j.appender.R=org.apache.log4j.RollingFileAppender +log4j.appender.R.File=target/test-client.log + +log4j.appender.R.MaxFileSize=100KB +# Keep one backup file +log4j.appender.R.MaxBackupIndex=1 + +log4j.appender.R.layout=org.apache.log4j.PatternLayout +log4j.appender.R.layout.ConversionPattern=%d %-5p [%t] [%c:%L] %m%n + +#packages +log4j.logger.org.collectionspace=DEBUG +log4j.logger.org.apache=INFO +log4j.logger.httpclient=INFO +log4j.logger.org.jboss.resteasy=INFO +log4j.logger.org.jvnet.hyperjaxb3=DEBUG +log4j.logger.org.hibernate=WARN \ No newline at end of file diff --git a/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/RoleDocumentHandler.java b/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/RoleDocumentHandler.java index 1661b78ff..77b3ca387 100644 --- a/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/RoleDocumentHandler.java +++ b/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/RoleDocumentHandler.java @@ -27,6 +27,7 @@ import java.util.ArrayList; import java.util.List; import java.util.UUID; +import org.collectionspace.services.account.AccountsCommonList; import org.collectionspace.services.authorization.PermissionRole; import org.collectionspace.services.authorization.PermissionRoleSubResource; import org.collectionspace.services.authorization.PermissionValue; @@ -45,7 +46,7 @@ import org.collectionspace.services.common.document.DocumentWrapper; import org.collectionspace.services.common.document.JaxbUtils; import org.collectionspace.services.common.security.SecurityUtils; import org.collectionspace.services.common.storage.jpa.JpaDocumentHandler; - +import org.collectionspace.services.jaxb.AbstractCommonList; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -54,7 +55,7 @@ import org.slf4j.LoggerFactory; * @author */ public class RoleDocumentHandler - extends JpaDocumentHandler { + extends JpaDocumentHandler> { private final Logger logger = LoggerFactory.getLogger(RoleDocumentHandler.class); private Role role; private RolesList rolesList; @@ -170,9 +171,9 @@ public class RoleDocumentHandler @Override public void completeUpdate(DocumentWrapper wrapDoc) throws Exception { - Role upAcc = wrapDoc.getWrappedObject(); - getServiceContext().setOutput(upAcc); - sanitize(upAcc); + Role updatedRole = wrapDoc.getWrappedObject(); + getServiceContext().setOutput(updatedRole); + sanitize(updatedRole); } @Override @@ -183,7 +184,7 @@ public class RoleDocumentHandler } @Override - public void handleGetAll(DocumentWrapper wrapDoc) throws Exception { + public void handleGetAll(DocumentWrapper> wrapDoc) throws Exception { RolesList rolesList = extractCommonPartList(wrapDoc); setCommonPartList(rolesList); getServiceContext().setOutput(getCommonPartList()); @@ -213,19 +214,44 @@ public class RoleDocumentHandler throw new UnsupportedOperationException("operation not relevant for AccountDocumentHandler"); } + /* + * See https://issues.collectionspace.org/browse/DRYD-181 + * + * For backward compatibility, we could not change the role list to be a child class of AbstractCommonList. This + * would have change the result payload and would break existing API clients. So the best we can do, it treat + * the role list payload as a special case and return the paging information. + * + */ + protected RolesList extractPagingInfoForRoles(RolesList roleList, DocumentWrapper> wrapDoc) + throws Exception { + + DocumentFilter docFilter = this.getDocumentFilter(); + long pageSize = docFilter.getPageSize(); + long pageNum = pageSize != 0 ? docFilter.getOffset() / pageSize : pageSize; + // set the page size and page number + roleList.setPageNum(pageNum); + roleList.setPageSize(pageSize); + List docList = wrapDoc.getWrappedObject(); + // Set num of items in list. this is useful to our testing framework. + roleList.setItemsInPage(docList.size()); + // set the total result size + roleList.setTotalItems(docFilter.getTotalItemsResult()); + + return roleList; + } + @Override public RolesList extractCommonPartList( - DocumentWrapper wrapDoc) - throws Exception { + DocumentWrapper> wrapDoc) throws Exception { - RolesList rolesList = new RolesList(); + RolesList rolesList = extractPagingInfoForRoles(new RolesList(), wrapDoc); List list = new ArrayList(); rolesList.setRole(list); - for (Object obj : wrapDoc.getWrappedObject()) { - Role role = (Role) obj; + for (Role role : wrapDoc.getWrappedObject()) { sanitize(role); list.add(role); } + return rolesList; } diff --git a/services/authorization/jaxb/src/main/resources/roles_list.xsd b/services/authorization/jaxb/src/main/resources/roles_list.xsd index 0e3fc1db1..b83b3dcb9 100644 --- a/services/authorization/jaxb/src/main/resources/roles_list.xsd +++ b/services/authorization/jaxb/src/main/resources/roles_list.xsd @@ -47,6 +47,11 @@ role list + + + + + diff --git a/services/common/src/main/java/org/collectionspace/services/authorization/storage/PermissionDocumentHandler.java b/services/common/src/main/java/org/collectionspace/services/authorization/storage/PermissionDocumentHandler.java index 5aed20f46..156ad27f6 100644 --- a/services/common/src/main/java/org/collectionspace/services/authorization/storage/PermissionDocumentHandler.java +++ b/services/common/src/main/java/org/collectionspace/services/authorization/storage/PermissionDocumentHandler.java @@ -29,11 +29,11 @@ import java.util.UUID; import javax.persistence.EntityExistsException; import javax.persistence.EntityManager; -import javax.persistence.EntityManagerFactory; import javax.persistence.NoResultException; import org.collectionspace.services.authorization.perms.ActionType; import org.collectionspace.services.authorization.CSpaceAction; +import org.collectionspace.services.authorization.RolesList; import org.collectionspace.services.authorization.perms.Permission; import org.collectionspace.services.authorization.perms.PermissionAction; import org.collectionspace.services.authorization.perms.PermissionsList; @@ -49,6 +49,7 @@ import org.collectionspace.services.common.document.JaxbUtils; import org.collectionspace.services.common.security.SecurityUtils; import org.collectionspace.services.common.storage.jpa.JpaDocumentHandler; import org.collectionspace.services.common.storage.jpa.JpaStorageUtils; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -57,7 +58,7 @@ import org.slf4j.LoggerFactory; * @author */ public class PermissionDocumentHandler - extends JpaDocumentHandler { + extends JpaDocumentHandler> { private final Logger logger = LoggerFactory.getLogger(PermissionDocumentHandler.class); private Permission permission; @@ -241,7 +242,7 @@ public class PermissionDocumentHandler } @Override - public void handleGetAll(DocumentWrapper wrapDoc) throws Exception { + public void handleGetAll(DocumentWrapper> wrapDoc) throws Exception { PermissionsList permissionsList = extractCommonPartList(wrapDoc); setCommonPartList(permissionsList); getServiceContext().setOutput(getCommonPartList()); @@ -251,6 +252,32 @@ public class PermissionDocumentHandler public void completeDelete(DocumentWrapper wrapDoc) throws Exception { } + /* + * See https://issues.collectionspace.org/browse/DRYD-181 + * + * For backward compatibility, we could not change the permission list to be a child class of AbstractCommonList. This + * would have change the result payload and would break existing API clients. So the best we can do, it treat + * the role list payload as a special case and return the paging information. + * + */ + protected PermissionsList extractPagingInfoForPerms(PermissionsList permList, DocumentWrapper> wrapDoc) + throws Exception { + + DocumentFilter docFilter = this.getDocumentFilter(); + long pageSize = docFilter.getPageSize(); + long pageNum = pageSize != 0 ? docFilter.getOffset() / pageSize : pageSize; + // set the page size and page number + permList.setPageNum(pageNum); + permList.setPageSize(pageSize); + List docList = wrapDoc.getWrappedObject(); + // Set num of items in list. this is useful to our testing framework. + permList.setItemsInPage(docList.size()); + // set the total result size + permList.setTotalItems(docFilter.getTotalItemsResult()); + + return permList; + } + @Override public Permission extractCommonPart( DocumentWrapper wrapDoc) @@ -266,10 +293,10 @@ public class PermissionDocumentHandler @Override public PermissionsList extractCommonPartList( - DocumentWrapper wrapDoc) + DocumentWrapper> wrapDoc) throws Exception { - PermissionsList permissionsList = new PermissionsList(); + PermissionsList permissionsList = extractPagingInfoForPerms(new PermissionsList(), wrapDoc); List list = new ArrayList(); permissionsList.setPermission(list); for (Object obj : wrapDoc.getWrappedObject()) { @@ -277,6 +304,7 @@ public class PermissionDocumentHandler sanitize(permission); list.add(permission); } + return permissionsList; } diff --git a/services/common/src/main/java/org/collectionspace/services/common/document/DocumentFilter.java b/services/common/src/main/java/org/collectionspace/services/common/document/DocumentFilter.java index b2c2150ad..cc885f10b 100644 --- a/services/common/src/main/java/org/collectionspace/services/common/document/DocumentFilter.java +++ b/services/common/src/main/java/org/collectionspace/services/common/document/DocumentFilter.java @@ -61,6 +61,11 @@ public abstract class DocumentFilter { /** The page size. */ protected int pageSize; // Pagination limit for list results + /** The total number of items for a query result -independent of paging restrictions. + * + */ + protected long totalItemsResult = -1; + //queryParams is not initialized as it would require a multi-valued map implementation //unless it is used from opensource lib...this variable holds ref to //implementation available in JBoss RESTeasy @@ -515,4 +520,18 @@ public abstract class DocumentFilter { protected String getTenantId() { return AuthN.get().getCurrentTenantId(); } + + /* + * Used to set the total number of items matching a query -independent of the paging restrictions. + */ + public void setTotalItemsResult(long totalItems) { + totalItemsResult = totalItems; + } + + /* + * Used to get the total number of items matching the last query made -independent of the paging restrictions. + */ + public long getTotalItemsResult() { + return totalItemsResult; + } } diff --git a/services/common/src/main/java/org/collectionspace/services/common/storage/jpa/JpaDocumentHandler.java b/services/common/src/main/java/org/collectionspace/services/common/storage/jpa/JpaDocumentHandler.java index c2d77bd06..152e12a49 100644 --- a/services/common/src/main/java/org/collectionspace/services/common/storage/jpa/JpaDocumentHandler.java +++ b/services/common/src/main/java/org/collectionspace/services/common/storage/jpa/JpaDocumentHandler.java @@ -50,7 +50,7 @@ public abstract class JpaDocumentHandler // Set num of items in list. this is useful to our testing framework. commonList.setItemsInPage(docList.size()); // set the total result size - commonList.setTotalItems(docList.size()); + commonList.setTotalItems(docFilter.getTotalItemsResult()); return (TL) commonList; } diff --git a/services/common/src/main/java/org/collectionspace/services/common/storage/jpa/JpaStorageClientImpl.java b/services/common/src/main/java/org/collectionspace/services/common/storage/jpa/JpaStorageClientImpl.java index 2e25788be..b5349389b 100644 --- a/services/common/src/main/java/org/collectionspace/services/common/storage/jpa/JpaStorageClientImpl.java +++ b/services/common/src/main/java/org/collectionspace/services/common/storage/jpa/JpaStorageClientImpl.java @@ -272,7 +272,11 @@ public class JpaStorageClientImpl implements StorageClient { //FIXME is transaction required for get? em.getTransaction().begin(); List list = q.getResultList(); + long totalItems = getTotalItems(em, ctx, handler); // Find out how many items our query would find independent of the paging restrictions em.getTransaction().commit(); + + docFilter.setTotalItemsResult(totalItems); // Save the items total in the doc filter for later reporting + DocumentWrapper wrapDoc = new DocumentWrapperImpl(list); handler.handle(Action.GET_ALL, wrapDoc); handler.complete(Action.GET_ALL, wrapDoc); @@ -290,7 +294,31 @@ public class JpaStorageClientImpl implements StorageClient { } } - /* (non-Javadoc) + /* + * Return the COUNT for a query to find the total number of matches independent of the paging restrictions. + */ + private long getTotalItems(EntityManager em, ServiceContext ctx, DocumentHandler handler) { + long result = -1; + + DocumentFilter docFilter = handler.getDocumentFilter(); + StringBuilder queryStrBldr = new StringBuilder("SELECT COUNT(*) FROM "); + queryStrBldr.append(getEntityName(ctx)); + queryStrBldr.append(" a"); + + List params = docFilter.buildWhereForSearch(queryStrBldr); + String queryStr = queryStrBldr.toString(); + Query q = em.createQuery(queryStr); + //bind parameters + for (DocumentFilter.ParamBinding p : params) { + q.setParameter(p.getName(), p.getValue()); + } + + result = (long) q.getSingleResult(); + + return result; + } + + /* (non-Javadoc) * @see org.collectionspace.services.common.storage.StorageClient#update(org.collectionspace.services.common.context.ServiceContext, java.lang.String, org.collectionspace.services.common.document.DocumentHandler) */ @Override diff --git a/services/hyperjaxb/src/main/resources/permissions_list.xsd b/services/hyperjaxb/src/main/resources/permissions_list.xsd index 2427a84df..f45fe2c53 100644 --- a/services/hyperjaxb/src/main/resources/permissions_list.xsd +++ b/services/hyperjaxb/src/main/resources/permissions_list.xsd @@ -41,6 +41,11 @@ permission configuration list + + + + + -- 2.47.3