In an integration project we are currently replacing an available integration platform using Oracle Service Bus 11g. Different incoming and outgoing message formats and protocols (HTTP, FTP, SMTP, etc.) are used from the external partners of our customer and therefore have to be supported. With OSB no problem at all, but polling a MS Exchange server for new e-mails is simply not possible with OSB standard tooling. Debt is a bug in MS Exchange server, which advertises that it supports plain authentification for login, but it does not ([1], search for AUTH=PLAIN). So when trying to access an exchange inbox from a proxy service ends up with failures, which cannot be worked around.
So we decided to implement a custom Java service that does the polling, because with plain Java the bug can be worked around by setting the corresponding Java Mail session parameters described in [1]. The challenge from a implementation perspective is that in a clustered environment, a service is in general active on all cluster nodes and so parallel access and therefore multi processing for one specific e-mail is possible. So the service has to be implemented as a Weblogic Singleton service [2] to avoid this. A Singleton service is physically deployed to the cluster and so available on all nodes, but it is only active on one specific cluster node. In case of problems on the node where the service is active, it might be activated on another node in the cluster automatically, depending on the failover configuration in the cluster.
Basically Singleton services may be implemented in two different fashions:
Standalone application
Part of an enterprise application
[code wraplines=“false“ collapse=“true“ language=“xml“]
com.opitzconsulting.mail.MailClientRunner
mail-client
[/code]
Deploying a singleton service as part of an enterprise application is the more flexible alternative and less invasive way regarding changes in the singleton implementation, because a simple redeployment of the application is sufficient. Using the standalone variant, a server restart is needed in case of changes in the Singletons implementation logic. In our concrete scenario we decided to implement the Mail Singleton service as part of an enterprise application.
After deploying the Singleton application to the cluster it will be activated on one of the cluster nodes and starts polling the specified email account. When stopping the server, where the Singleton service is currently active on, it will be deactivated on this node and directly be activated on another node. Observing the server logs shows this behaviour because of corresponding log outputs in the Singleton implementations activate() and deactivate() methods.
[code wraplines=“false“ collapse=“true“ language=“text“]
osb_server1.out
23:20:04.341 [[ACTIVE] ExecuteThread: ‚0‘ for queue: ‚weblogic.kernel.Default (self-tuning)‘] INFO MailClientRunner – SingletonService MailClientRunner is initiated…
23:20:05.461 [[ACTIVE] ExecuteThread: ‚5‘ for queue: ‚weblogic.kernel.Default (self-tuning)‘] INFO MailClientRunner – SingletonService MailClientRunner is activated…
23:20:06.736 [[ACTIVE] ExecuteThread: ‚5‘ for queue: ‚weblogic.kernel.Default (self-tuning)‘] INFO MailReaderClient – FROM: [„Bernhardt, Sven“ <Sven.Bernhardt@opitz-consulting.com>]
23:20:06.736 [[ACTIVE] ExecuteThread: ‚5‘ for queue: ‚weblogic.kernel.Default (self-tuning)‘] INFO MailReaderClient – SENT DATE: [Sat Jul 12 23:15:03 CEST 2014]
23:20:06.736 [[ACTIVE] ExecuteThread: ‚5‘ for queue: ‚weblogic.kernel.Default (self-tuning)‘] INFO MailReaderClient – SUBJECT: [Singleton Service Testmail]
23:20:07.001 [[ACTIVE] ExecuteThread: ‚5‘ for queue: ‚weblogic.kernel.Default (self-tuning)‘] INFO MailReaderClient – CONTENT: [Hello,
this is a test mail.
BR,
Sven
]
23:21:16.131 [[ACTIVE] ExecuteThread: ‚0‘ for queue: ‚weblogic.kernel.Default (self-tuning)‘] INFO MailClientRunner – SingletonService MailClientRunner has been deactivated…
[/code]
[code wraplines=“false“ collapse=“true“ language=“text“]
osb_server2.out
23:21:22.967 [[STANDBY] ExecuteThread: ‚1‘ for queue: ‚weblogic.kernel.Default (self-tuning)‘] INFO MailClientRunner – SingletonService MailClientRunner is activated…
23:21:24.220 [[STANDBY] ExecuteThread: ‚1‘ for queue: ‚weblogic.kernel.Default (self-tuning)‘] INFO MailReaderClient – FROM: [„Bernhardt, Sven“ <Sven.Bernhardt@opitz-consulting.com>]
23:21:24.220 [[STANDBY] ExecuteThread: ‚1‘ for queue: ‚weblogic.kernel.Default (self-tuning)‘] INFO MailReaderClient – SENT DATE: [Sat Jul 12 23:15:03 CEST 2014]
23:21:24.220 [[STANDBY] ExecuteThread: ‚1‘ for queue: ‚weblogic.kernel.Default (self-tuning)‘] INFO MailReaderClient – SUBJECT: [Singleton Service Testmail]
23:21:24.481 [[STANDBY] ExecuteThread: ‚1‘ for queue: ‚weblogic.kernel.Default (self-tuning)‘] INFO MailReaderClient – CONTENT: [Hello,
this is a test mail.
BR,
Sven
]
[/code]
[code wraplines=“false“ collapse=“true“ language=“java“]
package com.opitzconsulting.mail;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import weblogic.cluster.singleton.SingletonService;
public class MailClientRunner implements SingletonService {
private static final Logger log = LoggerFactory.getLogger(MailClientRunner.class.getSimpleName());
private MailReaderClient mailReaderClient;
public MailClientRunner() {
log.info(String.format(„SingletonService MailClientRunner is initiated…“));
}
@Override
public void activate() {
log.info(String.format(„SingletonService MailClientRunner is activated…“));
mailReaderClient = new MailReaderClient();
mailReaderClient.readMail();
}
@Override
public void deactivate() {
log.info(String.format(„SingletonService MailClientRunner has been deactivated…“));
}
}
[/code]
The interaction between Oracle Service Bus and the Singleton Mail service has been implemented using JMS Queues. The Mail service reads the mails, coverts the content (CSV, XML) from the mail body or from attachments, creates a uniform message format which is independent from protocol as well as format and enqueues it into the corresponding queues. From here OSB dequeues the messages and does the further processing. The logic from this point on is the same, used for other interfaces. With this implementation approach, by combining the strenghts of of JEE and OSB, we created a flexible, maintainable and standard-based way to integrate inbound email processing in our final integration architecture.
Links:
1 Kommentar
Pingback: You’ve Got Mail: Inbound Email Processing in WLS/OSB integration scenarios by The Cattle Crew | SOA Community Blog