Package org.eurekastreams.server.action.execution

Source Code of org.eurekastreams.server.action.execution.GenerateDailyUsageSummaryExecution

/*
* Copyright (c) 2010-2011 Lockheed Martin Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.eurekastreams.server.action.execution;

import java.io.Serializable;
import java.util.Date;
import java.util.List;

import org.apache.commons.logging.Log;
import org.eurekastreams.commons.actions.TaskHandlerExecutionStrategy;
import org.eurekastreams.commons.actions.context.ActionContext;
import org.eurekastreams.commons.actions.context.TaskHandlerActionContext;
import org.eurekastreams.commons.date.DateDayExtractor;
import org.eurekastreams.commons.date.DayOfWeekStrategy;
import org.eurekastreams.commons.date.GetDateFromDaysAgoStrategy;
import org.eurekastreams.commons.exceptions.ExecutionException;
import org.eurekastreams.commons.logging.LogFactory;
import org.eurekastreams.server.domain.DailyUsageSummary;
import org.eurekastreams.server.domain.dto.StreamDiscoverListsDTO;
import org.eurekastreams.server.persistence.mappers.DomainMapper;
import org.eurekastreams.server.persistence.mappers.requests.PersistenceRequest;
import org.eurekastreams.server.service.actions.requests.UsageMetricDailyStreamInfoRequest;
import org.eurekastreams.server.service.actions.requests.UsageMetricStreamSummaryRequest;

/**
* Execution strategy to generate the daily usage summary for the previous day.
*/
public class GenerateDailyUsageSummaryExecution implements TaskHandlerExecutionStrategy<ActionContext>
{
    /**
     * Logger.
     */
    private final Log logger = LogFactory.make();

    /**
     * strategy to get a date from N days ago.
     */
    private final GetDateFromDaysAgoStrategy daysAgoDateStrategy;

    /**
     * Number of days of data to generate.
     */
    private final int daysToGenerate;

    // mappers that apply to the whole system

    /**
     * Mapper to get a day's page view count - for the whole system.
     */
    private final DomainMapper<Date, Long> getDailyPageViewCountMapper;

    /**
     * Mapper to get a day's unique visitor count - for whole system.
     */
    private final DomainMapper<Date, Long> getDailyUniqueVisitorCountMapper;

    // mappers that may be scoped to a particular thread

    /**
     * Mapper to get a single day's DailyUsageSummary - for a stream or the whole system.
     */
    private final DomainMapper<UsageMetricDailyStreamInfoRequest, DailyUsageSummary> //
    getDailyUsageSummaryByDateMapper;

    /**
     * Mapper to get a day's message count - for a stream or the whole system.
     */
    private final DomainMapper<UsageMetricDailyStreamInfoRequest, Long> getDailyMessageCountMapper;

    /**
     * Mapper to get a day's stream contributor count - for a stream or the whole system.
     */
    private final DomainMapper<UsageMetricDailyStreamInfoRequest, Long> getDailyStreamContributorCountMapper;

    /**
     * Mapper to get a day's stream view count - for a stream or the whole system.
     */
    private final DomainMapper<UsageMetricDailyStreamInfoRequest, Long> getDailyStreamViewCountMapper;

    /**
     * Mapper to get a day's stream viewer count - for a stream or the whole system.
     */
    private final DomainMapper<UsageMetricDailyStreamInfoRequest, Long> getDailyStreamViewerCountMapper;

    /**
     * Mapper to get the total number of activities posted to a stream.
     */
    private final DomainMapper<UsageMetricDailyStreamInfoRequest, Long> getTotalActivityCountMapper;

    /**
     * Mapper to get the total number of comments posted to a stream.
     */
    private final DomainMapper<UsageMetricDailyStreamInfoRequest, Long> getTotalCommentCountMapper;

    /**
     * Mapper to get the total number of contributors to a stream by stream scope id.
     */
    private final DomainMapper<UsageMetricDailyStreamInfoRequest, Long> getTotalStreamContributorMapper;

    /**
     * Mapper to get day's average activity response time (for those that had responses) - for a stream or the whole
     * system.
     */
    private final DomainMapper<Date, Long> getDailyMessageResponseTimeMapper;

    // helpers

    /**
     * Mapper to get all the ids for the stream scopes to generate data for.
     */
    private final DomainMapper<Date, List<Long>> streamScopeIdsMapper;

    /**
     * Mapper to delete old UsageMetric data.
     */
    private final DomainMapper<Serializable, Serializable> usageMetricDataCleanupMapper;

    /**
     * Mapper to insert the DailyUsageSummary entity.
     */
    private final DomainMapper<PersistenceRequest<DailyUsageSummary>, Boolean> insertMapper;

    /**
     * Mapper to clear the entity manager.
     */
    private final DomainMapper<Serializable, Boolean> clearEntityManagerMapper;

