/******************************************************************************* * Copyright 2006 - 2012 Vienna University of Technology, * Department of Software Technology and Interactive Systems, IFS * * 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 eu.scape_project.planning.application; import java.io.PrintWriter; import java.io.Serializable; import java.io.StringWriter; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Properties; import java.util.UUID; import javax.annotation.PostConstruct; import javax.annotation.Resource; import javax.enterprise.context.RequestScoped; import javax.inject.Inject; import javax.mail.Message.RecipientType; import javax.mail.MessagingException; import javax.mail.Session; import javax.mail.Transport; import javax.mail.internet.InternetAddress; import javax.mail.internet.MimeMessage; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import javax.transaction.UserTransaction; import org.apache.commons.configuration.Configuration; import org.slf4j.Logger; import eu.scape_project.planning.model.Notification; import eu.scape_project.planning.model.Plan; import eu.scape_project.planning.model.User; import eu.scape_project.planning.utils.ConfigurationLoader; /** * Sends a bug report. */ @RequestScoped public class BugReport implements Serializable { private static final long serialVersionUID = -2769514045862394110L; private static final String SEPARATOR_LINE = "-------------------------------------------\n"; private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); @Inject private Logger log; @Inject private User user; @Inject private Messages messages; @Inject private ConfigurationLoader configurationLoader; @PersistenceContext private EntityManager em; @Resource private UserTransaction utx; private Configuration config; /** * Initialises the class. */ @PostConstruct public void init() { config = configurationLoader.load(); } /** * Method responsible for sending a bug report per mail. * * @param userEmail * email address of the user. * @param errorDescription * error description given by the user. * @param exception * the exception causing the bug/error. * @param location * the location of the application where the error occurred * @throws MailException * if the bug report could not be sent */ public void sendBugReport(String userEmail, String errorDescription, Throwable exception, String location) throws MailException { sendBugReport(userEmail, errorDescription, exception, location, "PlanningSuite", null); } /** * Method responsible for sending a bug report per mail. * * @param userEmail * email address of the user. * @param errorDescription * error description given by the user. * @param exception * the exception causing the bug/error. * @param requestUri * request URI where the error occurred * @param location * the location of the application where the error occurred * @param applicationName * application name * @throws MailException * if the bug report could not be sent */ public void sendBugReport(String userEmail, String errorDescription, Throwable exception, String requestUri, String location, String applicationName) throws MailException { sendBugReport(userEmail, errorDescription, exception, requestUri, location, applicationName, null); } /** * Method responsible for sending a bug report per mail. * * @param userEmail * email address of the user. * @param errorDescription * error description given by the user. * @param exception * the exception causing the bug/error. * @param requestUri * request URI where the error occurred * @param location * the location of the application where the error occurred * @param applicationName * application name * @param plan * the plan where the exception occurred * @throws MailException * if the bug report could not be sent */ public void sendBugReport(String userEmail, String errorDescription, Throwable exception, String requestUri, String location, String applicationName, Plan plan) throws MailException { try { Properties props = System.getProperties(); props.put("mail.smtp.host", config.getString("mail.smtp.host")); Session session = Session.getDefaultInstance(props, null); MimeMessage message = new MimeMessage(session); message.setFrom(new InternetAddress(config.getString("mail.from"))); message.setRecipient(RecipientType.TO, new InternetAddress(config.getString("mail.feedback"))); message.setSubject("[" + applicationName + "] from " + location); StringBuilder builder = new StringBuilder(); // Date builder.append("Date: ").append(DATE_FORMAT.format(new Date())).append("\n\n"); // User info if (user == null) { builder.append("No user available.\n\n"); } else { builder.append("User: ").append(user.getUsername()).append("\n"); if (user.getUserGroup() != null) { builder.append("Group: ").append(user.getUserGroup().getName()).append("\n"); } } builder.append("UserMail: ").append(userEmail).append("\n\n"); // Plan if (plan == null) { builder.append("No plan available.").append("\n\n"); } else { builder.append("Plan ID: ").append(plan.getPlanProperties().getId()).append("\n"); builder.append("Plan name: ").append(plan.getPlanProperties().getName()).append("\n\n"); } // Description builder.append("Description:\n"); builder.append(SEPARATOR_LINE); builder.append(errorDescription).append("\n"); builder.append(SEPARATOR_LINE).append("\n"); // Request URI builder.append("Request URI: ").append(requestUri).append("\n\n"); // Exception if (exception == null) { builder.append("No exception available.").append("\n"); } else { builder.append("Exception type: ").append(exception.getClass().getCanonicalName()).append("\n"); builder.append("Exception message: ").append(exception.getMessage()).append("\n"); StringWriter writer = new StringWriter(); exception.printStackTrace(new PrintWriter(writer)); builder.append("Stacktrace:\n"); builder.append(SEPARATOR_LINE); builder.append(writer.toString()); builder.append(SEPARATOR_LINE); } message.setText(builder.toString()); message.saveChanges(); Transport.send(message); log.debug("Bug report mail from user {} sent successfully to {}", user.getUsername(), config.getString("mail.feedback")); String userMessage = "Bugreport sent. Thank you for your feedback. We will try to analyse and resolve the issue as soon as possible."; Notification notification = new Notification(UUID.randomUUID().toString(), new Date(), "PLATO", userMessage, user); try { utx.begin(); em.persist(notification); utx.commit(); } catch (Exception e) { log.error("Failed to store user notification for bugreport of {}", user.getUsername(), e); } } catch (MessagingException e) { throw new MailException("Error sending bug report mail from user " + user.getUsername() + " to " + config.getString("mail.feedback"), e); } } /** * Adds the provided throwable and session information to the messages list. * * @param throwable * the throwable * @param sessionId * the current session ID * @param currentPage * the current page */ public void addExeptionToMessages(Throwable throwable, String sessionId, String currentPage) { addExeptionToMessages(throwable, sessionId, currentPage, null); } /** * Adds the provided throwable and session information to the messages list. * * @param throwable * the throwable * @param sessionId * the current session ID * @param currentPage * the current page * @param currentPlan * the current plan */ public void addExeptionToMessages(Throwable throwable, String sessionId, String currentPage, Plan currentPlan) { String username = null; if (user != null) { username = user.getUsername(); } else { username = ""; } ErrorMessage em = new ErrorMessage(throwable.getClass().getCanonicalName(), throwable.getMessage(), sessionId, username, currentPage, currentPlan); messages.addErrorMessage(em); log.debug("Added Error to Messages array: " + throwable.getClass().getCanonicalName()); } }