From a318104314cb92ca70dd93efd66b23b103244289 Mon Sep 17 00:00:00 2001 From: Roland Haeder Date: Sun, 13 Mar 2016 18:31:12 +0100 Subject: [PATCH] Continued with email delivery: - Added EJB for email change mail delivery - added needed jar(s) - updated project files --- lib/jmailer-ee.jar | Bin 0 -> 8085 bytes nbproject/build-impl.xml | 8 +- nbproject/genfiles.properties | 6 +- nbproject/project.properties | 3 + nbproject/project.xml | 1 + .../JobsEmailDeliveryMessageBean.java | 153 ++++++++++++++++++ .../JobsEmailChangeSessionBean.java | 113 +++++++++++-- 7 files changed, 266 insertions(+), 18 deletions(-) create mode 100644 lib/jmailer-ee.jar create mode 100644 src/java/org/mxchange/jmailee/model/delivery/JobsEmailDeliveryMessageBean.java diff --git a/lib/jmailer-ee.jar b/lib/jmailer-ee.jar new file mode 100644 index 0000000000000000000000000000000000000000..ec343a7cc8b5b2bfa7d1581a51a80d6435b9a38e GIT binary patch literal 8085 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 + @@ -849,9 +850,10 @@ exists or setup the property manually. For example like this: + - + @@ -862,7 +864,8 @@ exists or setup the property manually. For example like this: - + + @@ -876,6 +879,7 @@ exists or setup the property manually. For example like this: + diff --git a/nbproject/genfiles.properties b/nbproject/genfiles.properties index 06c57ad..9d653d1 100644 --- a/nbproject/genfiles.properties +++ b/nbproject/genfiles.properties @@ -1,8 +1,8 @@ -build.xml.data.CRC32=1100511e +build.xml.data.CRC32=8210263f build.xml.script.CRC32=9c0f08a9 build.xml.stylesheet.CRC32=5910fda3@1.55.1 # This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. # Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. -nbproject/build-impl.xml.data.CRC32=1100511e -nbproject/build-impl.xml.script.CRC32=866bcec0 +nbproject/build-impl.xml.data.CRC32=8210263f +nbproject/build-impl.xml.script.CRC32=1069361c nbproject/build-impl.xml.stylesheet.CRC32=6096d939@1.55.1 diff --git a/nbproject/project.properties b/nbproject/project.properties index e3a440e..9ff211d 100644 --- a/nbproject/project.properties +++ b/nbproject/project.properties @@ -28,6 +28,7 @@ file.reference.jcore.jar=lib/jcore.jar file.reference.jcoreee.jar=lib/jcoreee.jar file.reference.jcountry-core.jar=lib/jcountry-core.jar file.reference.jletter-lib.jar=lib/jletter-lib.jar +file.reference.jmailer-ee.jar=lib/jmailer-ee.jar file.reference.jphone-core.jar=lib/jphone-core.jar file.reference.juser-core.jar=lib/juser-core.jar file.reference.juser-lib.jar=lib/juser-lib.jar @@ -56,6 +57,7 @@ javac.classpath=\ ${file.reference.juser-core.jar}:\ ${file.reference.juser-lib.jar}:\ ${file.reference.jletter-lib.jar}:\ + ${file.reference.jmailer-ee.jar}:\ ${reference.jjobs-lib.jar} javac.compilerargs=-Xlint:unchecked -Xlint:deprecation javac.debug=true @@ -101,6 +103,7 @@ source.reference.jcore.jar=../jcore/src/ source.reference.jcoreee.jar=../jcoreee/src/ source.reference.jcountry-core.jar=../jcountry-core/src/ source.reference.jletter-lib.jar=../jletter-lib/src/ +source.reference.jmailer-ee.jar=../jmailer-ee/src/ source.reference.jphone-core.jar=../jphone-core/src/ source.reference.juser-core.jar=../juser-core/src/ source.reference.juser-lib.jar=../juser-lib/src/ diff --git a/nbproject/project.xml b/nbproject/project.xml index 8b607f6..4713c99 100644 --- a/nbproject/project.xml +++ b/nbproject/project.xml @@ -15,6 +15,7 @@ file.reference.juser-core.jar file.reference.juser-lib.jar file.reference.jletter-lib.jar + file.reference.jmailer-ee.jar reference.jjobs-lib.jar diff --git a/src/java/org/mxchange/jmailee/model/delivery/JobsEmailDeliveryMessageBean.java b/src/java/org/mxchange/jmailee/model/delivery/JobsEmailDeliveryMessageBean.java new file mode 100644 index 0000000..a912f53 --- /dev/null +++ b/src/java/org/mxchange/jmailee/model/delivery/JobsEmailDeliveryMessageBean.java @@ -0,0 +1,153 @@ +/* + * Copyright (C) 2016 quix0r + * + * 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 . + */ +package org.mxchange.jmailee.model.delivery; + +import java.io.Serializable; +import java.text.MessageFormat; +import java.util.Date; +import javax.annotation.Resource; +import javax.ejb.ActivationConfigProperty; +import javax.ejb.MessageDriven; +import javax.jms.JMSException; +import javax.jms.Message; +import javax.jms.MessageListener; +import javax.jms.ObjectMessage; +import javax.mail.MessagingException; +import javax.mail.Session; +import javax.mail.Transport; +import javax.mail.internet.InternetAddress; +import javax.mail.internet.MimeMessage; +import javax.naming.Context; +import javax.naming.InitialContext; +import javax.naming.NamingException; +import org.mxchange.jcoreeelogger.beans.local.logger.Log; +import org.mxchange.jcoreeelogger.beans.local.logger.LoggerBeanLocal; + +/** + * A message queue for sending out emails + *

