Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue 29711 analytics matcher layer #29755

Merged
merged 36 commits into from
Sep 3, 2024
Merged
Show file tree
Hide file tree
Changes from 27 commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
cf827da
Revert "fix: #28563 removing template ajax (#28572)"
jdotcms May 15, 2024
fb39637
Merge branch 'master' of github.com:dotCMS/core
jdotcms Jun 11, 2024
af6fed1
Merge branch 'master' of github.com:dotCMS/core
jdotcms Jun 14, 2024
96dd743
Merge branch 'master' of github.com:dotCMS/core
jdotcms Jun 18, 2024
fb71cf9
Merge branch 'master' of github.com:dotCMS/core
jdotcms Jun 24, 2024
ae1d5e1
Merge branches 'master' and 'master' of github.com:dotCMS/core
jdotcms Jun 25, 2024
b523af6
Merge branch 'master' of github.com:dotCMS/core
jdotcms Jun 27, 2024
95de159
Merge branch 'master' of github.com:dotCMS/core
jdotcms Jun 27, 2024
679b600
Merge branch 'master' of github.com:dotCMS/core
jdotcms Jun 28, 2024
4bb207b
Merge branch 'master' of github.com:dotCMS/core
jdotcms Jul 2, 2024
320b4b1
Merge branches 'master' and 'master' of github.com:dotCMS/core
jdotcms Jul 2, 2024
ed6a751
Merge branches 'master' and 'master' of github.com:dotCMS/core
jdotcms Jul 3, 2024
02a6e96
Merge branch 'master' of github.com:dotCMS/core
jdotcms Jul 4, 2024
5479786
Merge branch 'master' of github.com:dotCMS/core
jdotcms Jul 5, 2024
0762192
Merge branch 'master' of github.com:dotCMS/core
jdotcms Jul 9, 2024
2a61c7f
Merge branch 'master' of github.com:dotCMS/core
jdotcms Jul 11, 2024
0afad59
Merge branch 'master' of github.com:dotCMS/core
jdotcms Jul 17, 2024
9c510e7
Merge branch 'master' of github.com:dotCMS/core
jdotcms Jul 18, 2024
24a5827
Merge branch 'master' of github.com:dotCMS/core
jdotcms Jul 19, 2024
7468cd7
Merge branch 'master' of github.com:dotCMS/core
jdotcms Jul 22, 2024
0388022
Merge branch 'master' of github.com:dotCMS/core
jdotcms Jul 29, 2024
162ade1
Merge branch 'master' of github.com:dotCMS/core
jdotcms Aug 19, 2024
1e9be41
Merge branch 'master' of github.com:dotCMS/core
jdotcms Aug 21, 2024
17cac16
Merge branch 'master' of github.com:dotCMS/core
jdotcms Aug 21, 2024
ff615f0
Merge branch 'master' of github.com:dotCMS/core
jdotcms Aug 27, 2024
e2f47be
#29711 adding first draft for matcher layer
jdotcms Aug 27, 2024
c50e2c0
#29711 adding first draft for matcher layer
jdotcms Aug 27, 2024
1a8af52
#29711 getting closer to the matcher goal
jdotcms Aug 27, 2024
9e726ef
#29711 getting closer to the matcher goal
jdotcms Aug 27, 2024
ebec8f7
#29711 getting closer to the matcher goal
jdotcms Aug 27, 2024
a9a2243
#29711 getting closer to the matcher goal
jdotcms Aug 27, 2024
ba9fe4a
#29711 getting closer to the matcher goal
jdotcms Aug 27, 2024
df89ff7
#29711 getting closer to the matcher goal
jdotcms Aug 28, 2024
a6b6356
#29711 getting closer to the matcher goal
jdotcms Aug 29, 2024
ced4826
#29711 adding test fix
jdotcms Sep 3, 2024
3632da0
Merge branch 'master' into issue-29711-analytics-matcher-layer
jdotcms Sep 3, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
106 changes: 106 additions & 0 deletions dotCMS/src/main/java/com/dotcms/analytics/track/RequestMatcher.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
package com.dotcms.analytics.track;

import com.dotmarketing.util.Config;
import com.dotmarketing.util.RegEX;

import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.Objects;
import java.util.Set;