    /**
     * Mapper to get the summary data for a stream, or all streams - used for caching.
     */
    private final DomainMapper<UsageMetricStreamSummaryRequest, List<DailyUsageSummary>> summaryDataMapper;

    /**
     * Mapper to get the lists for the discover page - this should be a cache refreshing mapper, b/c that's how it's
     * used.
     */
    private final DomainMapper<Serializable, StreamDiscoverListsDTO> discoverPageListsCacheRefreshingMapper;

    /**
     * The number of days to cache summary data for.
     */
    private final int numberOfDaysToCacheSummaryDataFor;

    /**
     * Strategy to determine if a day is a weekday.
     */
    private final DayOfWeekStrategy dayOfWeekStrategy;

    /**
     * Constructor.
     *
     * @param inDaysToGenerate
     *            the number of days to generate data for
     * @param inDaysAgoDateStrategy
     *            strategy to get a date from yesterday
     * @param inGetDailyUsageSummaryByDateMapper
     *            Mapper to get a single day's DailyUsageSummary
     *
     * @param inGetDailyMessageCountMapper
     *            Mapper to get a day's message count
     * @param inGetDailyPageViewCountMapper
     *            Mapper to get a day's page view count.
     * @param inGetDailyStreamContributorCountMapper
     *            Mapper to get a day's stream contributor count.
     * @param inGetDailyStreamViewCountMapper
     *            Mapper to get a day's stream view count.
     * @param inGetDailyStreamViewerCountMapper
     *            Mapper to get a day's stream viewer count.
     * @param inGetDailyUniqueVisitorCountMapper
     *            Mapper to get a day's unique visitor count.
     * @param inGetDailyMessageResponseTimeMapper
     *            Mapper to get day's average activity response time (for those that had responses).
     * @param inInsertMapper
     *            mapper to insert DailyUsageSummary
     * @param inUsageMetricDataCleanupMapper
     *            mapper to delete old UsageMetric data
     * @param inDayOfWeekStrategy
     *            dayOfWeekStrategy strategy to determine if a day is a weekday
     * @param inStreamScopeIdsMapper
     *            mapper to get all the ids of the stream scopes to generate data for
     * @param inGetTotalActivityCountMapper
     *            mapper to get the total activities for a stream
     * @param inGetTotalCommentCountMapper
     *            mapper to get the total comments for a stream
     * @param inGetTotalStreamContributorMapper
     *            mapper to get the total number of contributors to a stream
     * @param inClearEntityManagerMapper
     *            mapper to clear entity manager
     * @param inSummaryDataMapper
     *            mapper to fetch & cache the stream scope's summary data
     * @param inDiscoverPageListsCacheRefreshingMapper
     *            mapper to fetch and refresh the discover page lists in cache
     * @param inNumberOfDaysToCacheSummaryDataFor
     *            the number of days to cache the summary data for
     */
    public GenerateDailyUsageSummaryExecution(
            final int inDaysToGenerate,
            final GetDateFromDaysAgoStrategy inDaysAgoDateStrategy,
            final DomainMapper<UsageMetricDailyStreamInfoRequest, DailyUsageSummary> inGetDailyUsageSummaryByDateMapper,
            final DomainMapper<UsageMetricDailyStreamInfoRequest, Long> inGetDailyMessageCountMapper,
            final DomainMapper<Date, Long> inGetDailyPageViewCountMapper,
            final DomainMapper<UsageMetricDailyStreamInfoRequest, Long> inGetDailyStreamContributorCountMapper,
            final DomainMapper<UsageMetricDailyStreamInfoRequest, Long> inGetDailyStreamViewCountMapper,
            final DomainMapper<UsageMetricDailyStreamInfoRequest, Long> inGetDailyStreamViewerCountMapper,
            final DomainMapper<Date, Long> inGetDailyUniqueVisitorCountMapper,
            final DomainMapper<Date, Long> inGetDailyMessageResponseTimeMapper,
            final DomainMapper<PersistenceRequest<DailyUsageSummary>, Boolean> inInsertMapper,
            final DomainMapper<Serializable, Serializable> inUsageMetricDataCleanupMapper,
            final DayOfWeekStrategy inDayOfWeekStrategy, final DomainMapper<Date, List<Long>> inStreamScopeIdsMapper,
            final DomainMapper<UsageMetricDailyStreamInfoRequest, Long> inGetTotalActivityCountMapper,
            final DomainMapper<UsageMetricDailyStreamInfoRequest, Long> inGetTotalCommentCountMapper,
            final DomainMapper<UsageMetricDailyStreamInfoRequest, Long> inGetTotalStreamContributorMapper,
            final DomainMapper<Serializable, Boolean> inClearEntityManagerMapper,
            final DomainMapper<UsageMetricStreamSummaryRequest, List<DailyUsageSummary>> inSummaryDataMapper,
            final DomainMapper<Serializable, StreamDiscoverListsDTO> inDiscoverPageListsCacheRefreshingMapper,
            final int inNumberOfDaysToCacheSummaryDataFor)
    {
        daysToGenerate = inDaysToGenerate;
        daysAgoDateStrategy = inDaysAgoDateStrategy;
        getDailyUsageSummaryByDateMapper = inGetDailyUsageSummaryByDateMapper;
        getDailyMessageCountMapper = inGetDailyMessageCountMapper;
        getDailyPageViewCountMapper = inGetDailyPageViewCountMapper;
        getDailyStreamContributorCountMapper = inGetDailyStreamContributorCountMapper;
        getDailyStreamViewCountMapper = inGetDailyStreamViewCountMapper;
        getDailyStreamViewerCountMapper = inGetDailyStreamViewerCountMapper;
        getDailyUniqueVisitorCountMapper = inGetDailyUniqueVisitorCountMapper;
        getDailyMessageResponseTimeMapper = inGetDailyMessageResponseTimeMapper;
        insertMapper = inInsertMapper;
        usageMetricDataCleanupMapper = inUsageMetricDataCleanupMapper;
        dayOfWeekStrategy = inDayOfWeekStrategy;
        streamScopeIdsMapper = inStreamScopeIdsMapper;
        getTotalActivityCountMapper = inGetTotalActivityCountMapper;
        getTotalCommentCountMapper = inGetTotalCommentCountMapper;
        getTotalStreamContributorMapper = inGetTotalStreamContributorMapper;
        clearEntityManagerMapper = inClearEntityManagerMapper;
        summaryDataMapper = inSummaryDataMapper;
        discoverPageListsCacheRefreshingMapper = inDiscoverPageListsCacheRefreshingMapper;
        numberOfDaysToCacheSummaryDataFor = inNumberOfDaysToCacheSummaryDataFor;
    }

