This week Oracle released it sixth patchset (11.1.1.7) of the SOA Suite and it’s IDE JDeveloper. In this new release there are some small changes in the IDE, but there are also some mayor changes like two new adapters; healthcare and the UMS (User Messaging Service). This blog will look into the use of the UMS adapter as a inbound and outbound service in a SOA Composite. This adapter was already available as beta in PS5 but now it is an official adapter.
By using the UMS (User Messaging Service) adapter as an inbound service you can initiate a instance of a SOA composite by receiving a email message on one or more configured recipients. By using the UMS adapter as an outbound service you can send email messages to one or more recipients with an optional option to send data message as an attachment.
Scroll to: Inbound UMS adapter | Custom Java CallOut | Outbound UMS adapter | Server Configuration | Testing Adapter
Let’s get into the basics
There are two parts to this adapter; one is the implementation in your SOA composite and the second one is the configuration of the USM adapter that is deployed within Weblogic. The implementation uses inbound and outbound connection factories which need to be configured in Weblogic before the SOA Composite is deployed.
Let’s say the context of this example is to register new employees, created in the CRM system, to go through the SOA Suite to provision other systems. Changes made by one of these systems need to be pushed back to the CRM system. The CRM system can only be coupled via email.
Inbound UMS adapter
First we look into the implementation within the SOA Composite using JDeveloper 11.1.1.7. For this example just create a new SOA project with an empty composite. Let’s start with the UMS adapter as an inbound service. In the composite editor drag the UMS adapter service adapter from the component palette to the exposed services swim lane.
It has almost the same steps as the File and FTP adapter. First give the new service a good name, where the name represents the message content being received by the inbound service, and click on Next. The installation of SOA Suite 11.1.1.7 comes with a default inbound connection factory eis/ums/UMSAdapterInbound, which we’re going to use, click on Next.
Because it’s an inbound service to initiate a new instance when receiving a new e-mail we choose Inbound Receive Notification as Operation Type and choose appropriate operation name (default: ReceiveNotification). Click on Next to accept values.
In the next step of the wizard we have the choice to create a polling or a listener interface. With a polling interface the interface will check every x units if there are new messages. A listener interface is similar to a JMS/AQ adapter it will react when a new message is received. Both interface have the option to operate in one single thread or more parallel threads to process the messages. It depends on the SLA which option is best, but consider that a listener interface costs more resources. Click on Next to accept the values.
Following step is assigning endpoint where the adapter will trigger on. In the current version there is only an option for email. In the endpoint configuration field it’s possible to assign one or more email addresses separated by a comma. These email addresses should be available to the Inbound connection factory assign in step 3. Click on Next to accept the values.
For processing the content of the messages the message schema need to be defined. In this step of the wizard we can select one of the following options for the input message; string type when content is text, opaque when content is base64 encoded or define a XSD schema when content is xml based string. For the last option you can use the type chooser by clicking on the looking glass icon and select the correct XSD and type to use. Click on Next to accept the values.
If you want to accept or reject messages you can add Message Filters. There are three kinds of filters; whitelist, blacklist and message filter. With the whitelist filter you can accept one or more sender addresses of which a message is processed. With the blacklist filter you can reject one or more sender addresses of which a messages isn’t processed. With de message filter you can accept or reject a message if “any” of the fields is matched with the given pattern. You can filter on data in the content of the message or match on the sender, subject or message header. For all three filters the pattern string is used for matching. This pattern is a Java RegEx expression. Click on Next to accept the values.
It also possible to use custom message filters by implementing a custom Java callout. In this step of the wizard you can enable the option en typ the name of the Java class, so for UMSCustomFilter.java it would be UMSCustomFilter. With a Java callout you can accept or reject a message via your own rules. But there are some steps to be taken first, because the Composite needs to find the given class. Instruction of creating such a class is listed below. Click on Next to accept the values.
If all steps are filled in correctly you can click on the Finish button to create the adapter.
Custom Java Callout
To use a custom Java callout to create your own message filter. We need to create a Java class which implements the interface oracle.tip.pc.services.translation.util.ICustomCallout. This interface defines a single method execute with a return value of boolean. Depending on the return value, the message is either processed or rejected. JDeveloper couldn’t find the necessary imports for this interface. Had to add jdeveloper\soa\modules\oracle\soa\fabric_11.1.1\bpm-infra.jar to the project classpath. Also when first compiling the class I got an error that it couldn’t access javax.mail classes so I added the javax.mail.jar from oracle_common\modules\javax.mail.jar.
public Inteface CustomCallout{ public boolean execute (Message message) throws exception; }
It uses the object Message which is a part of the UMS Session Description Protocol (SDP) Java API located at jdeveloper\communications\modules\oracle.sdp.messaging_11.1.1\sdpmessaging.jar. Below a example of a custom class. It checks if the sendeer is blocked for using the service.
package nl.amis.adapter.custom; import java.io.File; import oracle.sdp.messaging.Message; import oracle.tip.pc.services.translation.util.ICustomCallout; public class UMSCustomFilter implements ICustomCallout{ @Override public boolean execute(Message message) throws exception { String emailFromAddress = message.getSenders()[0].getValue(); String fileName = "/tmp/blockedusers/".concat(emailFromAddress).concat(".usr"); File file = new File(fileName); if(file.exists()) { return false; } return true; } }
After creating the Java class, bundle it with other custom classes it may use into a JAR file. Place the jar file under your Composite Application, under the SCA-INF/lib directory or place the class file directly into the SCA-INF/classes directory. A third alternative is to add the JAR file to the weblogic domain libs folder, so I can be used globally.
Outbound UMS adapter
The UMS adapter can also be used as a outbound adapter. In the composite editor drag the UMS adapter service adapter from the component palette to the external references swim lane. Just like with the inbound adapter give the service, in step 2, the appropriate name and in step 3 of the wizard type in the correct Connection Factory (default: eis/ums/UMSAdapterOutbound). Click on Next to accept the value.
In the next step choose the operation type Outbound Send Notification en give it an appropriate operation name (default: SendNotification). A outbound notification has an extra optional checkbox to receive the message ID as a reply and make it a synchronous call. Again click on Next to accept the values.
Following step is assigning values for the subject and recipients. Also there is an optional checkbox to send the message as an attachment. These email addresses must be accessible by the outbound connection factory assign in step 3. Click on Next to accept the values.
For processing the content of the messages the message schema need to be defined. Just like the inbound adapter we can select one of the following options for the input message; string type, opaque or define a XSD schema when content is xml based string. For the last option you can use the type chooser by clicking on the looking glass icon and select the correct XSD and type to use. Click on Next to accept the values.
If all steps are filled in correctly you can click on the Finish button to create the adapter. Below the structure with a example which uses an inbound adapter which polls for messages, for eacht message it calls a webservice and sends the result of this call to an outbound UMS.
Server Configuration
Before the deploying SOA composite can be deployed to the managed SOA server, we need to set-up the adapter itself. This is done on two places. First part is the configuration of the UMS adapter in the Weblogic Console and the second part is the configuration of the email driver that is used (i.g. on runtime the adapter in the SOA composite).
Let’s have a look what drives the UMS adapter integration. Under Deployments (weblogic console). Just like the DBAdapter and FTPAdapter deployments there is a UMSAdapter deplyment and also there are some usermessaging apps of which the usermessagdriver-email and usermessagingserver is used.
In de IDE the default connection pools where used. The configuration for both inbound as outbound connection pool can be found under Configuration -> Outbound Connection Pools of the UMSAdapter deployment.
The connection pools don’t hold any mail server configuration this is configured in the user messaging driver. The email driver is a part of the user messaging server. These applications can be found in the Enterprise Manager. Click on the link usermessageserver on the left side menu under User Messaging Service. This will show the application details, performance and drivers.
Click on the edit button on the right side after each driver to configure that specific driver. By default only the email driver is visible. There are more drivers packaged with weblogic, smpp and xmpp, but can’t be selected in the IDE (yet). Click on the edit button to open the configuration page of the driver. On the top op the page the main settings are displayed and include sender addresses and supported protocols. The bottom part contains a driver-specific configuration table with all settings that can be changed to have the correct values for the working environment.
The first seven settings are about the mailbox settings like the protocol to use, AutoDelete when a message is picked up, the check frequency in seconds and the folder to read the email messages from.
Scroll down for the Outgoing mail settings like the mailserver host, port, user and password.
Scroll further down for the Incoming mail settings like the mailserver host, port, user and password. But also the mail adresses to pull messages from, …
… which user and password to use for logging into these mail boxes and how much messages are processed at a time.
Testing the application
The SOA composite can now be deployed and tested. After successful deployment we send an email with xml content to the mail address where the inbound UMS adapters gets triggered on.
Simple Request / Response test
An example of a composed email message:
The message like it is received in the SOA Composite (including UMS properties):
The message send back for the SOA Composite to the Outbound UMS adapter:
The response message like it is received in an email client:
P.s. It is also possible to send attachments with message. A separate element attachtment is used for this. The element has an attribute with a reference to the file. With a forEach loop in BPEL you can loop through every element and with a simple expression you can get the content of the attachment.
ora:getAttachmentContent('InputVariable','body','/ns3:message/ns3:attachment/ns3:Attachment[$ForEachCounter]')
Fault handling
The inbound UMS Adapter uses the default rejection handling mechanism on the Inbound side of the Adapter for rejecting bad messages. For example, any translation-related errors result in message rejection. Under retriable error conditions, and when you specify retry-related endpoint properties, the Adapter tries to re-publish the Inbound message for the configured number of retries before rejecting the message.
The outbound UMS Adapter throws an exception for transient (recoverable) error conditions such as connection errors. For retriable errors, you can use a retry policy supported by the Adapter framework; to do this, you can set the binding property jca.retry.count to a retry count you want. Again, as with other Adapters, if you do not set the property, the retry is carried through according to the fault policy.
You can define non-retriable connection errors for outbound transactions through a fault policy. The maximum number of reconnection attempts can be defined through fault-policy.xml.
More on this subject you can find on the Oracle documentation page.
Hi Robert, good post ! Do you happen to know if I want to manipulate the incoming email properties such as subject (eg. need to categorize based on some words in the subject and write to DB and record the sender’s emails) how would I go about it ? Can’t access these properties as they are not shown as variable elements ready for mapping. Thank you.
You can access the jca propeties on the receive activity in BPEL.
Go to the properties tab en assign the wanted JCA property to a variable.
Example in source of BPEL:
Hi,
Can you please help me the way i can fetch the attachments from the mail through ums adapter and load it to Oracle universal content manager(UCM). Is there any ready web service for that?
I have no knowledge about webcenter content, but I do know webcenter has web services to add content.
http://docs.oracle.com/cd/E23943_01/doc.1111/e10807/c19_web_services.htm
Hi Robert, looking at how old this post it, this is probably a long shot but I am having issues reading attachments from emails. I have the following snippet in my code to get the attachment and send it as string to a web service I am calling:
ora:getAttachmentContent(‘AcceptEmailContent_ReceiveNotification_InputVariable.body/ns3:attachment’)
$InvokeMWMService_M2-MaintainUtilityActByHost_InputVariable.body/ns4:request/ns4:attachmentsGrp/ns4:attachmentsList/ns4:attachmentData
Since not all emails will have attachments, I am not sure if there is a better way to add a check. However, when I run the program, I get an error message that is not really very helpful. If you could give me any pointer as to how to go about it, I would really appreciate it.
An error occurs while processing the XPath expression; the expression is ora:getAttachmentProperty(‘Content-Type’, ‘AcceptEmailContent_ReceiveNotification_InputVariable’,’body’, ‘/ns3:attachment’).
The XPath expression failed to execute; the reason was: .
Check the detailed root cause described in the exception message text and verify that the XPath query is correct.
Hi Madhur,
Does this error also occur when you have a attachment?
If not you can add a skip rule on the assign or place a if/else clause arround it. I think it can’t determine the content type if there is no attachment.
Robert
I do have a if else skip clause. This code is only triggered when there is an attachment. It looks like it’s a product bug at this point. What version of SOA have you tried it on? I’m on 11.1.1.7.0 and it’s not working.
Hi Robert great post with lots of detail.
i’m using jdev 1.6 but i can’t find the UMS adapter. i have change the soa-config.xml removing the preview=true attribute but the adapter don’t appears. Can you help me ? THX
Hello Luis,
Did you follow the instructions posted by Edwin Biemond?
http://technology.amis.nl/2012/05/18/proces-email-with-the-new-ums-adapter-of-soa-suite-ps5/
That should do the trick.
I find out the problem. I was replacing on the soa-config.xml but i need to change the bpm-soa-config.xml file instead and add the adapter entry there, Thanks
how we can capture sender address in UMS adapter
In the message filter you can filter on sender address. And put it on a whitelist.
Any email from other sender adress will not be processed.
Hello Robert, nice writeup! How would you implement the “Inbound UMS adapter” functionality in an older 11G version that does not yet have the UMS adapter available?
Write a Java application that read the e-mail from the account en place the e-mail content in a JMS Queue or Advance Queue (Database).
Then let a SOA Composite Application poll the Queue via JMS or AQ adapter.
If you have a attachment, make a small XML message that has a base64binary element and add the content as base64 in this element or place base64 directly in a clob (advanced queue via message type). With the use of a correlationId you can make a difference between the mail body and it’s attachments.
Is this something what you were looking for?
Can you send me some screenshots of you’re EM configuration and maybe from your adapter configuration of your composite.
Do you have multiple composites that use the same USMAdapter resource eis/ums/UMSAdapterInbound?
Email: robert.van.molken@amis.nl
Hi,
I’m getting error when trying to deploy my Inbound process: Unable to create Endpoint..
“SDP-25108: One or more addresses from Access Point {0}is already registered by another application”
Maybe you know why? I’ve defined the incomming server deatails (server/port/mail/user) but still….
Thanks
Joe
Hi Joe,
No it is not possible. The adapter and the email engine (settings page) don’t have an option to copy the email that is processed to a different folder. There is only an option for auto deletion.
Maybe two solutions for this. Make an email rule that copies read email to another folder, so let the mail server do the work. And if that is not possible, write the processed email back to a outbound UMS adapter and make an email rule on the incoming e-mail.
Cheers,
Robert
Hi,
Great post.
Is it possible to move the incomming Email to another folder (under the inbox) after reading it?
Thanks
Joe
Hi,
Nice Post. I tried all the steps mentioned by you in the post to implement inbound UMS Adapter. I can see that the Messages are recieved by UMS successfully as it lists the same in the Message Latency and Statistics. But my service is not getting invoked.
Error message thrown is:Unable to complete initialization due to: Endpoint Activation Error.AdapterFrameworkImpl::endpointActivation – Endpoint Activation Error.The Resource Adapter UMS Adapter was unable to activate the endpoint oracle.tip.adapter.ums.inbound.UmsActivationSpec