This is an automated email from the ASF dual-hosted git repository. rombert pushed a commit to branch feature/track-map-calls in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-resourceresolver.git
commit 40a59145c21dfdeb6f33a77cb73391ac26cc31d5 Author: Robert Munteanu <[email protected]> AuthorDate: Thu Apr 8 13:32:21 2021 +0200 [WIP] Add basic tracking of map() calls --- .../console/ResourceResolverWebConsolePlugin.java | 24 ++++++++- .../resourceresolver/impl/mapping/MapTracker.java | 55 ++++++++++++++++++++ .../impl/mapping/ResourceMapperImpl.java | 1 + .../impl/mapping/MapTrackerTest.java | 59 ++++++++++++++++++++++ 4 files changed, 137 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/apache/sling/resourceresolver/impl/console/ResourceResolverWebConsolePlugin.java b/src/main/java/org/apache/sling/resourceresolver/impl/console/ResourceResolverWebConsolePlugin.java index 99d7276..b4bbfcf 100644 --- a/src/main/java/org/apache/sling/resourceresolver/impl/console/ResourceResolverWebConsolePlugin.java +++ b/src/main/java/org/apache/sling/resourceresolver/impl/console/ResourceResolverWebConsolePlugin.java @@ -51,6 +51,7 @@ import org.apache.sling.resourceresolver.impl.helper.URI; import org.apache.sling.resourceresolver.impl.helper.URIException; import org.apache.sling.resourceresolver.impl.mapping.MapEntriesHandler; import org.apache.sling.resourceresolver.impl.mapping.MapEntry; +import org.apache.sling.resourceresolver.impl.mapping.MapTracker; import org.apache.sling.spi.resource.provider.ResourceProvider; import org.osgi.framework.BundleContext; import org.osgi.framework.Constants; @@ -66,6 +67,8 @@ public class ResourceResolverWebConsolePlugin extends HttpServlet { private static final String ATTR_SUBMIT = "plugin.submit"; + private static final String ATTR_CLEAR_MAP_TRACKING = "plugin.clearMapTracking"; + private static final String PAR_MSG = "msg"; private static final String PAR_TEST = "test"; @@ -84,7 +87,7 @@ public class ResourceResolverWebConsolePlugin extends HttpServlet { this.runtimeService = runtimeService; this.bundleContext = context; - Dictionary<String, Object> props = new Hashtable<String, Object>(); + Dictionary<String, Object> props = new Hashtable<>(); props.put(Constants.SERVICE_DESCRIPTION, "Apache Sling Resource Resolver Web Console Plugin"); props.put(Constants.SERVICE_VENDOR, "The Apache Software Foundation"); @@ -202,6 +205,19 @@ public class ResourceResolverWebConsolePlugin extends HttpServlet { separatorHtml(pw); + titleHtml(pw, "Map calls tracking data", "In-memory cache tracking all calls to map()"); + + pw.println("<tr class='content'><td class='content' colspan='3'>"); + pw.println("<form method='post'>"); + pw.println("<input type='submit' name='" + ATTR_CLEAR_MAP_TRACKING + "' class='submit' value='Clear map tracking data'>"); + pw.println("</form>"); + pw.println("</td></tr class='content'>"); + + pw.println("<tr class='content'><td class='content' colspan='3'><pre>"); + MapTracker.get().dump(pw); + pw.println("</pre></td></tr class='content'>"); + separatorHtml(pw); + dumpDTOsHtml(pw); pw.println("</table>"); @@ -252,6 +268,10 @@ public class ResourceResolverWebConsolePlugin extends HttpServlet { } + if ( request.getParameter(ATTR_CLEAR_MAP_TRACKING) != null ) { + MapTracker.get().clear(); + } + // finally redirect final String path = request.getContextPath() + request.getServletPath() + request.getPathInfo(); @@ -326,7 +346,7 @@ public class ResourceResolverWebConsolePlugin extends HttpServlet { pw.println("<th class='content'>Redirect</th>"); pw.println("</tr>"); - final Set<String> usedPatterns = new HashSet<String>(); + final Set<String> usedPatterns = new HashSet<>(); for (final MapEntry entry : list) { final String pattern = entry.getPattern(); diff --git a/src/main/java/org/apache/sling/resourceresolver/impl/mapping/MapTracker.java b/src/main/java/org/apache/sling/resourceresolver/impl/mapping/MapTracker.java new file mode 100644 index 0000000..253261b --- /dev/null +++ b/src/main/java/org/apache/sling/resourceresolver/impl/mapping/MapTracker.java @@ -0,0 +1,55 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.sling.resourceresolver.impl.mapping; + +import java.io.PrintWriter; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicInteger; + +public class MapTracker { + + public static void main(String[] args) { + } + + private static final MapTracker INSTANCE = new MapTracker(); + + public static MapTracker get() { + return INSTANCE; + } + + private final ConcurrentHashMap<String, AtomicInteger> calls = new ConcurrentHashMap<>(); + + public void trackMapCall(String resourcePath) { + calls.computeIfAbsent(resourcePath, path -> new AtomicInteger(0)).incrementAndGet(); + } + + public void dump(PrintWriter pw) { + pw.println("--- SUMMARY OF RECORDED MAP CALLS ---"); + + calls.entrySet() + .stream() + .sorted( (first, second) -> Integer.compare(second.getValue().get(), first.getValue().get()) ) + .forEachOrdered( entry -> pw.printf("%10d\t%s%n", entry.getValue().get(), entry.getKey())); + pw.println("--- END ---"); + } + + public void clear() { + calls.clear(); + } +} diff --git a/src/main/java/org/apache/sling/resourceresolver/impl/mapping/ResourceMapperImpl.java b/src/main/java/org/apache/sling/resourceresolver/impl/mapping/ResourceMapperImpl.java index b44789d..ed83a1d 100644 --- a/src/main/java/org/apache/sling/resourceresolver/impl/mapping/ResourceMapperImpl.java +++ b/src/main/java/org/apache/sling/resourceresolver/impl/mapping/ResourceMapperImpl.java @@ -86,6 +86,7 @@ public class ResourceMapperImpl implements ResourceMapper { public Collection<String> getAllMappings(String resourcePath, HttpServletRequest request) { resolver.checkClosed(); + MapTracker.get().trackMapCall(resourcePath); // A note on the usage of the 'mappings' variable and the order of the results // diff --git a/src/test/java/org/apache/sling/resourceresolver/impl/mapping/MapTrackerTest.java b/src/test/java/org/apache/sling/resourceresolver/impl/mapping/MapTrackerTest.java new file mode 100644 index 0000000..7e41443 --- /dev/null +++ b/src/test/java/org/apache/sling/resourceresolver/impl/mapping/MapTrackerTest.java @@ -0,0 +1,59 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.sling.resourceresolver.impl.mapping; + +import static org.hamcrest.CoreMatchers.allOf; +import static org.hamcrest.CoreMatchers.containsString; +import static org.hamcrest.CoreMatchers.equalTo; +import static org.junit.Assert.assertThat; + +import java.io.PrintWriter; +import java.io.StringWriter; + +import org.junit.Test; + +public class MapTrackerTest { + + @Test + public void smokeTest() { + MapTracker mt = MapTracker.get(); + mt.clear(); + + for (int i = 0; i < 10; i++) + mt.trackMapCall("/content.html"); + + for (int i = 0; i < 2; i++) + mt.trackMapCall("/content/foo.html"); + + for (int i = 0; i < 5; i++) + mt.trackMapCall("/content/bar.html"); + + StringWriter out = new StringWriter(); + mt.dump(new PrintWriter(out)); + mt.dump(new PrintWriter(System.out, true)); + + String[] lines = out.toString().split("\\n"); + + assertThat("Total lines", lines.length, equalTo(5)); + assertThat("First entry", lines[1], allOf(containsString("10"), containsString("/content.html"))); + assertThat("Second entry", lines[2], allOf(containsString("5"), containsString("/content/bar.html"))); + assertThat("Third entry", lines[3], allOf(containsString("2"), containsString("/content/foo.html"))); + } + +}
