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

When implementing a Singleton service as a standalone application, it has to be bundled as a JAR-File and must be placed under /lib folder. Dependend third-party libs not provided by Weblogic must be also available within this folder, with a reference in the Singleton JARs manifest. Afterwards the servers has to be restarted and the Singleton service has to be registered in the Cluster using Weblogic Console.

 

SingletonStandaloneConfig

 

Part of an enterprise application

When implementing a Singleton service as part of an enterprise application, it has to be packaged inside an EAR-File which has to be deployed to the cluster. The registration of the Singleton to the Cluster is done by adding an entry to weblogic-application.xml.

[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]

Finally let’s have a short look on the implementation of the Singleton service:

[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:

Alle Beiträge von Sven Bernhardt

Sven Bernhardt is a technology enthusiast who works for OPITZ CONSULTING as the Chief Architect on the Corporate Development team. In this role, he manages the technology portfolio and develops Best Practices and Guidelines. In addition, Sven supports his colleagues in implementing Software solutions for Customers. Sven regularly speaks at various conferences about technology or architecture topics. He also shares his thoughts and experiences by writing articles and blog posts. In addition, he's a Kong Champion.

Schreibe einen Kommentar