From bbb498cd697097c3f4d717888ebb3275637ed362 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Roland=20H=C3=A4der?= Date: Tue, 17 May 2016 15:35:48 +0200 Subject: [PATCH] Continued: - added message-driven bean for mail delivery (generic) - added method init() method to initialize queue/factory - implemented business method resendConfirmationLink() (unfinished) - the business method enqueueEmailAddressForChange() now uses JMS and not directly calling the mailer MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Roland Häder --- nbproject/project.properties | 1 + .../resendlink/JobsResendLinkSessionBean.java | 108 ++++++++++++++++++ .../JobsEmailDeliveryMessageBean.java | 73 +++++------- .../JobsEmailChangeSessionBean.java | 79 ++++++++++--- 4 files changed, 201 insertions(+), 60 deletions(-) diff --git a/nbproject/project.properties b/nbproject/project.properties index 4d4ca38..8df765f 100644 --- a/nbproject/project.properties +++ b/nbproject/project.properties @@ -103,6 +103,7 @@ project.jjobs-lib=../jjobs-lib project.jjobs-mailer=../jjobs-mailer project.juser-core=../juser-core project.license=agpl30 +project.serviceLocator.class=org.mxchange.jjobs.mailer.model.delivery.JobsMailer reference.jjobs-lib.jar=${project.jjobs-lib}/dist/jjobs-lib.jar reference.jjobs-mailer.jar=${project.jjobs-mailer}/dist/jjobs-mailer.jar resource.dir=setup diff --git a/src/java/org/mxchange/jjobs/beans/resendlink/JobsResendLinkSessionBean.java b/src/java/org/mxchange/jjobs/beans/resendlink/JobsResendLinkSessionBean.java index d2c170b..cd10a18 100644 --- a/src/java/org/mxchange/jjobs/beans/resendlink/JobsResendLinkSessionBean.java +++ b/src/java/org/mxchange/jjobs/beans/resendlink/JobsResendLinkSessionBean.java @@ -16,8 +16,25 @@ */ package org.mxchange.jjobs.beans.resendlink; +import de.chotime.landingpage.beans.resendlink.ResendLinkSessionBeanRemote; +import java.text.MessageFormat; +import java.util.Locale; +import javax.annotation.PostConstruct; 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 org.mxchange.jjobs.database.BaseJobsDatabaseBean; +import org.mxchange.jusercore.model.user.User; +import org.mxchange.jusercore.model.user.status.UserAccountStatus; /** * A session-based EJB for resending confirmation links @@ -32,4 +49,95 @@ public class JobsResendLinkSessionBean extends BaseJobsDatabaseBean implements R */ private static final long serialVersionUID = 71_546_726_857_195_360L; + /** + * 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; + + /** + * Initialization of this bean + */ + @PostConstruct + public void init () { + // Trace message + this.getLoggerBeanLocal().logTrace("init: CALLED!"); //NOI18N + + try { + // Get initial context + Context context = new InitialContext(); + + // Get factory from JMS resource + QueueConnectionFactory connectionFactory = (QueueConnectionFactory) context.lookup("jms/jlandingpage-queue-factory"); //NOI18N + + // Lookup queue + this.queue = (Queue) context.lookup("jms/jlandingpage-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 + public String resendConfirmationLink (final User user, final Locale locale) { + // Log trace message + this.getLoggerBeanLocal().logTrace(MessageFormat.format("resendConfirmationLink: user={0} - CALLED!", user)); //NOI18N + + // The user instance should be valid + if (null == user) { + // Throw NPE + throw new NullPointerException("user is null"); //NOI18N + } else if (user.getUserId() == null) { + // Throw NPE again + throw new NullPointerException("user.userId is null"); //NOI18N + } else if (user.getUserId() < 1) { + // Invalid id number + throw new IllegalArgumentException(MessageFormat.format("user.userId={0} is not valid", user.getUserId())); //NOI18N + } else if (user.getUserConfirmKey() == null) { + // Throw NPE again + throw new NullPointerException("this.userConfirmKey is null"); //NOI18N + } else if (user.getUserAccountStatus() != UserAccountStatus.UNCONFIRMED) { + // User account status is not UNCONFIRMED + throw new IllegalStateException(MessageFormat.format("Account status from user.userId={0} is not UNCONFIRMED:{1}", user.getUserId(), user.getUserAccountStatus())); //NOI18N + } else if (null == locale) { + // Locale should be set + throw new NullPointerException("locale is null"); //NOI18N + } + + // @TODO Unfinished! + // All fine + return "resend_done"; //NOI18N + } + } diff --git a/src/java/org/mxchange/jmailee/model/delivery/JobsEmailDeliveryMessageBean.java b/src/java/org/mxchange/jmailee/model/delivery/JobsEmailDeliveryMessageBean.java index 57380fe..a6313c0 100644 --- a/src/java/org/mxchange/jmailee/model/delivery/JobsEmailDeliveryMessageBean.java +++ b/src/java/org/mxchange/jmailee/model/delivery/JobsEmailDeliveryMessageBean.java @@ -24,11 +24,9 @@ import javax.jms.JMSException; import javax.jms.Message; import javax.jms.MessageListener; import javax.jms.ObjectMessage; -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; +import org.mxchange.jjobs.database.BaseJobsDatabaseBean; +import org.mxchange.jjobsmailer.model.delivery.DeliverableJobsEmail; +import org.mxchange.jjobsmailer.model.delivery.JobsMailer; /** * A message queue for sending out emails @@ -42,78 +40,59 @@ import org.mxchange.jcoreeelogger.beans.local.logger.LoggerBeanLocal; @ActivationConfigProperty (propertyName = "destinationLookup", propertyValue = "jms/jjobs-email-queue"), @ActivationConfigProperty (propertyName = "destinationType", propertyValue = "javax.jms.Queue") }) -public class JobsEmailDeliveryMessageBean implements MessageListener { +public class JobsEmailDeliveryMessageBean extends BaseJobsDatabaseBean implements MessageListener { /** - * Logger bean + * Serial number */ - @Log - private LoggerBeanLocal loggerBeanLocal; + private static final long serialVersionUID = 75_638_176_619_024L; + + /** + * Mailer instance + */ + private final DeliverableJobsEmail mailer; /** * 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(MessageFormat.format("context.lookup() failed: {0}", ex.getMessage()), ex); //NOI18N - } + // Init mailer instance + this.mailer = new JobsMailer(); } @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? + this.getLoggerBeanLocal().logTrace(MessageFormat.format("onMessage: message={0} - CALLED!", message)); //NOI18N + // The parameter should be valid if (null == message) { - // message is null + // Throw NPE 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 + // Not implementing right interface + throw new IllegalArgumentException(MessageFormat.format("message={0} does not implemented ObjectMessage", message)); //NOI18N } // Securely cast it ObjectMessage objectMessage = (ObjectMessage) message; - // Init instance - Serializable object; + // Init variable + Serializable serializable; try { - // Get object from it - object = objectMessage.getObject(); + // Get object from message + serializable = objectMessage.getObject(); } catch (final JMSException ex) { - // Log exception ... - this.loggerBeanLocal.logException(ex); - - // ... and don't continue + // Log it and don't continue any further + this.getLoggerBeanLocal().logException(ex); 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; + this.getLoggerBeanLocal().logDebug(MessageFormat.format("onMessage: serializable={0}", serializable)); //NOI18N // Trace message - this.loggerBeanLocal.logTrace("onMessage: EXIT!"); //NOI18N + this.getLoggerBeanLocal().logTrace("onMessage - EXIT!"); //NOI18N } } 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 757b762..de9c2ca 100644 --- a/src/java/org/mxchange/jusercore/model/email_address/JobsEmailChangeSessionBean.java +++ b/src/java/org/mxchange/jusercore/model/email_address/JobsEmailChangeSessionBean.java @@ -19,6 +19,8 @@ package org.mxchange.jusercore.model.email_address; import java.text.MessageFormat; import java.util.GregorianCalendar; import java.util.List; +import java.util.Locale; +import java.util.Properties; import javax.annotation.PostConstruct; import javax.ejb.EJB; import javax.ejb.EJBException; @@ -31,14 +33,17 @@ import javax.jms.ObjectMessage; import javax.jms.Queue; import javax.jms.QueueConnectionFactory; import javax.jms.Session; +import javax.mail.Address; +import javax.mail.internet.AddressException; +import javax.mail.internet.InternetAddress; import javax.naming.Context; import javax.naming.InitialContext; import javax.naming.NamingException; import javax.persistence.NoResultException; import javax.persistence.Query; import org.mxchange.jjobs.database.BaseJobsDatabaseBean; -import org.mxchange.jjobsmailer.model.delivery.DeliverableJobsEmail; -import org.mxchange.jjobsmailer.model.delivery.JobsMailer; +import org.mxchange.jmailee.model.delivery.wrapper.EmailDeliveryWrapper; +import org.mxchange.jmailee.model.delivery.wrapper.WrapableEmailDelivery; import org.mxchange.jusercore.model.user.UserSessionBeanRemote; import org.mxchange.jusercore.model.user.UserUtils; @@ -147,11 +152,41 @@ public class JobsEmailChangeSessionBean extends BaseJobsDatabaseBean implements // Persist it //this.getEntityManager().persist(emailChange); - // Get mailer instance - DeliverableJobsEmail mailer = new JobsMailer(); + // Prepare mail wrapper + WrapableEmailDelivery emailWrapper = new EmailDeliveryWrapper(); - // Send out email change - mailer.sendEmailChangeMail(this.messageProducer, this.message, emailChange); + try { + // Create email address and set + Address emailAddress = new InternetAddress(emailChange.getEmailAddress()); + emailWrapper.setRecipient(emailAddress); + } catch (final AddressException ex) { + // Throw again + throw new EJBException(ex); + } + + // Set all values + Properties variables = UserUtils.getAllUserFields(emailChange.getEmailChangeUser()); + + // Set all + // @TODO Get locale from user + language from message bundle + emailWrapper.setLocale(Locale.GERMAN); + emailWrapper.setSubjectLine("Email change"); + emailWrapper.setTemplateName("email_change"); //NOI18N + emailWrapper.setTemplateVariables(variables); + + try { + // Send out email change + this.message.setObject(emailWrapper); + + // Send message + this.sendMessage(this.message); + } catch (final JMSException ex) { + // Throw again + throw new EJBException(ex); + } + + // Trace message + this.getLoggerBeanLocal().logTrace("enqueueEmailAddressForChange - EXIT!"); //NOI18N } /** @@ -159,15 +194,18 @@ public class JobsEmailChangeSessionBean extends BaseJobsDatabaseBean implements */ @PostConstruct public void init () { + // Trace message + this.getLoggerBeanLocal().logTrace("init: CALLED!"); //NOI18N + try { // Get initial context Context context = new InitialContext(); // Get factory from JMS resource - QueueConnectionFactory connectionFactory = (QueueConnectionFactory) context.lookup("jms/jjobs-queue-factory"); //NOI18N + QueueConnectionFactory connectionFactory = (QueueConnectionFactory) context.lookup("jms/jlandingpage-queue-factory"); //NOI18N // Lookup queue - this.queue = (Queue) context.lookup("jms/jjobs-email-queue"); //NOI18N + this.queue = (Queue) context.lookup("jms/jlandingpage-email-queue"); //NOI18N // Create connection this.connection = connectionFactory.createConnection(); @@ -208,8 +246,8 @@ public class JobsEmailChangeSessionBean extends BaseJobsDatabaseBean implements // Found it isFound = true; } catch (final NoResultException ex) { - // Ignore it for now - //this.getLoggerBeanLocal().logException(ex); + // Log it + this.getLoggerBeanLocal().logException(ex); } // Trace message @@ -286,9 +324,6 @@ public class JobsEmailChangeSessionBean extends BaseJobsDatabaseBean implements // Get single result ChangeableEmailAddress dummy = (ChangeableEmailAddress) query.getSingleResult(); } catch (final NoResultException ex) { - // Ignore it for now - //this.getLoggerBeanLocal().logException(ex); - // Not found isUsed = false; } @@ -302,4 +337,22 @@ public class JobsEmailChangeSessionBean extends BaseJobsDatabaseBean implements emailAddress.setEmailChangeHash(hash); } + /** + * Sends given message to configured queue + *

+ * @param message Message to send + *

+ * @throws JMSException if something went wrong + */ + private void sendMessage (final ObjectMessage message) throws JMSException { + // The parameter should be valid + if (null == message) { + // Throw NPE + throw new NullPointerException("message is null"); //NOI18N + } + + // Send it + this.messageProducer.send(message); + } + } -- 2.39.5