• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright 2016 Google Inc. All Rights Reserved.
3  *
4  * <p>Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
5  * except in compliance with the License. You may obtain a copy of the License at
6  *
7  * <p>http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * <p>Unless required by applicable law or agreed to in writing, software distributed under the
10  * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
11  * express or implied. See the License for the specific language governing permissions and
12  * limitations under the License.
13  */
14 package com.android.vts.util;
15 
16 import com.android.vts.entity.UserFavoriteEntity;
17 import com.google.appengine.api.datastore.DatastoreService;
18 import com.google.appengine.api.datastore.DatastoreServiceFactory;
19 import com.google.appengine.api.datastore.Entity;
20 import com.google.appengine.api.datastore.Key;
21 import com.google.appengine.api.datastore.Query;
22 import com.google.appengine.api.datastore.Query.Filter;
23 import com.google.appengine.api.datastore.Query.FilterOperator;
24 import com.google.appengine.api.datastore.Query.FilterPredicate;
25 import java.io.IOException;
26 import java.io.UnsupportedEncodingException;
27 import java.util.ArrayList;
28 import java.util.HashSet;
29 import java.util.List;
30 import java.util.Properties;
31 import java.util.Set;
32 import java.util.logging.Level;
33 import java.util.logging.Logger;
34 import javax.mail.Message;
35 import javax.mail.MessagingException;
36 import javax.mail.Session;
37 import javax.mail.Transport;
38 import javax.mail.internet.InternetAddress;
39 import javax.mail.internet.MimeMessage;
40 import org.apache.commons.lang.StringUtils;
41 
42 /** EmailHelper, a helper class for building and sending emails. */
43 public class EmailHelper {
44     protected static final Logger logger = Logger.getLogger(EmailHelper.class.getName());
45     protected static final String DEFAULT_EMAIL = System.getProperty("DEFAULT_EMAIL");
46     protected static final String EMAIL_DOMAIN = System.getProperty("EMAIL_DOMAIN");
47     protected static final String SENDER_EMAIL = System.getProperty("SENDER_EMAIL");
48     private static final String VTS_EMAIL_NAME = "VTS Alert Bot";
49 
50     /**
51      * Fetches the list of subscriber email addresses for a test.
52      *
53      * @param testKey The key for the test for which to fetch the email addresses.
54      * @returns List of email addresses (String).
55      * @throws IOException
56      */
getSubscriberEmails(Key testKey)57     public static List<String> getSubscriberEmails(Key testKey) throws IOException {
58         DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
59         Filter testFilter =
60                 new FilterPredicate(UserFavoriteEntity.TEST_KEY, FilterOperator.EQUAL, testKey);
61         Query favoritesQuery = new Query(UserFavoriteEntity.KIND).setFilter(testFilter);
62         Set<String> emailSet = new HashSet<>();
63         if (!StringUtils.isBlank(DEFAULT_EMAIL)) {
64             emailSet.add(DEFAULT_EMAIL);
65         }
66         for (Entity favorite : datastore.prepare(favoritesQuery).asIterable()) {
67             UserFavoriteEntity favoriteEntity = UserFavoriteEntity.fromEntity(favorite);
68             if (favoriteEntity != null && favoriteEntity.user != null
69                     && favoriteEntity.user.getEmail().endsWith(EMAIL_DOMAIN)) {
70                 emailSet.add(favoriteEntity.user.getEmail());
71             }
72         }
73         return new ArrayList<>(emailSet);
74     }
75 
76     /**
77      * Sends an email to the specified email address to notify of a test status change.
78      *
79      * @param emails List of subscriber email addresses (byte[]) to which the email should be sent.
80      * @param subject The email subject field, string.
81      * @param body The html (string) body to send in the email.
82      * @returns The Message object to be sent.
83      * @throws MessagingException, UnsupportedEncodingException
84      */
composeEmail(List<String> emails, String subject, String body)85     public static Message composeEmail(List<String> emails, String subject, String body)
86             throws MessagingException, UnsupportedEncodingException {
87         if (emails.size() == 0) {
88             throw new MessagingException("No subscriber email addresses provided");
89         }
90         Properties props = new Properties();
91         Session session = Session.getDefaultInstance(props, null);
92 
93         Message msg = new MimeMessage(session);
94         for (String email : emails) {
95             try {
96                 msg.addRecipient(Message.RecipientType.TO, new InternetAddress(email, email));
97             } catch (MessagingException | UnsupportedEncodingException e) {
98                 // Gracefully continue when a subscriber email is invalid.
99                 logger.log(Level.WARNING, "Error sending email to recipient " + email + " : ", e);
100             }
101         }
102         msg.setFrom(new InternetAddress(SENDER_EMAIL, VTS_EMAIL_NAME));
103         msg.setSubject(subject);
104         msg.setContent(body, "text/html; charset=utf-8");
105         return msg;
106     }
107 
108     /**
109      * Sends an email.
110      *
111      * @param msg Message object to send.
112      * @returns true if the message sends successfully, false otherwise
113      */
send(Message msg)114     public static boolean send(Message msg) {
115         try {
116             Transport.send(msg);
117         } catch (MessagingException e) {
118             logger.log(Level.WARNING, "Error sending email : ", e);
119             return false;
120         }
121         return true;
122     }
123 
124     /**
125      * Sends a list of emails and logs any failures.
126      *
127      * @param messages List of Message objects to be sent.
128      */
sendAll(List<Message> messages)129     public static void sendAll(List<Message> messages) {
130         for (Message msg : messages) {
131             send(msg);
132         }
133     }
134 
135     /**
136      * Sends an email.
137      *
138      * @param recipients List of email address strings to which an email will be sent.
139      * @param subject The subject of the email.
140      * @param body The body of the email.
141      * @returns true if the message sends successfully, false otherwise
142      */
send(List<String> recipients, String subject, String body)143     public static boolean send(List<String> recipients, String subject, String body) {
144         try {
145             Message msg = composeEmail(recipients, subject, body);
146             return send(msg);
147         } catch (MessagingException | UnsupportedEncodingException e) {
148             logger.log(Level.WARNING, "Error composing email : ", e);
149             return false;
150         }
151     }
152 }
153