All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.day.cq.analytics.sitecatalyst.ImpressionsImporter Maven / Gradle / Ivy

/*************************************************************************
 *
 * ADOBE CONFIDENTIAL
 * __________________
 *
 *  Copyright 2011 Adobe Systems Incorporated
 *  All Rights Reserved.
 *
 * NOTICE:  All information contained herein is, and remains
 * the property of Adobe Systems Incorporated and its suppliers,
 * if any.  The intellectual and technical concepts contained
 * herein are proprietary to Adobe Systems Incorporated and its
 * suppliers and may be covered by U.S. and Foreign Patents,
 * patents in process, and are protected by trade secret or copyright law.
 * Dissemination of this information or reproduction of this material
 * is strictly forbidden unless prior written permission is obtained
 * from Adobe Systems Incorporated.
 **************************************************************************/
package com.day.cq.analytics.sitecatalyst;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Dictionary;
import java.util.Set;

import javax.jcr.Node;
import javax.jcr.PathNotFoundException;
import javax.jcr.RepositoryException;

import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Properties;
import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.Service;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ValueMap;
import org.apache.sling.commons.json.JSONArray;
import org.apache.sling.commons.json.JSONException;
import org.apache.sling.commons.json.JSONObject;
import org.apache.sling.commons.osgi.OsgiUtil;
import org.apache.sling.discovery.TopologyEvent;
import org.apache.sling.discovery.TopologyEventListener;
import org.apache.sling.settings.SlingSettingsService;
import org.osgi.service.component.ComponentContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.day.cq.commons.inherit.HierarchyNodeInheritanceValueMap;
import com.day.cq.commons.inherit.InheritanceValueMap;
import com.day.cq.polling.importer.ImportException;
import com.day.cq.polling.importer.Importer;
import com.day.cq.statistics.StatisticsService;
import com.day.cq.wcm.webservicesupport.Configuration;
import com.day.cq.wcm.webservicesupport.ConfigurationManager;
import com.day.cq.wcm.webservicesupport.ConfigurationManagerFactory;


