diff --git a/pom.xml b/pom.xml index b42f91fcc8..6e05a8972b 100644 --- a/pom.xml +++ b/pom.xml @@ -63,7 +63,7 @@ 3.3.7 1.0.0 2.0.21 - 8.8 + 8.10 1.66 3.5.11 20090211 diff --git a/remote-api/src/main/java/org/alfresco/rest/api/impl/AuditImpl.java b/remote-api/src/main/java/org/alfresco/rest/api/impl/AuditImpl.java index fdb865fc99..344bb73520 100644 --- a/remote-api/src/main/java/org/alfresco/rest/api/impl/AuditImpl.java +++ b/remote-api/src/main/java/org/alfresco/rest/api/impl/AuditImpl.java @@ -280,21 +280,28 @@ public class AuditImpl implements Audit // clear null elements entriesAudit.removeAll(Collections.singleton(null)); - int totalItems = entriesAudit.size(); + int totalRetrievedItems = entriesAudit.size(); + int end = Math.min(limit - 1, totalRetrievedItems); + boolean hasMoreItems = totalRetrievedItems > end; - if (skipCount >= totalItems) + String omitTotalItemsParameter = parameters.getParameter("omitTotalItems"); + boolean omitTotalItems = (null != omitTotalItemsParameter) && Boolean.parseBoolean(omitTotalItemsParameter); + + Integer totalItems; + + if (omitTotalItems) { - List empty = Collections.emptyList(); - return CollectionWithPagingInfo.asPaged(paging, empty, false, totalItems); + totalItems = null; } else { - int end = Math.min(limit - 1, totalItems); - boolean hasMoreItems = totalItems > end; - - entriesAudit = entriesAudit.subList(skipCount, end); - return CollectionWithPagingInfo.asPaged(paging, entriesAudit, hasMoreItems, totalItems); + totalItems = hasMoreItems ? getAuditEntriesCountByApp(auditApplication) : totalRetrievedItems; } + + entriesAudit = (skipCount >= totalRetrievedItems) + ? Collections.emptyList() + : entriesAudit.subList(skipCount, end); + return CollectionWithPagingInfo.asPaged(paging, entriesAudit, hasMoreItems, totalItems); } /** @@ -882,4 +889,10 @@ public class AuditImpl implements Audit } } + + public int getAuditEntriesCountByApp(AuditService.AuditApplication auditApplication) + { + final String applicationName = auditApplication.getKey().substring(1); + return auditService.getAuditEntriesCountByApp(applicationName); + } } diff --git a/remote-api/src/test/java/org/alfresco/rest/api/tests/AuditAppTest.java b/remote-api/src/test/java/org/alfresco/rest/api/tests/AuditAppTest.java index 630e32d44b..a96d9b6db3 100644 --- a/remote-api/src/test/java/org/alfresco/rest/api/tests/AuditAppTest.java +++ b/remote-api/src/test/java/org/alfresco/rest/api/tests/AuditAppTest.java @@ -26,6 +26,7 @@ package org.alfresco.rest.api.tests; import static org.alfresco.rest.api.tests.util.RestApiUtil.toJsonAsStringNonNull; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; @@ -405,6 +406,31 @@ public class AuditAppTest extends AbstractSingleNetworkSiteTest validateAuditEntryFields(ae, auditApp); } + // MNT-21936 Audit query Rest API does not return the correct totalItems + int auditEntriesTotalItems = auditEntries.getPaging().getTotalItems(); + + // set maxItems to 1 + Map params = new HashMap<>(); + params.put("maxItems","1"); + + auditEntries = auditAppsProxy.getAuditAppEntries(auditApp.getId(), params, + HttpServletResponse.SC_OK); + + int AuditEntriesTotalItemsAfterLimit = auditEntries.getPaging().getTotalItems(); + int retrievedAuditEntriesCount = auditEntries.getPaging().getCount(); + // When totalItems are retrieved using getAuditEntriesCountByApp() method that was introduced in MNT-21936 + // 2 audit entries will be created. + assertEquals(auditEntriesTotalItems + 2, AuditEntriesTotalItemsAfterLimit); + assertEquals(1, retrievedAuditEntriesCount); + + // set omitTotalItems to true. + params.put("omitTotalItems", "true"); + auditEntries = auditAppsProxy.getAuditAppEntries(auditApp.getId(), params, + HttpServletResponse.SC_OK); + + // verify that totalItems is null. + assertNull(auditEntries.getPaging().getTotalItems()); + // Negative tests // 401 setRequestContext(networkOne.getId(), networkAdmin, "wrongPassword"); diff --git a/repository/src/main/java/org/alfresco/repo/audit/AuditComponent.java b/repository/src/main/java/org/alfresco/repo/audit/AuditComponent.java index 88ffcbb65d..49e400b582 100644 --- a/repository/src/main/java/org/alfresco/repo/audit/AuditComponent.java +++ b/repository/src/main/java/org/alfresco/repo/audit/AuditComponent.java @@ -261,4 +261,15 @@ public interface AuditComponent * @return a map containing min/max and the associated value */ HashMap getAuditMinMaxByApp(String applicationName, List extremes); + + /** + * Issue an audit query to retrieve count of records for a given application. + * + * @param applicationName the name of the application + * @return a map containing min/max and the associated value + */ + default int getAuditEntriesCountByApp(String applicationName) + { + return -1; + } } diff --git a/repository/src/main/java/org/alfresco/repo/audit/AuditComponentImpl.java b/repository/src/main/java/org/alfresco/repo/audit/AuditComponentImpl.java index 89d9d6a623..18b464c674 100644 --- a/repository/src/main/java/org/alfresco/repo/audit/AuditComponentImpl.java +++ b/repository/src/main/java/org/alfresco/repo/audit/AuditComponentImpl.java @@ -941,4 +941,18 @@ public class AuditComponentImpl implements AuditComponent return auditDAO.getAuditMinMaxByApp(applicationId, extremes); } + + @Override + public int getAuditEntriesCountByApp(String applicationName) + { + // Get the id for the application + AuditApplication app = auditModelRegistry.getAuditApplicationByName(applicationName); + Long applicationId = app.getApplicationId(); + if (applicationId == null) + { + throw new AuditException("No persisted instance exists for audit application: " + app); + } + + return auditDAO.getAuditEntriesCountByApp(applicationId); + } } diff --git a/repository/src/main/java/org/alfresco/repo/audit/AuditServiceImpl.java b/repository/src/main/java/org/alfresco/repo/audit/AuditServiceImpl.java index 51150e709a..0b96cc9304 100644 --- a/repository/src/main/java/org/alfresco/repo/audit/AuditServiceImpl.java +++ b/repository/src/main/java/org/alfresco/repo/audit/AuditServiceImpl.java @@ -177,4 +177,13 @@ public class AuditServiceImpl implements AuditService { return auditComponent.getAuditMinMaxByApp(applicationName, extremes); } + + /** + * {@inheritDoc} + */ + @Override + public int getAuditEntriesCountByApp(String applicationName) + { + return auditComponent.getAuditEntriesCountByApp(applicationName); + } } \ No newline at end of file diff --git a/repository/src/main/java/org/alfresco/repo/domain/audit/AuditDAO.java b/repository/src/main/java/org/alfresco/repo/domain/audit/AuditDAO.java index a435d04485..22180ea78b 100644 --- a/repository/src/main/java/org/alfresco/repo/domain/audit/AuditDAO.java +++ b/repository/src/main/java/org/alfresco/repo/domain/audit/AuditDAO.java @@ -233,4 +233,15 @@ public interface AuditDAO * @return a map containing min/max and the associated value */ HashMap getAuditMinMaxByApp(long appId, List extremes); + + /** + * Issue an audit query to retrieve count of records for a given application. + * + * @param applicationId the database id of the application + * @return a map containing min/max and the associated value + */ + default int getAuditEntriesCountByApp(long applicationId) + { + return -1; + } } \ No newline at end of file diff --git a/repository/src/main/java/org/alfresco/repo/domain/audit/ibatis/AuditDAOImpl.java b/repository/src/main/java/org/alfresco/repo/domain/audit/ibatis/AuditDAOImpl.java index 8137c0fec8..58c97a9fa6 100644 --- a/repository/src/main/java/org/alfresco/repo/domain/audit/ibatis/AuditDAOImpl.java +++ b/repository/src/main/java/org/alfresco/repo/domain/audit/ibatis/AuditDAOImpl.java @@ -65,6 +65,7 @@ public class AuditDAOImpl extends AbstractAuditDAOImpl private static final String DELETE_ENTRIES_BY_ID = "alfresco.audit.delete_AuditEntriesById"; private static final String INSERT_ENTRY = "alfresco.audit.insert.insert_AuditEntry"; private static final String SELECT_MINMAX_ENTRY_FOR_APP = "alfresco.audit.select_MinMaxAuditEntryId"; + private static final String SELECT_COUNT_ENTRIES_FOR_APP = "alfresco.audit.select_CountAuditEntryId"; @SuppressWarnings("unused") private static final String SELECT_ENTRIES_SIMPLE = "alfresco.audit.select_AuditEntriesSimple"; @@ -223,6 +224,17 @@ public class AuditDAOImpl extends AbstractAuditDAOImpl return result; } + @Override + public int getAuditEntriesCountByApp(long applicationId) + { + Map params = new HashMap<>(); + params.put("auditAppId", applicationId); + + int result = template.selectOne(SELECT_COUNT_ENTRIES_FOR_APP, params); + + return result; + } + @SuppressWarnings("unchecked") @Override protected void findAuditEntries( diff --git a/repository/src/main/java/org/alfresco/service/cmr/audit/AuditService.java b/repository/src/main/java/org/alfresco/service/cmr/audit/AuditService.java index 24bfd36e1a..7f1e2ab264 100644 --- a/repository/src/main/java/org/alfresco/service/cmr/audit/AuditService.java +++ b/repository/src/main/java/org/alfresco/service/cmr/audit/AuditService.java @@ -241,4 +241,15 @@ public interface AuditService * @return a map containing min/max and the associated value */ HashMap getAuditMinMaxByApp(String applicationName, List extremes); + + /** + * Issue an audit query to retrieve min / max audit record id for a given application. + * + * @param applicationName the name of the application + * @return a map containing min/max and the associated value + */ + default int getAuditEntriesCountByApp(String applicationName) + { + return -1; + } } diff --git a/repository/src/main/resources/alfresco/ibatis/org.alfresco.repo.domain.dialect.Dialect/audit-common-SqlMap.xml b/repository/src/main/resources/alfresco/ibatis/org.alfresco.repo.domain.dialect.Dialect/audit-common-SqlMap.xml index 85ffdfe12d..b9adc28823 100644 --- a/repository/src/main/resources/alfresco/ibatis/org.alfresco.repo.domain.dialect.Dialect/audit-common-SqlMap.xml +++ b/repository/src/main/resources/alfresco/ibatis/org.alfresco.repo.domain.dialect.Dialect/audit-common-SqlMap.xml @@ -59,6 +59,10 @@ + + + + @@ -277,6 +281,16 @@ + + +