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


The following commit(s) were added to refs/heads/feature/track-map-calls by 
this push:
     new 280ff7f  [WIP] Enhance map tracking to infer originating service
280ff7f is described below

commit 280ff7f9f2ef18c7621f9f20464eadbeba801974
Author: Robert Munteanu <[email protected]>
AuthorDate: Thu Apr 8 16:18:18 2021 +0200

    [WIP] Enhance map tracking to infer originating service
---
 .../resourceresolver/impl/mapping/MapTracker.java  | 54 ++++++++++++++++++++--
 .../impl/mapping/MapTrackerTest.java               | 28 +++++++++--
 2 files changed, 74 insertions(+), 8 deletions(-)

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
index 3ec7c4d..94d75fb 100644
--- 
a/src/main/java/org/apache/sling/resourceresolver/impl/mapping/MapTracker.java
+++ 
b/src/main/java/org/apache/sling/resourceresolver/impl/mapping/MapTracker.java
@@ -19,12 +19,18 @@
 package org.apache.sling.resourceresolver.impl.mapping;
 
 import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
 import java.util.Objects;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.atomic.AtomicInteger;
 
 import javax.servlet.http.HttpServletRequest;
 
+import org.apache.commons.lang3.StringUtils;
+import org.apache.sling.resourceresolver.impl.ResourceResolverImpl;
+
 public class MapTracker {
 
     private static final MapTracker INSTANCE = new MapTracker();
@@ -54,21 +60,59 @@ public class MapTracker {
     }
 
     static class Key {
+        private static final List<String> IGNORED_CLASS_NAMES = Arrays.asList(
+                ResourceResolverImpl.class.getName(),
+                ResourceMapperImpl.class.getName(),
+                MapTracker.class.getName(),
+                MapTracker.Key.class.getName());
+
+        private static final List<String> IGNORED_PACKAGE_PREFIXES = 
Arrays.asList(
+                "sun.reflect.",
+                "java.lang.reflect."
+        );
+
         private final String resourcePath;
-        private final String requestPath;
+        private final String requestor;
 
         public Key(String resourcePath, HttpServletRequest request) {
             this.resourcePath = resourcePath;
-            this.requestPath = request != null ? request.getRequestURI() : 
null;
+            this.requestor = request != null ? "REQUEST:" + 
request.getRequestURI() : "SERVICE:"+inferService();
+        }
+
+        private String inferService() {
+            Throwable origin = new RuntimeException().fillInStackTrace();
+            List<String> serviceChain = new ArrayList<>();
+            for ( StackTraceElement elem : origin.getStackTrace() ) {
+                if ( IGNORED_CLASS_NAMES.contains(elem.getClassName() ))
+                    continue;
+
+                boolean isIgnoredPackage = IGNORED_PACKAGE_PREFIXES.stream()
+                        .anyMatch( prefix -> 
elem.getClassName().startsWith(prefix) );
+
+                if ( isIgnoredPackage )
+                    continue;
+                serviceChain.add(elem.getClassName() + "." + 
elem.getMethodName());
+
+                if ( serviceChain.size() == 3) {
+                    return StringUtils.join(serviceChain, "|");
+                }
+            }
+
+            if ( !serviceChain.isEmpty() )
+                return StringUtils.join(serviceChain, "|");
+
+            return "UNKNOWN";
+
         }
 
+
         @Override
         public int hashCode() {
-            return Objects.hash(requestPath, resourcePath);
+            return Objects.hash(requestor, resourcePath);
         }
 
         public String getRequestPath() {
-            return requestPath;
+            return requestor;
         }
 
         public String getResourcePath() {
@@ -84,7 +128,7 @@ public class MapTracker {
             if (getClass() != obj.getClass())
                 return false;
             Key other = (Key) obj;
-            return Objects.equals(requestPath, other.requestPath) && 
Objects.equals(resourcePath, other.resourcePath);
+            return Objects.equals(requestor, other.requestor) && 
Objects.equals(resourcePath, other.resourcePath);
         }
 
 
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
index 11c8a22..f8ea6bf 100644
--- 
a/src/test/java/org/apache/sling/resourceresolver/impl/mapping/MapTrackerTest.java
+++ 
b/src/test/java/org/apache/sling/resourceresolver/impl/mapping/MapTrackerTest.java
@@ -22,10 +22,14 @@ 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 static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
 
 import java.io.PrintWriter;
 import java.io.StringWriter;
 
+import javax.servlet.http.HttpServletRequest;
+
 import org.junit.Test;
 
 public class MapTrackerTest {
@@ -38,22 +42,40 @@ public class MapTrackerTest {
         for (int i = 0; i < 10; i++)
             mt.trackMapCall("/content.html", null);
 
+        HttpServletRequest request = mock(HttpServletRequest.class);
+        when(request.getRequestURI()).thenReturn("/content/source.html");
+
+        for (int i = 0; i < 7; i++)
+            mt.trackMapCall("/content.html", request);
+
         for (int i = 0; i < 2; i++)
             mt.trackMapCall("/content/foo.html", null);
 
         for (int i = 0; i < 5; i++)
             mt.trackMapCall("/content/bar.html", null);
 
+        SomeService svc = new SomeService();
+
+        for (int i = 0; i < 3; i++)
+            svc.invoke(mt);
+
         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("Total lines", lines.length, equalTo(7));
         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")));
+        assertThat("First entry", lines[2],  allOf(containsString("7"), 
containsString("/content.html"), 
containsString("REQUEST:/content/source.html")));
+        assertThat("Third entry", lines[3],  allOf(containsString("5"), 
containsString("/content/bar.html")));
+        assertThat("Fourth entry", lines[4],  allOf(containsString("3"), 
containsString("/content/bar.html"), containsString("SomeService.invoke")));
+        assertThat("Fifth entry", lines[5],  allOf(containsString("2"), 
containsString("/content/foo.html")));
     }
 
+    static class SomeService {
+        public void invoke(MapTracker tracker) {
+            tracker.trackMapCall("/content/bar.html", null);
+        }
+    }
 }

Reply via email to