/**
 * The ImpressionsImporter is a {@link Importer} for importing page
 * impressions from SiteCatalyst.
 * 

* Page impressions are only fetched if the configured * ImpresionsImporter.REPORT_INTERVAL is larger than the time since the last * page impressions import. A timestamp for the last import attempt will be * stored in a cq:lastAttempt property of the cq:PollConfig parent * resource *

* * @deprecated Functionality has been replaced by the generic service Adobe AEM Analytics Report Importer */ @Component( metatype = true, label = "Day CQ Analytics SiteCatalyst Impressions Importer", description = "Imports SiteCatalyst Page Impressions periodically into CQ" ) @Service @Properties(value = { @org.apache.felix.scr.annotations.Property(name = Importer.SCHEME_PROPERTY, value = "sitecatalyst", propertyPrivate = true) }) @Deprecated public class ImpressionsImporter implements Importer, TopologyEventListener { /** default log */ private final Logger log = LoggerFactory.getLogger(getClass()); @Property( label = "Import interval", description = "Import interval in milliseconds. Default is set to 43200000 (12h).", longValue=43200000 ) protected static final String REPORT_INTERVAL = "cq.analytics.sitecatalyst.importer.inverval"; private static final long DEFAULT_INTERVAL = 43200000L; private long reportInterval; @Property( label = "Enabled", description = "Indicator if importer is enabled or disabled.", boolValue = true ) private static final String ENABLED = "cq.analytics.sitecatalyst.importer.enabled"; private static final boolean DEFAULT_ENABLED = false; private boolean enabled; @Reference private SlingSettingsService settingsService; @Reference private SitecatalystWebservice webservice; @Reference private StatisticsService statService; @Reference private ConfigurationManagerFactory cfgManagerFactory; /** Leader flag */ private boolean isLeader = false; /* * (non-Javadoc) * @see com.day.cq.polling.importer.Importer#importData(java.lang.String, java.lang.String, org.apache.sling.api.resource.Resource) */ public void importData(String scheme, String dataSource, Resource target) throws ImportException { if (enabled) { if (!isLeader) { log.info("Import skipped on slave instance"); return; } try { Resource pageResource = target.getParent().getParent(); InheritanceValueMap pageProperties = new HierarchyNodeInheritanceValueMap(pageResource); Node analytics = target.getParent().adaptTo(Node.class); String lastAttempt = "0"; if (analytics.hasProperty("cq:lastAttempt")) { lastAttempt = analytics.getProperty("cq:lastAttempt").getString(); } Configuration configuration = null; String[] services = pageProperties.getInherited("cq:cloudserviceconfigs", new String[]{}); ConfigurationManager cfgManager = cfgManagerFactory.getConfigurationManager(target.getResourceResolver()); if (services.length > 0) { configuration = cfgManager.getConfiguration("sitecatalyst", services); } if (configuration == null) { log.error("SiteCatalyst configuration not found"); return; } if (isImporterDisabledFromConfig(configuration)) { return; } String reportSuiteID = SitecatalystUtil.getReportSuites(settingsService, configuration); if (lastAttempt.startsWith("waiting")) { // try to read the triggered report String reportID = lastAttempt.replace("waiting-", ""); try { // call web service to get report status String response = webservice.getReport(configuration, reportID); JSONObject jsonObj = new JSONObject(response); JSONObject report = jsonObj.optJSONObject("report"); if (report != null) { JSONArray data = report.getJSONArray("data"); String lastAttemptDate = analytics.getProperty("cq:lastAttemptDate").getString(); String statsBasePath = "/var/statistics/pages" + analytics.getPath().replace("/jcr:content/analytics", ""); log.info("Report contains data items: " + data.length()); for (int i=0; i < data.length(); i++) { // iterate over the pages with data JSONObject pageData = data.getJSONObject(i); // update data for one page this.setStatsData(statsBasePath, lastAttemptDate, pageData.getString("name"), pageData.getJSONArray("counts").getString(0), target.getResourceResolver(), statService); } log.info("Report " + reportID + " imported"); } else { Long errorId = jsonObj.optLong("error"); String errorMsg = jsonObj.optString("error_description"); log.warn("Report " + reportID + " failed due to (error:" + errorId + "): " + errorMsg); } } catch (SitecatalystException e) { log.error("Call to Sitecatalyst failed", e); } catch (JSONException e) { log.error("Parsing JSON response failed", e); } finally { if (analytics.getSession().hasPendingChanges()) { analytics.setProperty("cq:lastAttempt", Long.toString(System.currentTimeMillis())); analytics.getSession().save(); } } } else { // check whether a new report should be triggered long last = Long.parseLong(lastAttempt); if (last + reportInterval < System.currentTimeMillis()) { // last report is 'reportInterval' ago, trigger a new one if (reportSuiteID == null) { log.warn("cannot import data since no valid report suite ID was found"); return; } try { String date;// = "2010-12-01"; // use the date from yesterday Calendar cal = Calendar.getInstance(); DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); cal.add(Calendar.DATE, -1); date = dateFormat.format(cal.getTime()); String response = webservice.queuePageViewReport(configuration, reportSuiteID, date); JSONObject jsonObj = new JSONObject(response); Long reportID = jsonObj.optLong("reportID"); if (reportID != 0) { analytics.setProperty("cq:lastAttempt", "waiting-" + reportID); analytics.setProperty("cq:lastAttemptDate", date); log.info("Report queued: " + reportID + " for " + reportSuiteID + " and " + date); } else { Long errorId = jsonObj.optLong("error"); String errorMsg = jsonObj.optString("error_description"); log.warn(jsonObj.toString()); log.warn("queueing report failed due to (error:" + errorId + "): " + errorMsg); analytics.setProperty("cq:lastAttempt", Long.toString(System.currentTimeMillis())); } } catch (SitecatalystException e) { log.error("Call to SiteCatalyst failed", e); analytics.setProperty("cq:lastAttempt", Long.toString(System.currentTimeMillis())); } catch (JSONException e) { log.error("Parsing JSON response failed", e); analytics.setProperty("cq:lastAttempt", Long.toString(System.currentTimeMillis())); } finally { if (analytics.getSession().hasPendingChanges()) { analytics.getSession().save(); } } } } } catch (PathNotFoundException e) { log.error("Reading analytics data failed for " + target.getPath(), e); } catch (RepositoryException e) { log.error("Reading analytics data failed", e); } } } private void setStatsData(String basePath, String date, String name, String count, ResourceResolver resolver, StatisticsService statService) { String statsPath = basePath; if (!name.equals("home")) { name = "/" + name.replace(":", "/"); } else { name = ""; } statsPath += name + "/.stats/"; statsPath += date.replace("-", "/"); Resource dayStats = resolver.getResource(statsPath); if (dayStats!=null) { // already added stats for this day ValueMap statsConfig = dayStats.adaptTo(ValueMap.class); long views = statsConfig.get("views", Long.class); if (views == Long.parseLong(count)) { return; } } // create new stats node or update existing one ImpressionsEntry view = new ImpressionsEntry(basePath, name, date, Long.parseLong(count)); try { statService.addEntry(view); } catch (RepositoryException e) { log.error("adding stats entry failed", e); } } /** * Check if the given Analytics cloud configuration is set to disable the impressions importer for the running instance mode. * * @param config the Analytics configuration to be checked * @return {@code true} if the impressions importer is disabled for the running instance mode, {@code false} otherwise */ private boolean isImporterDisabledFromConfig(Configuration config) { boolean disableAuthor = config.getInherited("disableImportPageImpressionsAuthor", false); boolean disablePublish = config.getInherited("disableImportPageImpressionsPublish", false); Set runmodes = settingsService.getRunModes(); if (disableAuthor && runmodes.contains("author")) { return true; } if (disablePublish && runmodes.contains("publish")) { return true; } return false; } // ----< SCR Integration >-------------------------------------------------- protected void activate(ComponentContext componentContext) { @SuppressWarnings("unchecked") final Dictionary config = componentContext.getProperties(); reportInterval = OsgiUtil.toLong(config.get(REPORT_INTERVAL), DEFAULT_INTERVAL); enabled = OsgiUtil.toBoolean(config.get(ENABLED), DEFAULT_ENABLED); } /** * @see org.apache.sling.discovery.TopologyEventListener#handleTopologyEvent(org.apache.sling.discovery.TopologyEvent) */ public void handleTopologyEvent(final TopologyEvent event) { if (event.getType() == TopologyEvent.Type.TOPOLOGY_CHANGED || event.getType() == TopologyEvent.Type.PROPERTIES_CHANGED || event.getType() == TopologyEvent.Type.TOPOLOGY_INIT) { this.isLeader = event.getNewView().getLocalInstance().isLeader(); } else if (event.getType() == TopologyEvent.Type.TOPOLOGY_CHANGING) { this.isLeader = false; } } // only here for backwards compatibility since this class is exported protected void bindCfgManager(ConfigurationManager cfg) { throw new UnsupportedOperationException(); } // only here for backwards compatibility since this class is exported protected void unbindCfgManager(ConfigurationManager cfg) { throw new UnsupportedOperationException(); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy