Skip to content

Commit

Permalink
#29866 adding first draft for the viewtool
Browse files Browse the repository at this point in the history
  • Loading branch information
jdotcms committed Sep 23, 2024
1 parent eb12737 commit 7cc4d9e
Show file tree
Hide file tree
Showing 6 changed files with 207 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -1,16 +1,30 @@
package com.dotcms.analytics.content;

import com.dotcms.analytics.query.AnalyticsQuery;
import com.dotcms.cube.CubeJSQuery;
import com.liferay.portal.model.User;

/**
*
* This interface provides the methods to run reports on content analytics.
*
* @author Jose Castro
* @since Sep 13th, 2024
*/
public interface ContentAnalyticsAPI {

/**
* Run a report based on an analytics query
* @param query
* @param user
* @return ReportResponse
*/
ReportResponse runReport(final AnalyticsQuery query, final User user);

/**
* Runs a raw report based on a cubeJS query
* @param cubeJSQuery
* @param user
* @return ReportResponse
*/
ReportResponse runRawReport(CubeJSQuery cubeJSQuery, User user);
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.dotcms.analytics.content;

import com.dotcms.analytics.query.AnalyticsQuery;
import com.dotcms.cube.CubeJSQuery;
import com.dotmarketing.util.Logger;
import com.liferay.portal.model.User;

Expand Down Expand Up @@ -31,4 +32,11 @@ public ReportResponse runReport(final AnalyticsQuery query, final User user) {
return this.contentAnalyticsFactory.getReport(query, user);
}

@Override
public ReportResponse runRawReport(CubeJSQuery cubeJSQuery, User user) {
Logger.debug(this, ()-> "Running the report for the raw query: " + cubeJSQuery);
// note: should check any permissions for an user.
return this.contentAnalyticsFactory.getRawReport(cubeJSQuery, user);
}

}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.dotcms.analytics.content;

import com.dotcms.analytics.query.AnalyticsQuery;
import com.dotcms.cube.CubeJSQuery;
import com.liferay.portal.model.User;

/**
Expand All @@ -20,4 +21,13 @@ public interface ContentAnalyticsFactory {
*/
ReportResponse getReport(final AnalyticsQuery query, final User user);

/**
* Runs the raw report based on the cube js query and user.
*
* @param query the query to run the report.
* @param user the user to run the report.
* @return the report response.
*/
ReportResponse getRawReport(final CubeJSQuery query, final User user);

}
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,20 @@ public ReportResponse getReport(final AnalyticsQuery query, final User user) {
Logger.debug(this, ()-> "Getting the report for the query: " + query);
try {
final CubeJSQuery cubeJSQuery = this.queryParser.parseQueryToCubeQuery(query);
return getRawReport(cubeJSQuery, user);
} catch (Exception e) {

Logger.error(this, e.getMessage(), e);
throw new DotRuntimeException(e);
}
}

