package org.sigmah.server.handler; /* * #%L * Sigmah * %% * Copyright (C) 2010 - 2016 URD * %% * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this program. If not, see * <http://www.gnu.org/licenses/gpl-3.0.html>. * #L% */ import com.google.gson.Gson; import com.google.inject.Inject; import com.google.inject.Singleton; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import org.apache.commons.lang3.StringUtils; import org.apache.commons.mail.EmailException; import org.sigmah.client.util.profiler.Scenario; import org.sigmah.server.conf.Properties; import org.sigmah.server.dispatch.impl.UserDispatch; import org.sigmah.server.handler.base.AbstractCommandHandler; import org.sigmah.server.mail.Email; import org.sigmah.server.mail.EmailAttachment; import org.sigmah.server.mail.MailSender; import org.sigmah.shared.command.SendProbeReport; import org.sigmah.shared.command.result.Result; import org.sigmah.shared.conf.PropertyKey; import org.sigmah.shared.dispatch.CommandException; import org.sigmah.shared.dto.profile.ExecutionDTO; import org.sigmah.shared.dto.profile.ProbesReportDetails; import org.sigmah.shared.dto.profile.ScenarioDetailsDTO; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Handler for <code>SendProbeReport</code> command. * * @author Mohamed KHADHRAOUI (mohamed.khadhraoui@netapsys.fr) */ @Singleton public class SendProbeReportHandler extends AbstractCommandHandler<SendProbeReport, Result> { /** * Logger. */ private static final Logger LOGGER = LoggerFactory.getLogger(SendProbeReportHandler.class); /** * End of line. */ final String LINE_SEPARATOR = System.getProperty("line.separator"); /** * Injected application properties. */ @Inject private Properties properties; /** * Injected application properties. */ @Inject private MailSender sender; /** * Gson instance, used to transform java objects to json. */ private final Gson gson = new Gson(); /** * {@inheritDoc} */ @Override protected Result execute(final SendProbeReport command, final UserDispatch.UserExecutionContext context) throws CommandException { if (command.getExecutionsProfiler() != null) { final ProbesReportDetails probesReportDetails = buildProbesReportDetails(command.getExecutionsProfiler()); final Email email = buildEmail(); try { final EmailAttachment markdownReport = new EmailAttachment(properties.getProperty(PropertyKey.MAIL_OPTIMISATION_MARKDOWN_FILE_NAME), buildMarkDownFile(probesReportDetails)); final EmailAttachment rawReport = new EmailAttachment(properties.getProperty(PropertyKey.MAIL_OPTIMISATION_JSON_FILE_NAME), buildRawReportFile(command.getExecutionsProfiler())); sender.sendWithAttachments(email, markdownReport, rawReport); } catch (EmailException e) { LOGGER.error("An error occured while sending the probe report.", e); } } return null; } /** * Build the raw json report from the execution list. * * @param executions * Object to be serialized. * @return The content of the raw report. */ public byte[] buildRawReportFile(final List<ExecutionDTO> executions) { final String stringReport = gson.toJson(executions); return stringReport.getBytes(); } /** * Build the mark down report. * * @param probesReportDetails * Detail of the probe session to report. * @return The content of the main report. */ private byte[] buildMarkDownFile(final ProbesReportDetails probesReportDetails) { final StringBuilder sb = new StringBuilder(); sb.append("## Performance Report").append(LINE_SEPARATOR); sb.append(" * Sigmah version : ").append(probesReportDetails.getVersionNumber()).append(LINE_SEPARATOR); sb.append(" * Start time : ").append(probesReportDetails.getStartTime()).append(LINE_SEPARATOR); sb.append(" * End time : ").append(probesReportDetails.getEndTime()).append(LINE_SEPARATOR); sb.append(" * User Agent : ").append(probesReportDetails.getUserAgent()).append(LINE_SEPARATOR); sb.append(LINE_SEPARATOR); sb.append("### Scenarios execution time ").append(LINE_SEPARATOR); sb.append(" | **Scenario** | **Min** | **Max** | **Average** | ").append(LINE_SEPARATOR); for (ScenarioDetailsDTO scenario : probesReportDetails.getSenarios()) { sb.append(" | ").append(scenario.getScenario().name()).append(" | ").append(String.valueOf(scenario.getMinDuartion())).append(" | ").append(String.valueOf(scenario.getMaxDuration())).append(" | ").append(String.valueOf(scenario.getAvrageDuration())).append(" | ").append(LINE_SEPARATOR); } return sb.toString().getBytes(); } /** * Build the report model. * * @param executions * List of executions. * @return A summary of the probing session. */ private ProbesReportDetails buildProbesReportDetails(final List<ExecutionDTO> executions) { final ProbesReportDetails probesReportDetails = new ProbesReportDetails(); Date startTime = null; Date endDateTime = null; final Map<Scenario, List<ExecutionDTO>> scenarioExecutionMap = new HashMap<Scenario, List<ExecutionDTO>>(); for (ExecutionDTO execution : executions) { // build map (senarion, list of execution) if (scenarioExecutionMap.containsKey(execution.getScenario())) { scenarioExecutionMap.get(execution.getScenario()).add(execution); } else { final List<ExecutionDTO> newList = new ArrayList<ExecutionDTO>(); newList.add(execution); scenarioExecutionMap.put(execution.getScenario(), newList); } //initialize common parameters if (startTime == null || startTime.after(execution.getDate())) { startTime = execution.getDate(); } if (endDateTime == null || endDateTime.before(execution.getDate())) { endDateTime = execution.getDate(); } if (probesReportDetails.getUserAgent() == null) { probesReportDetails.setUserAgent(execution.getUserAgent()); } if (probesReportDetails.getVersionNumber() == null) { probesReportDetails.setVersionNumber(execution.getVersionNumber()); } } probesReportDetails.setStartTime(startTime); probesReportDetails.setEndTime(endDateTime); for (Entry<Scenario, List<ExecutionDTO>> entry : scenarioExecutionMap.entrySet()) { probesReportDetails.getSenarios().add(calculateSenarioDetails(entry.getKey(), entry.getValue())); } return probesReportDetails; } /** * Calculate scenario. * * @param scenarioDetailsDTO * Scenario details. * @param executions List execution of scenario. */ private ScenarioDetailsDTO calculateSenarioDetails(final Scenario scenario, final List<ExecutionDTO> executions) { double minDuration = 0; double maxDuration = -1; double sumDuration = 0; Date startTime = null; Date endDateTime = null; final ScenarioDetailsDTO scenarioDetails = new ScenarioDetailsDTO(); scenarioDetails.setScenario(scenario); for (ExecutionDTO execution : executions) { if (execution.getDuration() < minDuration || minDuration == 0) { minDuration = execution.getDuration(); } if (execution.getDuration() > maxDuration) { maxDuration = execution.getDuration(); } sumDuration += execution.getDuration(); if (startTime == null || startTime.after(execution.getDate())) { startTime = execution.getDate(); } if (endDateTime == null || endDateTime.before(execution.getDate())) { endDateTime = execution.getDate(); } } scenarioDetails.setMaxDuration(maxDuration); scenarioDetails.setMinDuartion(minDuration); scenarioDetails.setAvrageDuration(executions.size() > 0 ? sumDuration / executions.size() : -1); scenarioDetails.setEndTime(endDateTime); scenarioDetails.setStartTime(startTime); return scenarioDetails; } /** * Build Email object. * * @return A new email object. */ private Email buildEmail() { final Email email = new Email(); email.setFromAddress(properties.getProperty(PropertyKey.MAIL_FROM_ADDRESS)); email.setFromName(properties.getProperty(PropertyKey.MAIL_FROM_NAME)); String toAdresse = properties.getProperty(PropertyKey.MAIL_OPTIMISATION_TO_ADDRESS); email.setToAddresses(!StringUtils.isBlank(toAdresse) ? toAdresse.split(";") : new String[0]); String copyAdresse = properties.getProperty(PropertyKey.MAIL_OPTIMISATION_COPY_ADDRESS); email.setCcAddresses(!StringUtils.isBlank(copyAdresse) ? copyAdresse.split(";") : new String[0]); email.setContentType(properties.getProperty(PropertyKey.MAIL_CONTENT_TYPE)); email.setHostName(properties.getProperty(PropertyKey.MAIL_HOSTNAME)); email.setSmtpPort(properties.getIntegerProperty(PropertyKey.MAIL_PORT)); email.setEncoding(properties.getProperty(PropertyKey.MAIL_ENCODING)); email.setSubject("Optimisation message"); email.setContent(""); email.setAuthenticationUserName(properties.getProperty(PropertyKey.MAIL_AUTH_USERNAME)); email.setAuthenticationPassword(properties.getProperty(PropertyKey.MAIL_AUTH_PASSWORD)); return email; } }