View Javadoc
1   /*
2    * Copyright 2001-2008 The Apache Software Foundation.
3    * 
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * 
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    * 
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   *
16   */
17  package org.apache.juddi.subscription.notify;
18  
19  import java.io.StringWriter;
20  import java.net.URISyntaxException;
21  import java.rmi.RemoteException;
22  import java.security.InvalidAlgorithmParameterException;
23  import java.security.InvalidKeyException;
24  import java.security.NoSuchAlgorithmException;
25  import java.text.SimpleDateFormat;
26  import java.util.Date;
27  import java.util.Properties;
28  import javax.crypto.BadPaddingException;
29  import javax.crypto.IllegalBlockSizeException;
30  import javax.crypto.NoSuchPaddingException;
31  import javax.mail.Address;
32  import javax.mail.Message.RecipientType;
33  import javax.mail.Multipart;
34  import javax.mail.PasswordAuthentication;
35  import javax.mail.Session;
36  import javax.mail.Transport;
37  import javax.mail.internet.InternetAddress;
38  import javax.mail.internet.MimeBodyPart;
39  import javax.mail.internet.MimeMessage;
40  import javax.mail.internet.MimeMultipart;
41  import javax.xml.bind.JAXB;
42  
43  import org.apache.commons.lang.StringEscapeUtils;
44  import org.apache.juddi.config.AppConfig;
45  import org.apache.juddi.config.Property;
46  import org.apache.juddi.config.ResourceConfig;
47  import org.apache.juddi.cryptor.CryptorFactory;
48  import org.apache.juddi.jaxb.JAXBMarshaller;
49  import org.apache.juddi.mapping.MappingModelToApi;
50  import org.apache.juddi.model.BindingTemplate;
51  import org.apache.juddi.model.Publisher;
52  import org.apache.juddi.model.Subscription;
53  import org.uddi.api_v3.DispositionReport;
54  import org.uddi.api_v3.Result;
55  import org.uddi.sub_v3.SubscriptionFilter;
56  import org.uddi.sub_v3.SubscriptionResultsList;
57  import org.uddi.subr_v3.NotifySubscriptionListener;
58  import org.uddi.v3_service.DispositionReportFaultMessage;
59  
60  /**
61   * This class extends the default SMTP notifier The following properties can be
62   * set in the juddiv3.xml, or as System params.
63   *
64   * "mail.smtp.from", "mail.smtp.host", "mail.smtp.port",
65   * "mail.smtp.socketFactory.class", "mail.smtp.socketFactory.fallback",
66   * "mail.smtp.starttls.enable",
67   * "mail.smtp.socketFactory.port","mail.smtp.auth","mail.smtp.user","mail.smtp.password"
68   *
69   * The following properties can be set juddiv3.xml.
70   *
71   * @author Kurt Stam
72   * @author Alex O'Ree
73   */
74  public class USERFRIENDLYSMTPNotifier extends SMTPNotifier {
75  
76          public static void notifySubscriptionDeleted(TemporaryMailContainer container) {
77                  try {
78                          Publisher publisher = container.getPublisher();
79                          Publisher deletedBy = container.getDeletedBy();
80                          Subscription obj = container.getObj();
81                          String emailaddress = publisher.getEmailAddress();
82                          if (emailaddress==null || emailaddress.trim().equals(""))
83                                  return;
84                          Properties properties = new Properties();
85                          Session session = null;
86                          String mailPrefix = AppConfig.getConfiguration().getString(Property.JUDDI_EMAIL_PREFIX, Property.DEFAULT_JUDDI_EMAIL_PREFIX);
87                          if (!mailPrefix.endsWith(".")) {
88                                  mailPrefix = mailPrefix + ".";
89                          }
90                          for (String key : mailProps) {
91                                  if (AppConfig.getConfiguration().containsKey(mailPrefix + key)) {
92                                          properties.put(key, AppConfig.getConfiguration().getProperty(mailPrefix + key));
93                                  } else if (System.getProperty(mailPrefix + key) != null) {
94                                          properties.put(key, System.getProperty(mailPrefix + key));
95                                  }
96                          }
97  
98                          boolean auth = (properties.getProperty("mail.smtp.auth", "false")).equalsIgnoreCase("true");
99                          if (auth) {
100                                 final String username = properties.getProperty("mail.smtp.user");
101                                 String pwd = properties.getProperty("mail.smtp.password");
102                                 //decrypt if possible
103                                 if (properties.getProperty("mail.smtp.password" + Property.ENCRYPTED_ATTRIBUTE, "false").equalsIgnoreCase("true")) {
104                                         try {
105                                                 pwd = CryptorFactory.getCryptor().decrypt(pwd);
106                                         } catch (NoSuchPaddingException ex) {
107                                                 log.error("Unable to decrypt settings", ex);
108                                         } catch (NoSuchAlgorithmException ex) {
109                                                 log.error("Unable to decrypt settings", ex);
110                                         } catch (InvalidAlgorithmParameterException ex) {
111                                                 log.error("Unable to decrypt settings", ex);
112                                         } catch (InvalidKeyException ex) {
113                                                 log.error("Unable to decrypt settings", ex);
114                                         } catch (IllegalBlockSizeException ex) {
115                                                 log.error("Unable to decrypt settings", ex);
116                                         } catch (BadPaddingException ex) {
117                                                 log.error("Unable to decrypt settings", ex);
118                                         }
119                                 }
120                                 final String password = pwd;
121                                 log.debug("SMTP username = " + username + " from address = " + emailaddress);
122                                 Properties eMailProperties = properties;
123                                 eMailProperties.remove("mail.smtp.user");
124                                 eMailProperties.remove("mail.smtp.password");
125                                 session = Session.getInstance(properties, new javax.mail.Authenticator() {
126                                         protected PasswordAuthentication getPasswordAuthentication() {
127                                                 return new PasswordAuthentication(username, password);
128                                         }
129                                 });
130                         } else {
131                                 Properties eMailProperties = properties;
132                                 eMailProperties.remove("mail.smtp.user");
133                                 eMailProperties.remove("mail.smtp.password");
134                                 session = Session.getInstance(eMailProperties);
135                         }
136 
137                         MimeMessage message = new MimeMessage(session);
138                         InternetAddress address = new InternetAddress(emailaddress);
139                         Address[] to = {address};
140                         message.setRecipients(RecipientType.TO, to);
141                         message.setFrom(new InternetAddress(properties.getProperty("mail.smtp.from", "jUDDI")));
142                         //Hello %s,<br><br>Your subscription UDDI subscription was deleted. Attached is what the subscription was. It was deleted by %s, %s at %s. This node is %s
143                         //maybe nice to use a template rather then sending raw xml.
144                         org.uddi.sub_v3.Subscription api = new org.uddi.sub_v3.Subscription();
145                         MappingModelToApi.mapSubscription(obj, api);
146                         String subscriptionResultXML = JAXBMarshaller.marshallToString(api, JAXBMarshaller.PACKAGE_SUBSCR_RES);
147                         Multipart mp = new MimeMultipart();
148 
149                         MimeBodyPart content = new MimeBodyPart();
150                         String msg_content = ResourceConfig.getGlobalMessage("notifications.smtp.subscriptionDeleted");
151                         SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd kk:mm:ssZ");
152 //Hello %s, %s<br><br>Your subscription UDDI subscription was deleted. Attached is what the subscription was. It was deleted by %s, %s at %s. This node is %s.
153                         msg_content = String.format(msg_content,
154                                 StringEscapeUtils.escapeHtml(publisher.getPublisherName()),
155                                 StringEscapeUtils.escapeHtml(publisher.getAuthorizedName()),
156                                 StringEscapeUtils.escapeHtml(deletedBy.getPublisherName()),
157                                 StringEscapeUtils.escapeHtml(deletedBy.getAuthorizedName()),
158                                 StringEscapeUtils.escapeHtml(sdf.format(new Date())),
159                                 StringEscapeUtils.escapeHtml(AppConfig.getConfiguration().getString(Property.JUDDI_NODE_ID, "(unknown node id!)")),
160                                 AppConfig.getConfiguration().getString(Property.JUDDI_BASE_URL, "(unknown url)"),
161                                 AppConfig.getConfiguration().getString(Property.JUDDI_BASE_URL_SECURE, "(unknown url)")
162                         );
163 
164                         content.setContent(msg_content, "text/html; charset=UTF-8;");
165                         mp.addBodyPart(content);
166 
167                         MimeBodyPart attachment = new MimeBodyPart();
168                         attachment.setContent(subscriptionResultXML, "text/xml; charset=UTF-8;");
169                         attachment.setFileName("uddiNotification.xml");
170                         mp.addBodyPart(attachment);
171 
172                         message.setContent(mp);
173                         message.setSubject(ResourceConfig.getGlobalMessage("notifications.smtp.userfriendly.subject") + " "
174                                 + StringEscapeUtils.escapeHtml(obj.getSubscriptionKey()));
175                         Transport.send(message);
176 
177                 } catch (Throwable t) {
178                         log.warn("Error sending email!" + t.getMessage());
179                         log.debug("Error sending email!" + t.getMessage(),t);
180                 }
181         }
182 
183         public static void notifyAccountDeleted(TemporaryMailContainer container) {
184                 try {
185                         Publisher publisher = container.getPublisher();
186                         Publisher deletedBy = container.getDeletedBy();
187                         String emailaddress = publisher.getEmailAddress();
188                         if (emailaddress==null || emailaddress.trim().equals(""))
189                                 return;
190                         Properties properties = new Properties();
191                         Session session = null;
192                         String mailPrefix = AppConfig.getConfiguration().getString(Property.JUDDI_EMAIL_PREFIX, Property.DEFAULT_JUDDI_EMAIL_PREFIX);
193                         if (!mailPrefix.endsWith(".")) {
194                                 mailPrefix = mailPrefix + ".";
195                         }
196                         for (String key : mailProps) {
197                                 if (AppConfig.getConfiguration().containsKey(mailPrefix + key)) {
198                                         properties.put(key, AppConfig.getConfiguration().getProperty(mailPrefix + key));
199                                 } else if (System.getProperty(mailPrefix + key) != null) {
200                                         properties.put(key, System.getProperty(mailPrefix + key));
201                                 }
202                         }
203                         
204                         boolean auth = (properties.getProperty("mail.smtp.auth", "false")).equalsIgnoreCase("true");
205                         if (auth) {
206                                 final String username = properties.getProperty("mail.smtp.user");
207                                 String pwd = properties.getProperty("mail.smtp.password");
208                                 //decrypt if possible
209                                 if (properties.getProperty("mail.smtp.password" + Property.ENCRYPTED_ATTRIBUTE, "false").equalsIgnoreCase("true")) {
210                                         try {
211                                                 pwd = CryptorFactory.getCryptor().decrypt(pwd);
212                                         } catch (NoSuchPaddingException ex) {
213                                                 log.error("Unable to decrypt settings", ex);
214                                         } catch (NoSuchAlgorithmException ex) {
215                                                 log.error("Unable to decrypt settings", ex);
216                                         } catch (InvalidAlgorithmParameterException ex) {
217                                                 log.error("Unable to decrypt settings", ex);
218                                         } catch (InvalidKeyException ex) {
219                                                 log.error("Unable to decrypt settings", ex);
220                                         } catch (IllegalBlockSizeException ex) {
221                                                 log.error("Unable to decrypt settings", ex);
222                                         } catch (BadPaddingException ex) {
223                                                 log.error("Unable to decrypt settings", ex);
224                                         }
225                                 }
226                                 final String password = pwd;
227                                 log.debug("SMTP username = " + username + " from address = " + emailaddress);
228                                 Properties eMailProperties = properties;
229                                 eMailProperties.remove("mail.smtp.user");
230                                 eMailProperties.remove("mail.smtp.password");
231                                 session = Session.getInstance(properties, new javax.mail.Authenticator() {
232                                         protected PasswordAuthentication getPasswordAuthentication() {
233                                                 return new PasswordAuthentication(username, password);
234                                         }
235                                 });
236                         } else {
237                                 Properties eMailProperties = properties;
238                                 eMailProperties.remove("mail.smtp.user");
239                                 eMailProperties.remove("mail.smtp.password");
240                                 session = Session.getInstance(eMailProperties);
241                         }
242 
243                         MimeMessage message = new MimeMessage(session);
244                         InternetAddress address = new InternetAddress(emailaddress);
245                         Address[] to = {address};
246                         message.setRecipients(RecipientType.TO, to);
247                         message.setFrom(new InternetAddress(properties.getProperty("mail.smtp.from", "jUDDI")));
248                                 //Hello %s,<br><br>Your subscription UDDI subscription was deleted. Attached is what the subscription was. It was deleted by %s, %s at %s. This node is %s
249 
250                         Multipart mp = new MimeMultipart();
251 
252                         MimeBodyPart content = new MimeBodyPart();
253                         String msg_content = ResourceConfig.getGlobalMessage("notifications.smtp.accountDeleted");
254                         SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd kk:mm:ssZ");
255 //Hello %s, %s,<br><br>Your account has been deleted by %s, %s at %s. This node is %s.
256                         msg_content = String.format(msg_content,
257                                 StringEscapeUtils.escapeHtml(publisher.getPublisherName()),
258                                 StringEscapeUtils.escapeHtml(publisher.getAuthorizedName()),
259                                 StringEscapeUtils.escapeHtml(deletedBy.getPublisherName()),
260                                 StringEscapeUtils.escapeHtml(deletedBy.getAuthorizedName()),
261                                 StringEscapeUtils.escapeHtml(sdf.format(new Date())),
262                                 StringEscapeUtils.escapeHtml(AppConfig.getConfiguration().getString(Property.JUDDI_NODE_ID, "(unknown node id!)")),
263                                 AppConfig.getConfiguration().getString(Property.JUDDI_BASE_URL, "(unknown url)"),
264                                 AppConfig.getConfiguration().getString(Property.JUDDI_BASE_URL_SECURE, "(unknown url)")
265                         );
266 
267                         content.setContent(msg_content, "text/html; charset=UTF-8;");
268                         mp.addBodyPart(content);
269 
270                         message.setContent(mp);
271                         message.setSubject(ResourceConfig.getGlobalMessage("notifications.smtp.accountDeleted.subject"));
272                         Transport.send(message);
273 
274                 } catch (Throwable t) {
275                         log.warn("Error sending email!" + t.getMessage());
276                         log.debug("Error sending email!" + t.getMessage(), t);
277                 }
278         }
279 
280         public USERFRIENDLYSMTPNotifier(BindingTemplate bindingTemplate) throws URISyntaxException, Exception {
281                 super(bindingTemplate);
282                 publisherName = bindingTemplate.getAuthorizedName();
283         }
284 
285         String publisherName;
286 
287         @Override
288         public DispositionReport notifySubscriptionListener(NotifySubscriptionListener body) throws DispositionReportFaultMessage, RemoteException {
289 
290                 try {
291                         log.info("Sending notification email to " + notificationEmailAddress + " from " + getEMailProperties().getProperty("mail.smtp.from", "jUDDI"));
292                         if (session != null && notificationEmailAddress != null) {
293                                 MimeMessage message = new MimeMessage(session);
294                                 InternetAddress address = new InternetAddress(notificationEmailAddress);
295                                 Address[] to = {address};
296                                 message.setRecipients(RecipientType.TO, to);
297                                 message.setFrom(new InternetAddress(getEMailProperties().getProperty("mail.smtp.from", "jUDDI")));
298                                 //maybe nice to use a template rather then sending raw xml.
299                                 String subscriptionResultXML = JAXBMarshaller.marshallToString(body, JAXBMarshaller.PACKAGE_SUBSCR_RES);
300                                 Multipart mp = new MimeMultipart();
301 
302                                 MimeBodyPart content = new MimeBodyPart();
303                                 String msg_content = ResourceConfig.getGlobalMessage("notifications.smtp.userfriendly.body");
304 
305                                 msg_content = String.format(msg_content,
306                                         StringEscapeUtils.escapeHtml(this.publisherName),
307                                         StringEscapeUtils.escapeHtml(AppConfig.getConfiguration().getString(Property.JUDDI_NODE_ID, "(unknown node id!)")),
308                                         GetSubscriptionType(body),
309                                         GetChangeSummary(body));
310 
311                                 content.setContent(msg_content, "text/html; charset=UTF-8;");
312                                 mp.addBodyPart(content);
313 
314                                 MimeBodyPart attachment = new MimeBodyPart();
315                                 attachment.setContent(subscriptionResultXML, "text/xml; charset=UTF-8;");
316                                 attachment.setFileName("uddiNotification.xml");
317                                 mp.addBodyPart(attachment);
318 
319                                 message.setContent(mp);
320                                 message.setSubject(ResourceConfig.getGlobalMessage("notifications.smtp.userfriendly.subject") + " "
321                                         + body.getSubscriptionResultsList().getSubscription().getSubscriptionKey());
322                                 Transport.send(message);
323                         } else {
324                                 throw new DispositionReportFaultMessage("Session is null!", null);
325                         }
326                 } catch (Exception e) {
327                         log.error(e.getMessage(), e);
328                         throw new DispositionReportFaultMessage(e.getMessage(), null);
329                 }
330 
331                 DispositionReport dr = new DispositionReport();
332                 Result res = new Result();
333                 dr.getResult().add(res);
334 
335                 return dr;
336         }
337 
338         static String GetChangeSummary(NotifySubscriptionListener body) {
339                 SubscriptionResultsList r = body.getSubscriptionResultsList();
340                 StringWriter sw = new StringWriter();
341 
342                 if (r.getAssertionStatusReport() != null) {
343                         JAXB.marshal(r.getAssertionStatusReport(), sw);
344                 } else if (r.getBindingDetail() != null) {
345                         JAXB.marshal(r.getBindingDetail(), sw);
346                 } else if (r.getBusinessDetail() != null) {
347                         JAXB.marshal(r.getBusinessDetail(), sw);
348                 } else if (r.getBusinessList() != null) {
349                         JAXB.marshal(r.getBusinessList(), sw);
350                 } else if (r.getRelatedBusinessesList() != null) {
351                         JAXB.marshal(r.getRelatedBusinessesList(), sw);
352                 } else if (r.getServiceDetail() != null) {
353                         JAXB.marshal(r.getServiceDetail(), sw);
354                 } else if (r.getServiceList() != null) {
355                         JAXB.marshal(r.getServiceList(), sw);
356                 } else if (r.getTModelDetail() != null) {
357                         JAXB.marshal(r.getTModelDetail(), sw);
358                 } else if (r.getTModelList() != null) {
359                         JAXB.marshal(r.getTModelList(), sw);
360                 }
361 
362                 return "<pre>" + StringEscapeUtils.escapeHtml(sw.toString()) + "</pre>";
363         }
364 
365         static String GetSubscriptionType(NotifySubscriptionListener body) {
366                 if (body != null && body.getSubscriptionResultsList() != null
367                         && body.getSubscriptionResultsList().getSubscription() != null
368                         && body.getSubscriptionResultsList().getSubscription().getSubscriptionFilter() != null) {
369                         SubscriptionFilter sub = body.getSubscriptionResultsList().getSubscription().getSubscriptionFilter();
370                         if (sub.getFindBinding() != null) {
371                                 return " binding search results";
372                         }
373                         if (sub.getFindBusiness() != null) {
374                                 return " business search results";
375                         }
376                         if (sub.getFindRelatedBusinesses() != null) {
377                                 return " related business search results";
378                         }
379                         if (sub.getFindService() != null) {
380                                 return " service search results";
381                         }
382                         if (sub.getFindTModel() != null) {
383                                 return " tModel search results";
384                         }
385                         if (sub.getGetAssertionStatusReport() != null) {
386                                 return " assertion status report";
387                         }
388                         if (sub.getGetBindingDetail() != null) {
389                                 return " details on a specific binding";
390                         }
391                         if (sub.getGetBusinessDetail() != null) {
392                                 return " details on a specific business";
393                         }
394                         if (sub.getGetServiceDetail() != null) {
395                                 return " details on a specific service";
396                         }
397                         if (sub.getGetTModelDetail() != null) {
398                                 return " details on a specific tModel";
399                         }
400                 }
401                 return " (unable to determine what the subscription type is)";
402 
403         }
404 
405 }