+ * @author Roland Haeder + */ +@MessageDriven (activationConfig = { + @ActivationConfigProperty (propertyName = "destinationLookup", propertyValue = "jms/jjobs-email-queue"), + @ActivationConfigProperty (propertyName = "destinationType", propertyValue = "javax.jms.Queue") +}) +public class JobsEmailDeliveryMessageBean implements MessageListener { + + /** + * Email session + */ + @Resource (name = "jmail/jjobs") + private Session jmailjjobs; + + /** + * Logger bean + */ + @Log + private LoggerBeanLocal loggerBeanLocal; + + /** + * Default constructor + */ + public JobsEmailDeliveryMessageBean () { + try { + // Get initial context + Context context = new InitialContext(); + + // Lookup logger + this.loggerBeanLocal = (LoggerBeanLocal) context.lookup("java:global/jcore-logger-ejb/logger!org.mxchange.jcoreeelogger.beans.local.logger.LoggerBeanLocal"); //NOI18N + } catch (final NamingException ex) { + // Continue to throw + throw new RuntimeException("context.lookup() failed.", ex); //NOI18N + } + } + + @Override + public void onMessage (final Message message) { + // Trace message + this.loggerBeanLocal.logTrace(MessageFormat.format("onMessage: message={0} - CALLED!", message)); //NOI18N + + // Is the message castable to ObjectMessage? + if (null == message) { + // message is null + throw new NullPointerException("message is null"); //NOI18N + } else if (!(message instanceof ObjectMessage)) { + // Not castable + throw new ClassCastException(MessageFormat.format("message cannot be casted to ObjectMessage: {0}", message)); //NOI18N + } + + // Securely cast it + ObjectMessage objectMessage = (ObjectMessage) message; + + // Init instance + Serializable object; + + try { + // Get object from it + object = objectMessage.getObject(); + } catch (final JMSException ex) { + // Log exception ... + this.loggerBeanLocal.logException(ex); + + // ... and don't continue + return; + } + + // Debug message + this.loggerBeanLocal.logDebug(MessageFormat.format("onMessage: object={0}", object)); //NOI18N + + // Does this object implement WrapableCheckout ? + if (null == object) { + // object cannot be null + throw new NullPointerException("object is null"); //NOI18N + } else if (!(object instanceof WrapableEmailDelivery)) { + // Not proper interface used + throw new ClassCastException(MessageFormat.format("object does not implement WrapableEmailDelivery: {0}", object)); //NOI18N + } + + // Cast the object to the wrapper interface + WrapableEmailDelivery emailDelivery = (WrapableEmailDelivery) object; + + // Trace message + this.loggerBeanLocal.logTrace("onMessage: EXIT!"); //NOI18N + } + + /** + * Sends an email to given email address with subject line. + *

+ * @param emailAddress Email address for recipient + * @param subjectLine Subject line + * @param body Body part + *

+ * @throws NamingException If the resource cannot be found + * @throws MessagingException If something happened on message delivery + */ + private void sendMail (final String emailAddress, final String subjectLine, final String body) throws NamingException, MessagingException { + // Get MIME message instance + MimeMessage message = new MimeMessage(this.jmailjjobs); + + // Set subject, recipients and body + message.setSubject(subjectLine); + message.setRecipients(javax.mail.Message.RecipientType.TO, InternetAddress.parse(emailAddress, true)); + message.setSentDate(new Date()); + message.setText(body); + + // Directly send email + Transport.send(message); + } + +} diff --git a/src/java/org/mxchange/jusercore/model/email_address/JobsEmailChangeSessionBean.java b/src/java/org/mxchange/jusercore/model/email_address/JobsEmailChangeSessionBean.java index 1a67eb1..4b5fe41 100644 --- a/src/java/org/mxchange/jusercore/model/email_address/JobsEmailChangeSessionBean.java +++ b/src/java/org/mxchange/jusercore/model/email_address/JobsEmailChangeSessionBean.java @@ -19,12 +19,26 @@ package org.mxchange.jusercore.model.email_address; import java.text.MessageFormat; import java.util.GregorianCalendar; import java.util.List; +import javax.annotation.PostConstruct; import javax.ejb.EJB; import javax.ejb.EJBException; import javax.ejb.Stateless; +import javax.faces.FacesException; +import javax.jms.Connection; +import javax.jms.JMSException; +import javax.jms.MessageProducer; +import javax.jms.ObjectMessage; +import javax.jms.Queue; +import javax.jms.QueueConnectionFactory; +import javax.jms.Session; +import javax.naming.Context; +import javax.naming.InitialContext; +import javax.naming.NamingException; import javax.persistence.NoResultException; import javax.persistence.Query; import org.mxchange.jcoreee.database.BaseDatabaseBean; +import org.mxchange.jmailee.model.delivery.DeliverableEmail; +import org.mxchange.jmailee.model.delivery.Mailer; import org.mxchange.jusercore.model.user.UserSessionBeanRemote; import org.mxchange.jusercore.model.user.UserUtils; @@ -41,6 +55,31 @@ public class JobsEmailChangeSessionBean extends BaseDatabaseBean implements Emai */ private static final long serialVersionUID = 182_698_165_971_548L; + /** + * Connection + */ + private Connection connection; + + /** + * Object message + */ + private ObjectMessage message; + + /** + * Message producer + */ + private MessageProducer messageProducer; + + /** + * Mailer message queue + */ + private Queue queue; + + /** + * Session instance + */ + private Session session; + /** * User bean */ @@ -73,30 +112,78 @@ public class JobsEmailChangeSessionBean extends BaseDatabaseBean implements Emai } @Override - public void enqueueEmailAddressForChange (final ChangeableEmailAddress emailAddress) { + public void enqueueEmailAddressForChange (final ChangeableEmailAddress emailChange) { // Trace message - this.getLoggerBeanLocal().logTrace(MessageFormat.format("enqueueEmailAddressForChange: emailAddress={0} - CALLED!", emailAddress)); //NOI18N + this.getLoggerBeanLocal().logTrace(MessageFormat.format("enqueueEmailAddressForChange: emailChange={0} - CALLED!", emailChange)); //NOI18N // Email address change should be valid - if (null == emailAddress) { + if (null == emailChange) { // Abort here - throw new NullPointerException("emailAddress is null"); //NOI18N - } else if (!this.userBean.ifUserExists(emailAddress.getEmailChangeUser())) { + throw new NullPointerException("emailChange is null"); //NOI18N + } else if (emailChange.getEmailChangeUser() == null) { + // Throw NPE again + throw new NullPointerException("emailChange.emailChangeUser is null"); //NOI18N + } else if (emailChange.getEmailChangeUser().getUserId() == null) { + // Throw NPE again + throw new NullPointerException("emailChange.emailChangeUser.userId is null"); //NOI18N + } else if (emailChange.getEmailChangeUser().getUserId() < 1) { + // Not valid id + throw new IllegalArgumentException(MessageFormat.format("emailChange.emailChangeUser.userId={0} is invalid.", emailChange.getEmailChangeUser().getUserId())); //NOI18N + } else if (!this.userBean.ifUserExists(emailChange.getEmailChangeUser())) { // User does not exist - throw new EJBException(MessageFormat.format("Email change with id {0} does not exist.", emailAddress.getEmailChangeId())); //NOI18N - } else if (emailAddress.getEmailAddress().trim().isEmpty()) { + throw new EJBException(MessageFormat.format("Email change with id {0} does not exist.", emailChange.getEmailChangeId())); //NOI18N + } else if (emailChange.getEmailAddress().trim().isEmpty()) { // Email address is empty - throw new IllegalArgumentException("emailAddress.emaiLAddress is empty."); //NOI18N - } else if (this.isEmailAddressEnqueued(emailAddress.getEmailAddress())) { + throw new IllegalArgumentException("emailChange.emaiLAddress is empty."); //NOI18N + } else if (this.isEmailAddressEnqueued(emailChange.getEmailAddress())) { // Email address is already enqueued - throw new EJBException(MessageFormat.format("Email address {0} is already enqueued.", emailAddress.getEmailAddress())); //NOI18N + throw new EJBException(MessageFormat.format("Email address {0} is already enqueued.", emailChange.getEmailAddress())); //NOI18N } // The email change is not (yet) there, add secure hash and "created" timestamp - emailAddress.setEmailChangeCreated(new GregorianCalendar()); - this.generateSecureHash(emailAddress); + emailChange.setEmailChangeCreated(new GregorianCalendar()); + this.generateSecureHash(emailChange); - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + // Persist it + //this.getEntityManager().persist(emailChange); + + // Get mailer instance + DeliverableEmail mailer = new Mailer(); + + // Send out email change + mailer.sendEmailChangeMail(this.messageProducer, this.message, emailChange); + } + + /** + * Initialization of this bean + */ + @PostConstruct + public void init () { + try { + // Get initial context + Context context = new InitialContext(); + + // Get factory from JMS resource + QueueConnectionFactory connectionFactory = (QueueConnectionFactory) context.lookup("jms/jjobs-queue-factory"); //NOI18N + + // Lookup queue + this.queue = (Queue) context.lookup("jms/jjobs-email-queue"); //NOI18N + + // Create connection + this.connection = connectionFactory.createConnection(); + + // Init session instance + this.session = this.connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + + // And message producer + this.messageProducer = this.session.createProducer(this.queue); + + // Finally the message instance itself + this.message = this.session.createObjectMessage(); + } catch (final NamingException | JMSException e) { + // Continued to throw + throw new FacesException(e); + } } @Override -- 2.39.5