    /**
     * Generate the daily usage summary for the previous day.
     *
     * @param inActionContext
     *            the action context
     * @return true if data was inserted, false if already existed
     * @throws ExecutionException
     *             when something really, really bad happens
     */
    @Override
    public Serializable execute(final TaskHandlerActionContext<ActionContext> inActionContext)
            throws ExecutionException
    {
        long start = System.currentTimeMillis();
        for (int i = daysToGenerate; i >= 1; i--)
        {
            logger.info("Generating metric data for " + i + " days ago.");
            generateDailyUsageSummaryForDay(i);
        }

        // delete old data
        logger.info("Deleting old daily usage metric data older than 2 days");
        usageMetricDataCleanupMapper.execute(null);

        logger.info("Completed generating usage metrics in " + (System.currentTimeMillis() - start) + "ms");

        // now ask for the discover page lists from the refresh mapper, which will cause the cache to update
        logger.info("Updating the Discover Page cache.");
        discoverPageListsCacheRefreshingMapper.execute(null);
        logger.info("Completed generating Discover Page cache.");

        return Boolean.TRUE;
    }

    /**
     * Generate the daily usage summary for all streams for a specific day.
     *
     * @param inDaysAgo
     *            the number of days ago to generate data for
     */
    private void generateDailyUsageSummaryForDay(final int inDaysAgo)
    {
        Date reportDate = DateDayExtractor.getStartOfDay(daysAgoDateStrategy.execute(inDaysAgo));

        if (!dayOfWeekStrategy.isWeekday(reportDate))
        {
            logger.info("Ignoring " + reportDate + " - it's a weekend");
            return;
        }

        logger.info("Checking id daily usage summary data exists for " + reportDate);
        DailyUsageSummary existingSummary = getDailyUsageSummaryByDateMapper
                .execute(new UsageMetricDailyStreamInfoRequest(reportDate, null));
        clearEntityManagerMapper.execute(null);

        if (existingSummary != null)
        {
            logger.info("Data already exists for " + reportDate);
            return;
        }

        // generate data for all streams
        generateDailyUsageSummaryForStreamScope(reportDate, null);

        // now generate data for each stream
        List<Long> streamScopeIds = streamScopeIdsMapper.execute(reportDate);
        for (Long streamScopeId : streamScopeIds)
        {
            generateDailyUsageSummaryForStreamScope(reportDate, streamScopeId);
        }

        logger.info("Inserted Daily Summary metrics for " + reportDate);
    }

