package org.ff4j.audit.repository; /* * #%L * ff4j-core * %% * Copyright (C) 2013 - 2016 FF4J * %% * 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. * #L% */ import static org.ff4j.audit.EventConstants.TITLE_BARCHAR_HIT; import static org.ff4j.audit.EventConstants.TITLE_PIE_HITCOUNT; import java.text.SimpleDateFormat; import java.util.Collections; import java.util.Comparator; import java.util.Date; import java.util.List; import java.util.Map; import java.util.Set; import java.util.TreeSet; import java.util.concurrent.TimeUnit; import org.ff4j.audit.Event; import org.ff4j.audit.EventQueryDefinition; import org.ff4j.audit.MutableHitCount; import org.ff4j.audit.chart.BarChart; import org.ff4j.audit.chart.PieChart; import org.ff4j.audit.chart.Serie; import org.ff4j.utils.Util; /** * Superclass implementing the custom serialization. * * @author Cedrick Lunven (@clunven) */ public abstract class AbstractEventRepository implements EventRepository { /** Create key. */ protected static final SimpleDateFormat KDF = new SimpleDateFormat("yyyyMMdd"); /** {@inheritDoc} */ @Override public PieChart getFeatureUsagePieChart(EventQueryDefinition q) { return renderPieChartRainBow(TITLE_PIE_HITCOUNT + getTitle(q), getFeatureUsageHitCount(q)); } /** {@inheritDoc} */ @Override public PieChart getHostPieChart(EventQueryDefinition q) { return renderPieChartGradient("HostNames " + getTitle(q), getHostHitCount(q), "00AB8B", "EEFFEE"); } /** {@inheritDoc} */ @Override public PieChart getSourcePieChart(EventQueryDefinition q) { return renderPieChartGradient("Sources " + getTitle(q), getSourceHitCount(q), "AB008B", "FFEEEE"); } /** {@inheritDoc} */ @Override public PieChart getUserPieChart(EventQueryDefinition q) { return renderPieChartGradient("Users " + getTitle(q), getUserHitCount(q), "008BAB", "EEEEFF"); } /** * Convert hicount into pieChart. * * @param hitRatio * current hist ratio * @return * pie chart */ protected PieChart renderPieChartGradient(String title, Map < String, MutableHitCount > hitRatio, String fromColor, String toColor) { return renderPieChart(title, hitRatio, Util.generateRGBGradient(fromColor, toColor, hitRatio.size())); } /** * Convert hicount into pieChart. * * @param hitRatio * current hist ratio * @return * pie chart */ protected PieChart renderPieChartRainBow(String title, Map < String, MutableHitCount > hitRatio) { return renderPieChart(title, hitRatio, Util.generateHSVGradient("ee1100", "442299", hitRatio.size())); } /** * Convert hicount into pieChart. * * @param hitRatio * current hist ratio * @return * pie chart */ private PieChart renderPieChart(String title, Map < String, MutableHitCount > hitRatio, List < String > colors) { PieChart pieChart = new PieChart(title); int idxColor = 0; for (String key : hitRatio.keySet()) { Serie<Integer> ps = new Serie<Integer>(key, hitRatio.get(key).get(), colors.get(idxColor)); pieChart.getSectors().add(ps); idxColor++; } return pieChart; } protected BarChart renderBarChartRainbow(String title, Map < String, MutableHitCount > hitRatio) { return renderBarChart(title, hitRatio, Util.generateHSVGradient("ee1100", "442299", hitRatio.size())); } protected BarChart renderBarChartGradient(String title, Map < String, MutableHitCount > hitRatio, String colorFrom, String colorTo) { return renderBarChart(title, hitRatio, Util.generateRGBGradient(colorFrom, colorTo, hitRatio.size())); } /** * Generation of title. * * @param q * current query * @return * title formated with slot. */ protected String getTitle(EventQueryDefinition q) { return " FROM <b>" + getKeyDate(q.getFrom()) + "</b> TO <b>" + getKeyDate(q.getTo()) + "</b>"; } /** * Convert hicount into pieChart. * * @param hitRatio * current hist ratio * @return * pie chart */ private BarChart renderBarChart(String title, Map < String, MutableHitCount > hitRatio, List < String > colors) { BarChart barChart = new BarChart(title); int idxColor = 0; for (String key : hitRatio.keySet()) { Serie<Integer> bar = new Serie<Integer>(key, new Double(hitRatio.get(key).get()).intValue(), colors.get(idxColor)); barChart.getChartBars().add(bar); idxColor++; } orderBarDecrecent(barChart); return barChart; } public void orderBarDecrecent(BarChart barChart) { Comparator<Serie<Integer>> c = new Comparator<Serie<Integer>>() { public int compare(Serie<Integer> o1, Serie<Integer> o2) { return o1.getValue() - o2.getValue(); } }; Collections.sort(barChart.getChartBars(), c); } /** {@inheritDoc} */ @Override public BarChart getFeatureUsageBarChart(EventQueryDefinition q) { return renderBarChartRainbow(TITLE_BARCHAR_HIT + getTitle(q), getFeatureUsageHitCount(q)); } /** {@inheritDoc} */ @Override public BarChart getHostBarChart(EventQueryDefinition q) { return renderBarChartGradient("BarChart 'host' FROM " + getTitle(q), getHostHitCount(q), "00AB8B", "EEFFEE"); } /** {@inheritDoc} */ @Override public BarChart getSourceBarChart(EventQueryDefinition q) { return renderBarChartGradient("BarChart 'Source' FROM " + getTitle(q), getSourceHitCount(q), "AB008B", "FFEEEE"); } /** {@inheritDoc} */ @Override public BarChart getUserBarChart(EventQueryDefinition q) { return renderBarChartGradient("BarChart 'User' FROM " + getTitle(q), getUserHitCount(q), "008BAB", "EEEEFF"); } /** {@inheritDoc} */ @Override public int getFeatureUsageTotalHitCount(EventQueryDefinition q) { Map < String, MutableHitCount > hitRatio = getFeatureUsageHitCount(q); int total = 0; if (hitRatio != null) { for (MutableHitCount hc : hitRatio.values()) { total += hc.get(); } } return total; } /** {@inheritDoc} */ @Override public String toString() { StringBuilder sb = new StringBuilder("{"); sb.append("\"type\":\"" + this.getClass().getCanonicalName() + "\""); EventQueryDefinition q = new EventQueryDefinition(); sb.append(",\"todayHitsPieChart\": " + getFeatureUsagePieChart(q).toJson()); sb.append(",\"todayHitsBarChart\": " + getFeatureUsageBarChart(q).toJson()); getFeatureUsageHistory(q, TimeUnit.HOURS); sb.append(",\"todayTotalHitCount\":" + getFeatureUsageTotalHitCount(q)); sb.append("}"); return sb.toString(); } /** * Utility. * * @param evt * current evenement * @param startTime * begin time * @param endTime * end time * @return * if the event is between dates */ protected boolean isEventInInterval(Event evt, long startTime, long endTime) { return (evt.getTimestamp() >= startTime) && (evt.getTimestamp() <= endTime); } /** * Format a timestamp to create a Key. * * @param time * current tick * @return * date as Key */ protected String getKeyDate(long time) { return KDF.format(new Date(time)); } /** * Will get a list of all days between 2 dates. * * @param startTime * tip start * @param endTime * tip end * @return * list of days */ protected Set < String > getCandidateDays(long startTime, long endTime) { Set < String > resultKeys = new TreeSet<String>(); String endKey = getKeyDate(endTime); resultKeys.add(endKey); long time = startTime; while (!endKey.equals(getKeyDate(time))) { resultKeys.add(getKeyDate(time)); time += 3600 * 1000 * 24; } return resultKeys; } }