-
Notifications
You must be signed in to change notification settings - Fork 468
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Issue 30382 analytics user event rules actionlet (#30415)
Adding the changes to allow to fire an event on a rule
- Loading branch information
Showing
11 changed files
with
258 additions
and
19 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
38 changes: 38 additions & 0 deletions
38
dotCMS/src/main/java/com/dotcms/analytics/track/collectors/CustomerEventCollector.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
package com.dotcms.analytics.track.collectors; | ||
|
||
import com.dotcms.analytics.track.matchers.UserCustomDefinedRequestMatcher; | ||
import com.dotmarketing.beans.Host; | ||
|
||
import java.util.HashMap; | ||
import java.util.Objects; | ||
|
||
/** | ||
* This event collector creator basically allows to send a message for a customer event. | ||
* These events are fired by rest, wf and rules. | ||
* @author jsanca | ||
*/ | ||
public class CustomerEventCollector implements Collector { | ||
@Override | ||
public boolean test(final CollectorContextMap collectorContextMap) { | ||
|
||
return UserCustomDefinedRequestMatcher.USER_CUSTOM_EVENT_MATCHER_ID.equals(collectorContextMap.getRequestMatcher().getId()) ; // should compare with the id | ||
} | ||
|
||
@Override | ||
public CollectorPayloadBean collect(final CollectorContextMap collectorContextMap, | ||
final CollectorPayloadBean collectorPayloadBean) { | ||
final String uri = (String)collectorContextMap.get("uri"); | ||
final String host = (String)collectorContextMap.get("host"); | ||
final Host site = (Host) collectorContextMap.get("currentHost"); | ||
final String language = (String)collectorContextMap.get("lang"); | ||
collectorPayloadBean.put("url", uri); | ||
collectorPayloadBean.put("host", host); | ||
collectorPayloadBean.put("language", language); | ||
collectorPayloadBean.put("site", null != site?site.getIdentifier():"unknown"); | ||
final String eventType = (String)collectorContextMap.get("eventType") == null? | ||
EventType.CUSTOM_USER_EVENT.getType():(String)collectorContextMap.get("eventType"); | ||
collectorPayloadBean.put("event_type", eventType); | ||
|
||
return collectorPayloadBean; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
105 changes: 105 additions & 0 deletions
105
...n/java/com/dotmarketing/portlets/rules/actionlet/RuleAnalyticsFireUserEventActionlet.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
package com.dotmarketing.portlets.rules.actionlet; | ||
|
||
import com.dotcms.analytics.track.collectors.WebEventsCollectorService; | ||
import com.dotcms.analytics.track.collectors.WebEventsCollectorServiceFactory; | ||
import com.dotcms.analytics.track.matchers.UserCustomDefinedRequestMatcher; | ||
import com.dotcms.util.DotPreconditions; | ||
import com.dotmarketing.portlets.rules.RuleComponentInstance; | ||
import com.dotmarketing.portlets.rules.model.ParameterModel; | ||
import com.dotmarketing.portlets.rules.parameter.ParameterDefinition; | ||
import com.dotmarketing.portlets.rules.parameter.display.TextInput; | ||
import com.dotmarketing.portlets.rules.parameter.type.TextType; | ||
import com.dotmarketing.util.UUIDUtil; | ||
import com.dotmarketing.util.WebKeys; | ||
import com.liferay.util.StringPool; | ||
|
||
import javax.servlet.http.HttpServletRequest; | ||
import javax.servlet.http.HttpServletResponse; | ||
import java.io.Serializable; | ||
import java.util.HashMap; | ||
import java.util.Map; | ||
import java.util.Objects; | ||
import java.util.Optional; | ||
|
||
/** | ||
* This actionlet allows to fire an user event to the analytics backend. | ||
* @author jsanca | ||
*/ | ||
public class RuleAnalyticsFireUserEventActionlet extends RuleActionlet<RuleAnalyticsFireUserEventActionlet.Instance> { | ||
|
||
public static final UserCustomDefinedRequestMatcher USER_CUSTOM_DEFINED_REQUEST_MATCHER = new UserCustomDefinedRequestMatcher(); | ||
private final transient WebEventsCollectorService webEventsCollectorService; | ||
|
||
private static final long serialVersionUID = 1L; | ||
public static final String RULE_EVENT_TYPE = "eventType"; | ||
public static final String RULE_OBJECT_TYPE = "objectType"; | ||
public static final String RULE_OBJECT_ID = "objectId"; | ||
public static final String RULE_REQUEST_ID = "requestId"; | ||
public static final String RULE_CONTENT = "CONTENT"; | ||
public static final String RULE_ID = "id"; | ||
public static final String RULE_OBJECT_CONTENT_TYPE_VAR_NAME = "object_content_type_var_name"; | ||
public static final String RULE_OBJECT = "object"; | ||
public static final String RULE_EVENT_TYPE1 = "event_type"; | ||
|
||
public RuleAnalyticsFireUserEventActionlet() { | ||
this(WebEventsCollectorServiceFactory.getInstance().getWebEventsCollectorService()); | ||
} | ||
|
||
public RuleAnalyticsFireUserEventActionlet(final WebEventsCollectorService webEventsCollectorService) { | ||
super("api.system.ruleengine.actionlet.analytics_user_event", | ||
new ParameterDefinition<>(0, RULE_EVENT_TYPE, new TextInput<>(new TextType().required())), | ||
new ParameterDefinition<>(1, RULE_OBJECT_TYPE, new TextInput<>(new TextType())), | ||
new ParameterDefinition<>(2, RULE_OBJECT_ID, new TextInput<>(new TextType())) | ||
); | ||
|
||
this.webEventsCollectorService = webEventsCollectorService; | ||
} | ||
|
||
@Override | ||
public Instance instanceFrom(Map<String, ParameterModel> parameters) { | ||
return new Instance(parameters); | ||
} | ||
|
||
@Override | ||
public boolean evaluate(final HttpServletRequest request, final HttpServletResponse response, final Instance instance) { | ||
|
||
final String identifier = getRuleId(request); | ||
|
||
request.setAttribute(RULE_REQUEST_ID, Objects.nonNull(request.getAttribute(RULE_REQUEST_ID)) ? | ||
request.getAttribute(RULE_REQUEST_ID) : UUIDUtil.uuid()); | ||
final HashMap<String, String> objectDetail = new HashMap<>(); | ||
final Map<String, Serializable> userEventPayload = new HashMap<>(); | ||
|
||
userEventPayload.put(RULE_ID, Objects.nonNull(instance.objectId) ? instance.objectId : identifier); | ||
|
||
objectDetail.put(RULE_ID, identifier); | ||
objectDetail.put(RULE_OBJECT_CONTENT_TYPE_VAR_NAME, Objects.nonNull(instance.objectType) ? instance.objectType : RULE_CONTENT); | ||
userEventPayload.put(RULE_OBJECT, objectDetail); | ||
userEventPayload.put(RULE_EVENT_TYPE1, instance.eventType); | ||
webEventsCollectorService.fireCollectorsAndEmitEvent(request, response, USER_CUSTOM_DEFINED_REQUEST_MATCHER, userEventPayload); | ||
|
||
return true; | ||
} | ||
|
||
private String getRuleId(final HttpServletRequest request) { | ||
|
||
return Optional.of(request.getAttribute(WebKeys.RULES_ENGINE_PARAM_CURRENT_RULE_ID)).orElseGet(()-> StringPool.UNKNOWN).toString(); | ||
} | ||
|
||
public class Instance implements RuleComponentInstance { | ||
|
||
private final String eventType; | ||
private final String objectType; | ||
private final String objectId; | ||
|
||
public Instance(final Map<String, ParameterModel> parameters) { | ||
|
||
DotPreconditions.checkNotNull(parameters, "parameters can't be null"); | ||
this.eventType = parameters.getOrDefault(RULE_EVENT_TYPE, new ParameterModel()).getValue(); | ||
this.objectType = parameters.getOrDefault(RULE_OBJECT_TYPE, new ParameterModel()).getValue(); | ||
this.objectId = parameters.getOrDefault(RULE_OBJECT_ID, new ParameterModel()).getValue(); | ||
} | ||
} | ||
|
||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
81 changes: 81 additions & 0 deletions
81
...va/com/dotmarketing/portlets/rules/actionlet/RuleAnalyticsFireUserEventActionletTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
package com.dotmarketing.portlets.rules.actionlet; | ||
|
||
import com.dotcms.UnitTestBase; | ||
import com.dotcms.analytics.track.collectors.Collector; | ||
import com.dotcms.analytics.track.collectors.WebEventsCollectorService; | ||
import com.dotcms.analytics.track.matchers.RequestMatcher; | ||
import com.dotmarketing.portlets.rules.model.ParameterModel; | ||
import com.dotmarketing.util.WebKeys; | ||
import org.junit.Assert; | ||
import org.junit.Test; | ||
|
||
import javax.servlet.http.HttpServletRequest; | ||
import javax.servlet.http.HttpServletResponse; | ||
import java.io.Serializable; | ||
import java.util.HashMap; | ||
import java.util.Map; | ||
|
||
import static org.mockito.Mockito.mock; | ||
import static org.mockito.Mockito.when; | ||
|
||
/** | ||
* This actionlet allows to fire an user event rule to the analytics backend. | ||
* @author jsanca | ||
*/ | ||
public class RuleAnalyticsFireUserEventActionletTest extends UnitTestBase { | ||
|
||
/** | ||
* * Method to test: RuleAnalyticsFireUserEventActionlet.evaluate | ||
* * Given Scenario: Creates the context and send the information to the rule | ||
* * ExpectedResult: The Payload created has to have the expected values based on the inputs | ||
* @throws Exception | ||
*/ | ||
@Test | ||
public void testActionletSetsFireUserEventOnHappyPath() throws Exception { | ||
|
||
final WebEventsCollectorService webEventsCollectorService = new WebEventsCollectorService() { | ||
@Override | ||
public void fireCollectors(HttpServletRequest request, HttpServletResponse response, RequestMatcher requestMatcher) { | ||
|
||
} | ||
|
||
@Override | ||
public void addCollector(Collector... collectors) { | ||
|
||
} | ||
|
||
@Override | ||
public void removeCollector(String collectorId) { | ||
|
||
} | ||
|
||
@Override | ||
public void fireCollectorsAndEmitEvent(HttpServletRequest request, HttpServletResponse response, | ||
RequestMatcher requestMatcher, Map<String, Serializable> userEventPayload) { | ||
|
||
Assert.assertNotNull(userEventPayload); | ||
Assert.assertEquals("page", userEventPayload.get("event_type")); | ||
Assert.assertEquals("345", userEventPayload.get("id")); | ||
|
||
final Map<String, String> object = (Map<String, String>) userEventPayload.get("object"); | ||
Assert.assertNotNull(object); | ||
Assert.assertEquals("123", object.get("id")); | ||
Assert.assertEquals("CONTENT", object.get("object_content_type_var_name")); | ||
} | ||
}; | ||
|
||
final RuleAnalyticsFireUserEventActionlet analyticsFireUserEventActionlet = new RuleAnalyticsFireUserEventActionlet(webEventsCollectorService); | ||
final Map<String, ParameterModel> params = new HashMap<>(); | ||
params.put(RuleAnalyticsFireUserEventActionlet.RULE_EVENT_TYPE, new ParameterModel(RuleAnalyticsFireUserEventActionlet.RULE_EVENT_TYPE, "page")); | ||
params.put(RuleAnalyticsFireUserEventActionlet.RULE_OBJECT_TYPE, new ParameterModel()); | ||
params.put(RuleAnalyticsFireUserEventActionlet.RULE_OBJECT_ID, new ParameterModel(RuleAnalyticsFireUserEventActionlet.RULE_EVENT_TYPE, "345")); | ||
|
||
final HttpServletRequest request = mock(HttpServletRequest.class); | ||
final HttpServletResponse response = mock(HttpServletResponse.class); | ||
when(request.getAttribute(WebKeys.RULES_ENGINE_PARAM_CURRENT_RULE_ID)).thenReturn("123"); | ||
final RuleAnalyticsFireUserEventActionlet.Instance instance = analyticsFireUserEventActionlet.instanceFrom(params); | ||
|
||
analyticsFireUserEventActionlet.evaluate(request, response, instance); | ||
} | ||
|
||
} |