@Override
public ReportResponse getRawReport(final CubeJSQuery cubeJSQuery, final User user) {

try {

Logger.debug(this, ()-> "Getting the report for the raw query: " + cubeJSQuery);
final CubeJSClient cubeClient = cubeJSClientFactory.create(user);
return toReportResponse(cubeClient.send(cubeJSQuery));
} catch (DotDataException| DotSecurityException e) {
Expand Down
155 changes: 155 additions & 0 deletions dotCMS/src/main/java/com/dotcms/analytics/viewtool/AnalyticsTool.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
package com.dotcms.analytics.viewtool;

import com.dotcms.analytics.content.ContentAnalyticsAPI;
import com.dotcms.analytics.content.ReportResponse;
import com.dotcms.analytics.query.AnalyticsQuery;
import com.dotcms.analytics.query.AnalyticsQueryParser;
import com.dotcms.cdi.CDIUtils;
import com.dotcms.cube.CubeJSQuery;
import com.dotcms.rest.api.v1.DotObjectMapperProvider;
import com.dotmarketing.business.web.WebAPILocator;
import com.dotmarketing.exception.DotRuntimeException;
import com.dotmarketing.util.Logger;
import com.liferay.portal.model.User;
import org.apache.velocity.tools.view.context.ViewContext;
import org.apache.velocity.tools.view.tools.ViewTool;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.Map;

/**
* This class is a ViewTool that can be used to access the analytics data.
* @author jsanca
*/
public class AnalyticsTool implements ViewTool {

private final ContentAnalyticsAPI contentAnalyticsAPI;
private final AnalyticsQueryParser analyticsQueryParser;

private User user = null;

public AnalyticsTool() {
this(CDIUtils.getBean(ContentAnalyticsAPI.class).get(),
CDIUtils.getBean(AnalyticsQueryParser.class).get());
}


public AnalyticsTool(final ContentAnalyticsAPI contentAnalyticsAPI,
final AnalyticsQueryParser analyticsQueryParser) {

this.contentAnalyticsAPI = contentAnalyticsAPI;
this.analyticsQueryParser = analyticsQueryParser;
}

@Override
public void init(final Object initData) {

if (initData instanceof ViewContext) {

final HttpServletRequest request = ((ViewContext) initData).getRequest();
final HttpSession session = request.getSession(false);

if (session != null) {
try {
user = WebAPILocator.getUserWebAPI().getLoggedInUser(request);
} catch (DotRuntimeException e) {
Logger.error(this.getClass(), e.getMessage());
}
}
}
}

/**
* Runs an analytics report based on the string json query.
* example:
* <code>
* #set($query = "{
* "dimensions": ["Events.referer", "Events.experiment", "Events.variant", "Events.utcTime", "Events.url", "Events.lookBackWindow", "Events.eventType"],
* "measures": ["Events.count", "Events.uniqueCount"],
* "filters": "Events.variant = ['B'] or Events.experiments = ['B']",
* "limit":100,
* "offset":1,
* "timeDimensions":"Events.day day",
* "orders":"Events.day ASC"
* }")
*
* $dotanalytics.runReportFromJson($query)
* </code>
* @param query
* @return
*/
public ReportResponse runReportFromJson(final String query) {

Logger.debug(this, () -> "Running report from json: " + query);
return contentAnalyticsAPI.runReport(this.analyticsQueryParser.parseJsonToQuery(query), user);
}

/**
* Runs an analytics report based on Map query.
* example:
* <code>
* #set ($myQuery = {})
* $myMap.put('dimensions', ["Events.referer", "Events.experiment", "Events.variant", "Events.utcTime", "Events.url", "Events.lookBackWindow", "Events.eventType"])
* $myMap.put('measures', ["Events.count", "Events.uniqueCount"])
* $myMap.put('filters', "Events.variant = ['B'] or Events.experiments = ['B']")
* $myMap.put('limit', 100)
* $myMap.put('offset', 1)
* $myMap.put('timeDimensions', "Events.day day")
* $myMap.put('orders', "Events.day ASC")
*
* $dotanalytics.runReportFromMap($myQuery)
* </code>
* @param query
* @return
*/
public ReportResponse runReportFromMap(final Map<String, Object> query) {

Logger.debug(this, () -> "Running report from map: " + query);
final AnalyticsQuery analyticsQuery = DotObjectMapperProvider.getInstance()
.getDefaultObjectMapper().convertValue(query, AnalyticsQuery.class);
return contentAnalyticsAPI.runReport(analyticsQuery, user);
}

/**
* Runs an analytics report based cube js raw json string query
*
* example:
* <code>
* #set($query = "{
*
* }")
*
* $dotanalytics.runRawReportFromJson($query)
* </code>
* @param query
* @return
*/
public ReportResponse runRawReportFromJson(final Map<String, Object> query) {

Logger.debug(this, () -> "Running report from raw query: " + query);
final CubeJSQuery cubeJSQuery = DotObjectMapperProvider.getInstance()
.getDefaultObjectMapper().convertValue(query, CubeJSQuery.class);
return contentAnalyticsAPI.runRawReport(cubeJSQuery, user);
}

/**
* Runs an analytics report based on Map query.
* example:
* <code>
* #set ($myQuery = {})
*
*
* $dotanalytics.runRawReportFromMap($myQuery)
* </code>
* @param query
* @return
*/
public ReportResponse runRawReportFromMap(final Map<String, Object> query) {

Logger.debug(this, () -> "Running report from raw query map: " + query);
final CubeJSQuery cubeJSQuery = DotObjectMapperProvider.getInstance()
.getDefaultObjectMapper().convertValue(query, CubeJSQuery.class);
return contentAnalyticsAPI.runRawReport(cubeJSQuery, user);
}
}
5 changes: 5 additions & 0 deletions dotCMS/src/main/webapp/WEB-INF/toolbox.xml
Original file line number Diff line number Diff line change
Expand Up @@ -322,4 +322,9 @@
<scope>request</scope>
<class>com.dotcms.ai.viewtool.AIViewTool</class>
</tool>
<tool>
<key>analytics</key>
<scope>request</scope>
<class>com.dotcms.analytics.viewtool.AnalyticsTool</class>
</tool>
</toolbox>

0 comments on commit 7cc4d9e

Please sign in to comment.