Thursday, March 7, 2013

System integration via JavaMail and MDBs with Apache TomEE

Attention: This is old stuff. New build instructions here

In the previous post we moved the authentication logic from one application to another. We are trying to split tasks between applications and eventually between servers. That means that the PhotoDB application development team can concentrate their effort on how to manage pictures by leaving the user management to another group of geeks. For now, the FaceID geeks have only implemented the user management via regular database tables, but they could easily integrate other authentication methods (think LDAP, Google, Facebook etc)  in a transparent fashion.

Now imagine that our PhotoDB application should go on-line for everyone to use it. How would the PhotoDB administrator create all the users accounts? Manually creating one by one would make it the worst job in the world. Giving the potential customers free access to the FaceID application so they can add themselves as users of the system is not a good idea; The FaceID application is supposed to be used by system admins only. The usual solution is to allow the customers to create their user account from the target application itself. In our case, it would be a page like the example bellow.

Wait a minute! We have just created a whole application that is supposed to manage the users for us and now we are planing to move the user management back to the PhotoDB application? Not really. The PhotoDB application will request a new user from FaceID but in a decoupled way. The glue in between the two will be regular emails, MDBs and Message Brokers. We also don't want to delegate the email manipulation to any of our existing applications. It is time to add a new player to the team: Msglnk.

Msglnk is the central repository of all the email information of our solution. The PhotoDB and the FaceID applications don't need to keep any email configuration. They may want to send an email, but they do it by delegating the task to the Msglnk app. The app reads and sends emails with JavaMail. It communicates with the other two applications via JMS in the following way:

  • When a new email arrives, it sends a javax.jms.TextMessage through the IncomingEmailQueue javax.jms.Queue.
  • It has a MDB that listens the SendEmailQueue. Messages coming from this queue are requests from other application to send an email in their behaviour. The Msglnk formats the email and sends it through one of the pre-defined sessions. 
  • It checks for new emails every 5 minutes or when the user clicks the  "Read emails from remote server" button.

Check what the application looks like:

Out of the box, this application will not read or send any emails. You should first define the default mail session. The "Email session configuration" field has the skeleton of a JavaMail session configuration. It is designed to be used with a gmail account, but you can change it to fit your provider configurations. If you want to use a gmail account, make sure that your account has the pop access available, change the "your user here" and "your password here" strings by the real values and click "Save session configuration". Now you can click the red button in order to read your emails.

Tip: check the 2-step verification settings. You way want to use an application-specific password to improve security.

You can test your configuration with the "Send email" tab.

If "" receives the email, the configuration is correct.

Ok, let's test it. Copy and paste this code (open the link) into a terminal. It will perform the following steps:
  • create a <HOME_DIR>/posts/solution-demo directory
  • clone all the three applications under the created directory
  • download a specially created Makefile that builds all the three apps
  • execute the "start-all" target of the downloaded Makefile
In a few seconds you should see an output like this...

 7-Mar-2013 6:43:18 AM org.apache.openejb.cdi.OpenEJBLifecycle startApplication  
 INFO: OpenWebBeans Container is starting...  
 7-Mar-2013 6:43:18 AM org.apache.webbeans.plugins.PluginLoader startUp  
 INFO: Adding OpenWebBeansPlugin : [CdiPlugin]  
 7-Mar-2013 6:43:18 AM org.apache.webbeans.plugins.PluginLoader startUp  
 INFO: Adding OpenWebBeansPlugin : [OpenWebBeansJsfPlugin]  
 7-Mar-2013 6:43:18 AM org.apache.openejb.cdi.BeansDeployer validateInjectionPoints  
 INFO: All injection points are validated successfully.  
 7-Mar-2013 6:43:18 AM org.apache.openejb.cdi.OpenEJBLifecycle startApplication  
 INFO: OpenWebBeans Container has started, it took 2 ms.  
 7-Mar-2013 6:43:18 AM org.apache.openejb.assembler.classic.Assembler createApplication  
 INFO: Deployed Application(path=/home/tveronezi/TOMEE/tomee-runtime/webapps/docs)  
 7-Mar-2013 6:43:18 AM org.apache.coyote.AbstractProtocol start  
 INFO: Starting ProtocolHandler ["http-bio-8080"]  
 7-Mar-2013 6:43:18 AM org.apache.coyote.AbstractProtocol start  
 INFO: Starting ProtocolHandler ["ajp-bio-8009"]  
 7-Mar-2013 6:43:18 AM org.apache.catalina.startup.Catalina start  
 INFO: Server startup in 4648 ms  

Windows users should check the Makefile source code and manually do what it does.

Now you should have all the three applications up and running. Go to http://localhost:8080/msglnk/ and set up the default email session with a gmail account. Go to http://localhost:8080/photodb/, inform a valid email address, set a password and click the "Create new user" button. You should see a page like this...

Go to http://localhost:8080/faceid/ and check if your user is already there. Check if you can login with this new user.

When you hit the "Ok" button, you should see this in the log...

Now check your email box. You should have a new email waiting for you.

Reply this email and wait up to 5 minutes to get your account activated, or go to http://localhost:8080/msglnk/ to and click the "Read emails from remote server" button to manually trigger the email reader.

Once your user is activated, try to login again.

Side note

The Msglnk GUI is implemented with YUI 3. Go check the code to see how to use this JS framework. We have now three different ways to implement JS applications:

Did you notice that the last thing we need to worry about is TomEE? :O)
Give it a try and have fun with Apache TomEE!