/**
* Matcher to include the tracking for analytics of some request.
*
* @author jsanca
*/
public interface RequestMatcher {

String CHARSET = Config.getStringProperty("CHARSET", "UTF-8");

/**
* Return true if match the request with the patterns and methods
* @param request {@link HttpServletRequest}
* @return boolean true if the request match the patterns and methods
*/
default boolean match(final HttpServletRequest request) {

final Set<String> patterns = getMatcherPatterns();
final Set<String> methods = getAllowedMethods();
return Objects.nonNull(patterns) && !patterns.isEmpty() &&
Objects.nonNull(methods) && !methods.isEmpty() &&
isAllowedMethod (methods, request.getMethod()) &&
match(request, patterns);
}

/**
* Match the request with the patterns
* @param request {@link HttpServletRequest}
* @param patterns Set of patterns
* @return boolean true if any of the patterns match the request
*/
default boolean match(final HttpServletRequest request, final Set<String> patterns) {

final String requestURI = request.getRequestURI();
return patterns.stream().anyMatch(pattern -> match(requestURI, pattern));
}

/**
* Match the request URI with the pattern
* @param requestURI String
* @param pattern String
* @return boolean true if the pattern match the request URI
*/
default boolean match (final String requestURI, final String pattern) {

String uftUri = null;

try {

uftUri = URLDecoder.decode(requestURI, CHARSET);
} catch (UnsupportedEncodingException e) {

uftUri = requestURI;
}

return RegEX.containsCaseInsensitive(uftUri, pattern.trim());
jdotcms marked this conversation as resolved.
Show resolved Hide resolved
} // match.

/**
* Determinate if the method is allowed
* @param methods Set of methods
* @param method String current request method
* @return boolean true if the method is allowed
*/
default boolean isAllowedMethod(final Set<String> methods, final String method) {

return methods.contains(method);
}

/**
* Returns a set of patterns for the matcher
* @return Set by default empty
*/
default Set<String> getMatcherPatterns() {

return Set.of();
}

/**
* Returns the request methods allowed for this matcher.
* @return Set by default empty
*/
default Set<String> getAllowedMethods() {

return Set.of();
}

/**
* Return an id for the Matcher, by default returns the class name.
* @return
*/
default String getId() {

return this.getClass().getName();
}
}
jdotcms marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import static javax.ws.rs.core.HttpHeaders.CONTENT_LENGTH;
import static javax.ws.rs.core.HttpHeaders.CONTENT_TYPE;

import com.dotcms.analytics.track.RequestMatcher;
import com.dotcms.experiments.business.ExperimentsAPI;
import com.dotcms.experiments.model.Experiment;
import com.dotcms.filters.interceptor.Result;
Expand Down Expand Up @@ -32,6 +33,7 @@
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
Expand All @@ -47,6 +49,10 @@
public class EventLogWebInterceptor implements WebInterceptor {

private static final long serialVersionUID = 1L;

jdotcms marked this conversation as resolved.
Show resolved Hide resolved
private final Map<String, RequestMatcher> requestMatchersMap = new ConcurrentHashMap<>();

// this should be translated to matcher and the rest of the pipeline
private static final String[] PATHS = new String[] {
"/s/lib.js",
"/api/v1/event"
Expand All @@ -70,6 +76,16 @@ public EventLogWebInterceptor() {
});
}

/**
* Add a request matchers
* @param requestMatchers
*/
public void addRequestMatcher(final RequestMatcher... requestMatchers) {
for (final RequestMatcher matcher : requestMatchers) {
requestMatchersMap.put(matcher.getId(), matcher);
}
}

@Override
public String[] getFilters() {
return PATHS;
Expand All @@ -79,6 +95,15 @@ public String[] getFilters() {
public Result intercept(final HttpServletRequest request, final HttpServletResponse response) throws IOException {
setHeaders(response);

final Optional<RequestMatcher> matcherOpt = this.anyMatcher(request);
if (matcherOpt.isPresent()) {

Logger.debug(this, ()-> "Matched: " + matcherOpt.get().getId() + " request: " + request.getRequestURI());
//fireNextStep(request, response);
return Result.SKIP_NO_CHAIN;
}

// I think we have to migrate this to a matcher later
if ("GET".equals(request.getMethod())) {
doGet(request, response);
}
Expand All @@ -94,6 +119,13 @@ public Result intercept(final HttpServletRequest request, final HttpServletRespo
return Result.SKIP_NO_CHAIN;
}

private Optional<RequestMatcher> anyMatcher(final HttpServletRequest request) {

return requestMatchersMap.values().stream()
.filter(matcher -> matcher.match(request))
.findFirst();
}

public void doGet(final HttpServletRequest request, final HttpServletResponse response) throws IOException {
Logger.info(getClass(), "doGet");
response.getWriter().append(jitsuLib.get());
Expand Down Expand Up @@ -193,4 +225,4 @@ public void setHeaders(final HttpServletResponse response) {
response.addHeader("access-control-max-age", "86400");
}

}
}
Loading