From 886313d3809808004d55bb725890e7329fafc83f Mon Sep 17 00:00:00 2001 From: Yegor Kozlov Date: Tue, 29 Oct 2024 23:09:26 +0300 Subject: [PATCH] #3443 Content Sync: don't drill down into content tree if recursion is off (#3452) * #3443 Content Sync: don't drill down into content tree if recursion is off --- CHANGELOG.md | 1 + all/pom.xml | 2 +- bundle-cloud/pom.xml | 2 +- bundle-onprem/pom.xml | 2 +- bundle/pom.xml | 2 +- .../commons/contentsync/ContentCatalog.java | 52 ++++++++++++++++++- .../impl/LastModifiedStrategy.java | 46 ++++++++++++---- .../acs/commons/contentsync/package-info.java | 2 +- .../impl/TestLastModifiedStrategy.java | 43 +++++++++------ oakpal-checks/pom.xml | 2 +- pom.xml | 2 +- ui.apps/pom.xml | 2 +- .../components/utilities/contentsync/POST.jsp | 5 +- ui.config/pom.xml | 2 +- ui.content/pom.xml | 2 +- 15 files changed, 125 insertions(+), 42 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 39721c863d..cee9db4055 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com) - ## Unreleased ([details][unreleased changes details]) +- #3443 - Content Sync: don't drill down into content tree if recursion is off ### Fixed - #3459 - Top level properties in parameterized include are now respected. diff --git a/all/pom.xml b/all/pom.xml index 9483980cd6..9ecca7ae78 100644 --- a/all/pom.xml +++ b/all/pom.xml @@ -25,7 +25,7 @@ com.adobe.acs acs-aem-commons - 6.8.1-SNAPSHOT + 6.9.0-SNAPSHOT diff --git a/bundle-cloud/pom.xml b/bundle-cloud/pom.xml index f29eb5eeba..36a04f3c94 100644 --- a/bundle-cloud/pom.xml +++ b/bundle-cloud/pom.xml @@ -25,7 +25,7 @@ com.adobe.acs acs-aem-commons - 6.8.1-SNAPSHOT + 6.9.0-SNAPSHOT diff --git a/bundle-onprem/pom.xml b/bundle-onprem/pom.xml index 2429be90c1..b2ab6a991b 100644 --- a/bundle-onprem/pom.xml +++ b/bundle-onprem/pom.xml @@ -25,7 +25,7 @@ com.adobe.acs acs-aem-commons - 6.8.1-SNAPSHOT + 6.9.0-SNAPSHOT diff --git a/bundle/pom.xml b/bundle/pom.xml index 8eeb267a82..a3ff0db54b 100644 --- a/bundle/pom.xml +++ b/bundle/pom.xml @@ -25,7 +25,7 @@ com.adobe.acs acs-aem-commons - 6.8.1-SNAPSHOT + 6.9.0-SNAPSHOT diff --git a/bundle/src/main/java/com/adobe/acs/commons/contentsync/ContentCatalog.java b/bundle/src/main/java/com/adobe/acs/commons/contentsync/ContentCatalog.java index da80dbecb1..abd4b82adf 100644 --- a/bundle/src/main/java/com/adobe/acs/commons/contentsync/ContentCatalog.java +++ b/bundle/src/main/java/com/adobe/acs/commons/contentsync/ContentCatalog.java @@ -36,6 +36,10 @@ import java.util.stream.Collectors; +/** + * The ContentCatalog class provides methods to fetch and process content catalogs + * from a remote instance. + */ public class ContentCatalog { private RemoteInstance remoteInstance; @@ -46,12 +50,48 @@ public ContentCatalog(RemoteInstance remoteInstance, String catalogServlet) { this.catalogServlet = catalogServlet; } + /** + * @deprecated use {@link #getFetchURI(String, String, boolean)} + */ + @Deprecated public URI getFetchURI(String path, String updateStrategy) throws URISyntaxException { - return remoteInstance.toURI(catalogServlet, "root", path, "strategy", updateStrategy); + return getFetchURI(path, updateStrategy, true); + } + + /** + * Gets the URI to fetch the catalog. + * + * @param path the path to fetch the catalog for + * @param updateStrategy the update strategy to use + * @param recursive whether to fetch recursively + * @return the URI to fetch the catalog + * @throws URISyntaxException if the URI syntax is incorrect + */ + public URI getFetchURI(String path, String updateStrategy, boolean recursive) throws URISyntaxException { + return remoteInstance.toURI(catalogServlet, "root", path, "strategy", + updateStrategy, "recursive", String.valueOf(recursive)); } + /** + * @deprecated use {@link #fetch(String, String, boolean)} + */ + @Deprecated public List fetch(String path, String updateStrategy) throws IOException, URISyntaxException { - URI uri = getFetchURI(path, updateStrategy); + return fetch(path, updateStrategy, true); + } + + /** + * Fetches the catalog items from the remote instance. + * + * @param path the path to fetch the catalog for + * @param updateStrategy the update strategy to use + * @param recursive whether to fetch recursively + * @return a list of catalog items + * @throws IOException if an I/O error occurs + * @throws URISyntaxException if the URI syntax is incorrect + */ + public List fetch(String path, String updateStrategy, boolean recursive) throws IOException, URISyntaxException { + URI uri = getFetchURI(path, updateStrategy, recursive); String json = remoteInstance.getString(uri); @@ -70,6 +110,14 @@ public List fetch(String path, String updateStrategy) throws IOExce .collect(Collectors.toList()); } + /** + * Gets the delta between the catalog items and the resources in the resource resolver. + * + * @param catalog the list of catalog items + * @param resourceResolver the resource resolver to check against + * @param updateStrategy the update strategy to use + * @return a list of catalog items that are modified or not present in the resource resolver + */ public List getDelta(List catalog, ResourceResolver resourceResolver, UpdateStrategy updateStrategy) { List lst = new ArrayList<>(); for(CatalogItem item : catalog){ diff --git a/bundle/src/main/java/com/adobe/acs/commons/contentsync/impl/LastModifiedStrategy.java b/bundle/src/main/java/com/adobe/acs/commons/contentsync/impl/LastModifiedStrategy.java index 41c31ee888..2c9f38596d 100644 --- a/bundle/src/main/java/com/adobe/acs/commons/contentsync/impl/LastModifiedStrategy.java +++ b/bundle/src/main/java/com/adobe/acs/commons/contentsync/impl/LastModifiedStrategy.java @@ -54,33 +54,50 @@ public class LastModifiedStrategy implements UpdateStrategy { @Reference private ServletResolver servletResolver; + /** + * The ContentCatalog class provides methods to fetch and process content catalogs + * from a remote instance. + */ @Override public List getItems(SlingHttpServletRequest request) { String rootPath = request.getParameter("root"); if (rootPath == null) { throw new IllegalArgumentException("root request parameter is required"); } - boolean recursive = "true".equals(request.getParameter("recursive")); + boolean nonRecursive = "false".equals(request.getParameter("recursive")); Resource root = request.getResourceResolver().getResource(rootPath); if (root == null) { return Collections.emptyList(); } List items = new ArrayList<>(); - new AbstractResourceVisitor() { - @Override - public void visit(Resource res) { - if ((!recursive && !res.getPath().equals(root.getPath())) || !accepts(res)) { - return; + if (nonRecursive) { + JsonObjectBuilder json = Json.createObjectBuilder(); + writeMetadata(json, root, request); + items.add(new CatalogItem(json.build())); + } else { + new AbstractResourceVisitor() { + @Override + public void visit(Resource res) { + if (!accepts(res)) { + return; + } + JsonObjectBuilder json = Json.createObjectBuilder(); + writeMetadata(json, res, request); + items.add(new CatalogItem(json.build())); } - JsonObjectBuilder json = Json.createObjectBuilder(); - writeMetadata(json, res, request); - items.add(new CatalogItem(json.build())); - } - }.accept(root); + }.accept(root); + } return items; } + /** + * Checks if the remote resource is modified compared to the local resource. + * + * @param remoteResource the remote catalog item + * @param localResource the local resource + * @return true if the remote resource is modified, false otherwise + */ @Override public boolean isModified(CatalogItem remoteResource, Resource localResource) { LastModifiedInfo remoteLastModified = getLastModified(remoteResource); @@ -89,6 +106,13 @@ public boolean isModified(CatalogItem remoteResource, Resource localResource) { return remoteLastModified.getLastModified() > localLastModified.getLastModified(); } + /** + * Generates a message indicating the modification status of the resource. + * + * @param remoteResource the remote catalog item + * @param localResource the local resource + * @return a message indicating the modification status + */ @Override @SuppressWarnings("squid:S2583") public String getMessage(CatalogItem remoteResource, Resource localResource) { diff --git a/bundle/src/main/java/com/adobe/acs/commons/contentsync/package-info.java b/bundle/src/main/java/com/adobe/acs/commons/contentsync/package-info.java index 7350e1cc41..6a8ead1f49 100644 --- a/bundle/src/main/java/com/adobe/acs/commons/contentsync/package-info.java +++ b/bundle/src/main/java/com/adobe/acs/commons/contentsync/package-info.java @@ -17,5 +17,5 @@ * limitations under the License. * #L% */ -@org.osgi.annotation.versioning.Version("1.2.0") +@org.osgi.annotation.versioning.Version("1.3.0") package com.adobe.acs.commons.contentsync; diff --git a/bundle/src/test/java/com/adobe/acs/commons/contentsync/impl/TestLastModifiedStrategy.java b/bundle/src/test/java/com/adobe/acs/commons/contentsync/impl/TestLastModifiedStrategy.java index 195c87eb53..6da09dfee1 100644 --- a/bundle/src/test/java/com/adobe/acs/commons/contentsync/impl/TestLastModifiedStrategy.java +++ b/bundle/src/test/java/com/adobe/acs/commons/contentsync/impl/TestLastModifiedStrategy.java @@ -84,6 +84,9 @@ public void testLastModifiedNA() { assertFalse(updateStrategy.isModified(new CatalogItem(catalogItem), pageResource)); } + /** + * isModified() returns true if the resource is newer + */ @Test public void testPageModified() { String pagePath = "/content/wknd/page"; @@ -200,8 +203,7 @@ public void testCustomExporter() { assertEquals(customExporter, item.getCustomExporter()); } - @Test - public void testRecursive() { + void sync(String ... requestParams) { doAnswer(invocation -> { GenericServlet servlet = mock(GenericServlet.class); doReturn(REDIRECT_SERVLET).when(servlet).getServletName(); @@ -213,28 +215,35 @@ public void testRecursive() { context.create().page("/content/wknd/en/home"); MockSlingHttpServletRequest request = context.request(); - request.addRequestParameter("root", "/content/wknd"); - request.addRequestParameter("recursive", "true"); + for(int i = 0; i < requestParams.length; i += 2){ + request.addRequestParameter(requestParams[i], requestParams[i + 1]); + } + } - List items = updateStrategy.getItems(request); + @Test + public void testRecursive() { + sync("root", "/content/wknd", + "recursive", "true"); + + List items = updateStrategy.getItems(context.request()); assertEquals(3, items.size()); } @Test - public void testNonRecursive() { - doAnswer(invocation -> { - GenericServlet servlet = mock(GenericServlet.class); - doReturn(REDIRECT_SERVLET).when(servlet).getServletName(); - return servlet; - }).when(servletResolver).resolveServlet(any(SlingHttpServletRequest.class)); + public void testRecursiveDefault() { + sync("root", "/content/wknd"); - context.create().page("/content/wknd"); - context.create().page("/content/wknd/en"); - context.create().page("/content/wknd/en/home"); - MockSlingHttpServletRequest request = context.request(); - request.addRequestParameter("root", "/content/wknd"); + List items = updateStrategy.getItems(context.request()); + assertEquals(3, items.size()); + } - List items = updateStrategy.getItems(request); + @Test + public void testNonRecursive() { + sync("root", "/content/wknd", + "recursive", "false"); + + List items = updateStrategy.getItems(context.request()); assertEquals(1, items.size()); } + } diff --git a/oakpal-checks/pom.xml b/oakpal-checks/pom.xml index 41a735fc5e..d1117c8b08 100644 --- a/oakpal-checks/pom.xml +++ b/oakpal-checks/pom.xml @@ -25,7 +25,7 @@ com.adobe.acs acs-aem-commons - 6.8.1-SNAPSHOT + 6.9.0-SNAPSHOT diff --git a/pom.xml b/pom.xml index 92f25675b6..0adb48f4be 100644 --- a/pom.xml +++ b/pom.xml @@ -25,7 +25,7 @@ com.adobe.acs acs-aem-commons - 6.8.1-SNAPSHOT + 6.9.0-SNAPSHOT pom ACS AEM Commons - Reactor Project diff --git a/ui.apps/pom.xml b/ui.apps/pom.xml index 5ce6bc7285..ed7fb4e685 100644 --- a/ui.apps/pom.xml +++ b/ui.apps/pom.xml @@ -25,7 +25,7 @@ com.adobe.acs acs-aem-commons - 6.8.1-SNAPSHOT + 6.9.0-SNAPSHOT diff --git a/ui.apps/src/main/content/jcr_root/apps/acs-commons/components/utilities/contentsync/POST.jsp b/ui.apps/src/main/content/jcr_root/apps/acs-commons/components/utilities/contentsync/POST.jsp index d252999fd1..89497786b5 100755 --- a/ui.apps/src/main/content/jcr_root/apps/acs-commons/components/utilities/contentsync/POST.jsp +++ b/ui.apps/src/main/content/jcr_root/apps/acs-commons/components/utilities/contentsync/POST.jsp @@ -70,6 +70,7 @@ boolean incremental = request.getParameter("incremental") != null; boolean createVersion = request.getParameter("createVersion") != null; boolean delete = request.getParameter("delete") != null; + boolean recursive = request.getParameter("recursive") != null; ValueMap generalSettings = ConfigurationUtils.getSettingsResource(resourceResolver).getValueMap(); @@ -96,10 +97,10 @@ ContentSync contentSync = new ContentSync(remoteInstance, resourceResolver, importer); ContentCatalog contentCatalog = new ContentCatalog(remoteInstance, catalogServlet); - println(printWriter, "building catalog from " + contentCatalog.getFetchURI(root, strategyPid) ); + println(printWriter, "building catalog from " + contentCatalog.getFetchURI(root, strategyPid, recursive) ); out.flush(); List catalog; - List remoteItems = contentCatalog.fetch(root, strategyPid); + List remoteItems = contentCatalog.fetch(root, strategyPid, recursive); long t0 = System.currentTimeMillis(); println(printWriter, remoteItems.size() + " resource"+(remoteItems.size() == 1 ? "" : "s")+" fetched in " + (System.currentTimeMillis() - t0) + " ms"); if(incremental){ diff --git a/ui.config/pom.xml b/ui.config/pom.xml index 4d54209d57..c29a4caf6a 100644 --- a/ui.config/pom.xml +++ b/ui.config/pom.xml @@ -25,7 +25,7 @@ com.adobe.acs acs-aem-commons - 6.8.1-SNAPSHOT + 6.9.0-SNAPSHOT diff --git a/ui.content/pom.xml b/ui.content/pom.xml index 58e7b84304..0a3441e0e9 100644 --- a/ui.content/pom.xml +++ b/ui.content/pom.xml @@ -25,7 +25,7 @@ com.adobe.acs acs-aem-commons - 6.8.1-SNAPSHOT + 6.9.0-SNAPSHOT