    /**
     * Generate the daily usage summary for the stream scope with the input id, and for the given date.
     *
     * @param inDate
     *            the date to generate for
     * @param inStreamScopeId
     *            the streamscope id to generate stats for
     */
    private void generateDailyUsageSummaryForStreamScope(final Date inDate, final Long inStreamScopeId)
    {
        try
        {
            UsageMetricDailyStreamInfoRequest streamInfoRequest = new UsageMetricDailyStreamInfoRequest(inDate,
                    inStreamScopeId);

            String timerLog = "TimerData:" + inStreamScopeId;
            long start;
            long totalStart = System.currentTimeMillis();

            long uniqueVisitorCount = 0;
            long pageViewCount = 0;
            long streamViewCount = 0;
            long streamViewerCount = 0;
            long streamContributorCount = 0;
            long messageCount = 0;
            long avgActvityResponeTime = 0;

            Long totalActivityCount = null;
            Long totalCommentCount = null;
            Long totalContributorCount = null;

            // get the stream view count -
            logger.info("Generating number of stream views for " + inDate);

            start = System.currentTimeMillis();
            clearEntityManagerMapper.execute(null);
            streamViewCount = getDailyStreamViewCountMapper.execute(streamInfoRequest);
            timerLog += "\t1: " + (System.currentTimeMillis() - start);

            if (inStreamScopeId == null)
            {
                // doesn't make sense on a per-stream basis
                logger.info("Generating number of unique visitors for " + inDate);
                clearEntityManagerMapper.execute(null);
                uniqueVisitorCount = getDailyUniqueVisitorCountMapper.execute(inDate);

                logger.info("Generating number of page views for " + inDate);
                clearEntityManagerMapper.execute(null);
                pageViewCount = getDailyPageViewCountMapper.execute(inDate);

                logger.info("Generating average activity comment time (for those with comments on the same day) for "
                        + inDate);
                clearEntityManagerMapper.execute(null);
                avgActvityResponeTime = getDailyMessageResponseTimeMapper.execute(inDate);
            }
            else
            {
                // these are only generated for individual streams
                start = System.currentTimeMillis();
                clearEntityManagerMapper.execute(null);
                totalActivityCount = getTotalActivityCountMapper.execute(streamInfoRequest);
                timerLog += "\t2: " + (System.currentTimeMillis() - start);

                start = System.currentTimeMillis();
                clearEntityManagerMapper.execute(null);
                totalCommentCount = getTotalCommentCountMapper.execute(streamInfoRequest);
                timerLog += "\t3: " + (System.currentTimeMillis() - start);

                start = System.currentTimeMillis();
                clearEntityManagerMapper.execute(null);
                totalContributorCount = getTotalStreamContributorMapper.execute(streamInfoRequest);
                timerLog += "\t4: " + (System.currentTimeMillis() - start);
            }

            logger.info("Generating number of stream viewers for " + inDate);
            start = System.currentTimeMillis();
            clearEntityManagerMapper.execute(null);
            streamViewerCount = getDailyStreamViewerCountMapper.execute(streamInfoRequest);
            timerLog += "\t6: " + (System.currentTimeMillis() - start);

            logger.info("Generating number of stream contributors for " + inDate);
            start = System.currentTimeMillis();
            clearEntityManagerMapper.execute(null);
            streamContributorCount = getDailyStreamContributorCountMapper.execute(streamInfoRequest);
            timerLog += "\t7: " + (System.currentTimeMillis() - start);

            logger.info("Generating number of messages (activities and comments) for " + inDate);
            start = System.currentTimeMillis();
            clearEntityManagerMapper.execute(null);
            messageCount = getDailyMessageCountMapper.execute(streamInfoRequest);
            timerLog += "\t8: " + (System.currentTimeMillis() - start);

            DailyUsageSummary data = new DailyUsageSummary(uniqueVisitorCount, pageViewCount, streamViewerCount,
                    streamViewCount, streamContributorCount, messageCount, avgActvityResponeTime, inDate,
                    inDate.getTime(), inStreamScopeId, totalActivityCount, totalCommentCount, totalContributorCount);

            // store this
            logger.info("Inserting daily usage metric data for " + inDate);
            start = System.currentTimeMillis();
            clearEntityManagerMapper.execute(null);
            insertMapper.execute(new PersistenceRequest<DailyUsageSummary>(data));
            timerLog += "\t9: " + (System.currentTimeMillis() - start);

            // fetch the stream's data, which should be configured to force a cache refresh
            start = System.currentTimeMillis();
            clearEntityManagerMapper.execute(null);
            summaryDataMapper.execute(new UsageMetricStreamSummaryRequest(numberOfDaysToCacheSummaryDataFor,
                    inStreamScopeId));
            timerLog += "\t10: " + (System.currentTimeMillis() - start);
            timerLog += "\tTOTAL: " + (System.currentTimeMillis() - totalStart);
            logger.trace(timerLog);
        }
        catch (Exception e)
        {
            logger.error("Error generating daily usage summary for date: " + inDate + " and stream scope id "
                    + inStreamScopeId);
        }
    }
}
TOP

Related Classes of org.eurekastreams.server.action.execution.GenerateDailyUsageSummaryExecution

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.