In Patch Set 2 of Soa Suite 11g Oracle added a simple java API for UMS and in this blogpost I will use this API in a EJB Session Bean with a Remote Interface and also expose this Session Bean as a Web Service. This Session Bean & Web Service can be used in your custom applications so you don't need to have or build your own messaging methods because Soa Suite can do more and much better and even keeps track of your messages. Just call the Web Service or the Session Bean, deliver a list of Receivers with names and the media delivery type and it will return a MessageId with this you can check the status of your send messages.
In this blogpost I will use the email and instant messaging driver to deliver my messages. And as a demo I can send email attachements, deliver a message to IM and Email Client. ( Multi part Message , plain text part for IM and HTML part for Email ) and at last get retrieve the status of these messages. And you can use this in SoapUI, a web service proxy or in a EJB java client.
First you need to enable and configure the UMS Email and Instant Messaging Driver ( XMPP).
Go to the Weblogic console of your Soa Domain probably http://xxxxx:7001/console and select the XMPP UMS driver and go the the target tab and enable the Soa servers or soa cluster.
You need to reboot the Soa Server managed Servers.
In the User Messaging Service part of the Enterprise Manager Website http://xxxx:7001/em you can select the xmpp driver and go the XMPP Driver Properties.
In my case I will use Google Talk as IM service. Provide the server and a Talk user account.
Do the Same for your UMS Email driver. Provide the SMTP server.
And enable all the Work Flow communications in the WorkFlow Notifications Properties page of the Soa Infrastructure part..
You need to reboot the Soa Server managed Servers.
Now you can go to the developer part and create a JDeveloper project and add an new Application. Your project needs to have the UMS library located at jdeveloper\communications\modules\oracle.sdp.messaging_11.1.1\sdpmessaging.jar and your application also needs to have a reference to the oracle.sdp.messaging shared library. Do this in the weblogic-application.xml.
This EJB / WS needs to deployed on the Soa Suite Managed Servers.
To make things more simple I made two entities Receiver and Status.
The Receiver just needs an email address and type ( EMAIL or IM )
package nl.whitehorses.soa.ums.entities; import java.io.Serializable; public class Receiver implements Serializable{ public Receiver() { } private String receiver; private String channel; public Receiver(String receiver, String channel) { super(); this.receiver = receiver; this.channel = channel; } public void setReceiver(String receiver) { this.receiver = receiver; } public String getReceiver() { return receiver; } public void setChannel(String channel) { this.channel = channel; } public String getChannel() { return channel; } }The Status entity gives some simple info about the send messages.
package nl.whitehorses.soa.ums.entities; import java.io.Serializable; import java.util.Date; public class Status implements Serializable { public Status() { } private String messageId; private Date sendTime; private String receiver; private String status; public Status(String messageId, Date sendTime, String receiver, String status) { super(); this.messageId = messageId; this.sendTime = sendTime; this.receiver = receiver; this.status = status; } public void setMessageId(String messageId) { this.messageId = messageId; } public String getMessageId() { return messageId; } public void setSendTime(Date sendTime) { this.sendTime = sendTime; } public Date getSendTime() { return sendTime; } public void setReceiver(String receiver) { this.receiver = receiver; } public String getReceiver() { return receiver; } public void setStatus(String status) { this.status = status; } public String getStatus() { return status; } public String toString() { return "message id: "+ messageId+" time: "+sendTime.toString()+ " status: " +status + " receiver: " + receiver; } }Here the main code with three method sendMailAttachmentMsg, sendMixedMsg and getMessageStatus.
The sendMailAttachmentMsg method will only send Mail with Attachments and sendMixedMsg method can send messages to Google Talk and Email, it depends on the receivers and getMessageStatus returns the Statusses of the send messages.
package nl.whitehorses.soa.ums.services; import javax.ejb.Remote; import javax.ejb.Stateless; import java.util.HashMap; import java.util.Map; import java.util.ArrayList; import java.util.List; import javax.activation.DataHandler; import javax.jws.WebMethod; import javax.jws.WebParam; import javax.jws.WebResult; import javax.jws.WebService; import javax.mail.internet.MimeBodyPart; import javax.mail.internet.MimeMultipart; import nl.whitehorses.soa.ums.entities.Receiver; import nl.whitehorses.soa.ums.utilities.ReceiverConvertor; import oracle.sdp.messaging.Address; import oracle.sdp.messaging.ApplicationInfo; import oracle.sdp.messaging.DeliveryType; import oracle.sdp.messaging.Message; import oracle.sdp.messaging.MessagingFactory; import oracle.sdp.messaging.MessagingClient; import oracle.sdp.messaging.MessagingClientFactory; import oracle.sdp.messaging.MessagingException; import oracle.sdp.messaging.Status; import oracle.sdp.messaging.util.ByteArrayDataSource; import oracle.sdp.messaging.util.StringDataSource; @Stateless(name="SessionEJB", mappedName = "SoaUMSMessaging-SessionEJB") @Remote @WebService(name = "UMSMessagingService", serviceName = "UMSMessagingService", portName = "UMSMessagingServicePort") public class SessionEJBBean implements SessionEJB { MessagingClient mClient = null; Map<String, Object> params = new HashMap<String, Object>(); public SessionEJBBean() { params.put(ApplicationInfo.APPLICATION_NAME, "CompanyMsgr"); params.put(ApplicationInfo.APPLICATION_INSTANCE_NAME, "CompanyInstance"); } @WebMethod @WebResult(name = "messageId") public String sendMailAttachmentMsg( @WebParam(name = "sender") String sender, @WebParam(name = "receivers") List<Receiver> receivers, @WebParam(name = "subject") String subject, @WebParam(name = "message") String message, @WebParam(name = "data") byte[] data, @WebParam(name = "mimetype") String mimetype, @WebParam(name = "filename") String fileName) { MimeMultipart mp = null; try { // plain msg for the body MimeBodyPart mp_partPlain = new MimeBodyPart(); mp_partPlain.setText(message); // binary attachement MimeBodyPart mp_partBinary = new MimeBodyPart(); ByteArrayDataSource dataSource = new ByteArrayDataSource(data, mimetype); mp_partBinary.setDataHandler(new DataHandler(dataSource)); mp_partBinary.setFileName(fileName); mp = new MimeMultipart("alternative"); mp.addBodyPart(mp_partPlain); mp.addBodyPart(mp_partBinary); } catch (javax.mail.MessagingException e) { e.printStackTrace(); } try { Message soaMessage = MessagingFactory.createMessage(); Address soaSender = MessagingFactory.buildAddress(sender, DeliveryType.EMAIL, null); soaMessage.setSubject(subject); soaMessage.setContent(mp, "multipart/alternative"); soaMessage.addSender(soaSender); soaMessage.addAllRecipients(ReceiverConvertor.convertReceiver(receivers)); mClient = MessagingClientFactory.createMessagingClient(params); String messageId = mClient.send(soaMessage); return messageId; } catch (MessagingException e) { e.printStackTrace(); } return null; } @WebMethod @WebResult(name = "statusses") public List<nl.whitehorses.soa.ums.entities.Status> getMessageStatus( @WebParam(name = "messageId") String messageId) { try { mClient = MessagingClientFactory.createMessagingClient(params); Status[] msgStatuses = mClient.getStatus(messageId); List<nl.whitehorses.soa.ums.entities.Status> statusses = new ArrayList<nl.whitehorses.soa.ums.entities.Status>(); for (Status msgStatus : msgStatuses) { nl.whitehorses.soa.ums.entities.Status status = new nl.whitehorses.soa.ums.entities.Status(); status.setMessageId(msgStatus.getMessageId()); status.setReceiver(msgStatus.getAddress().toString()); status.setStatus(msgStatus.getType().toString()); status.setSendTime(msgStatus.getDate().getTime()); statusses.add(status); } return statusses; } catch (MessagingException e) { e.printStackTrace(); } return null; } @WebMethod @WebResult(name = "messageId") public String sendMixedMsg(@WebParam(name = "subject") String subject, @WebParam(name = "message") String message, @WebParam(name = "sender") String sender, @WebParam(name = "receivers") List<Receiver> receivers) { Message soaMessage = MessagingFactory.createMessage(); MimeMultipart part_mp = null; try { // IM Message MimeBodyPart part_mp_partPlain = new MimeBodyPart(); // set IM part_mp_partPlain.addHeader(soaMessage.HEADER_SDPM_PAYLOAD_PART_DELIVERY_TYPE, "IM"); part_mp_partPlain.setText(message); // Email Message MimeBodyPart part_mp_partRich = new MimeBodyPart(); // set Email part_mp_partRich.addHeader(soaMessage.HEADER_SDPM_PAYLOAD_PART_DELIVERY_TYPE, "EMAIL"); StringDataSource htmlDataSource = new StringDataSource("<html><head></head><body><b><i>"+ message+ "</i></b></body></html>", "text/html; charset=UTF-8"); part_mp_partRich.setDataHandler(new DataHandler(htmlDataSource)); part_mp = new MimeMultipart("alternative"); part_mp.addBodyPart(part_mp_partPlain); part_mp.addBodyPart(part_mp_partRich); } catch (javax.mail.MessagingException b) { b.printStackTrace(); } try { mClient = MessagingClientFactory.createMessagingClient(params); soaMessage.setSubject(subject); soaMessage.setContent(part_mp, "multipart/alternative"); // Enabled for IM and Email soaMessage.setMultiplePayload(true); Address soaSender = MessagingFactory.buildAddress(sender, DeliveryType.EMAIL, null); soaMessage.addSender(soaSender); soaMessage.addAllRecipients(ReceiverConvertor.convertReceiver(receivers)); String messageId = mClient.send(soaMessage); return messageId; } catch (oracle.sdp.messaging.MessagingException b) { b.printStackTrace(); } return null; } }
My EJB test client
package nl.whitehorses.soa.ums; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; import java.util.ArrayList; import java.util.Hashtable; import java.util.List; import javax.naming.Context; import javax.naming.InitialContext; import javax.naming.NamingException; import nl.whitehorses.soa.ums.entities.Receiver; import nl.whitehorses.soa.ums.entities.Status; import nl.whitehorses.soa.ums.services.SessionEJB; public class SessionEJBClient { public static void main(String[] args) { try { final Context context = getInitialContext(); SessionEJB sessionEJB = (SessionEJB)context.lookup("SoaUMSMessaging-SessionEJB#nl.whitehorses.soa.ums.services.SessionEJB"); List<Receiver> receivers = new ArrayList<Receiver>(); Receiver receiver = new Receiver("xxx@gmail.com", "EMAIL"); Receiver receiver2 = new Receiver("xxxx@tiscali.nl", "EMAIL"); receivers.add(receiver); receivers.add(receiver2); String messageId = sessionEJB.sendMailAttachmentMsg( "xxxx@xs4all.nl", receivers, "hello subject", "hello body" ,doDownload("C:/temp/logo.png"), "image/png", "logo.png"); System.out.println("MessageId is " + messageId + " lets wait 2 seconds for the status"); Thread.sleep(2000); if (messageId != null) { List<Status> statusses = sessionEJB.getMessageStatus(messageId); for (Status status : statusses) { System.out.println(status.toString()); } } Receiver receiver3 = new Receiver("nl2en@bot.talk.google.com", "IM"); receivers.add(receiver3); messageId = sessionEJB.sendMixedMsg("Hello", "Hello world", "xxxx@xs4all.nl", receivers ); System.out.println("MessageId is " + messageId + " lets wait for the status"); Thread.sleep(4000); if (messageId != null) { List<Status> statusses = sessionEJB.getMessageStatus(messageId); for (Status status : statusses) { System.out.println(status.toString()); } } } catch (Exception ex) { ex.printStackTrace(); } } private static Context getInitialContext() throws NamingException { Hashtable env = new Hashtable(); env.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory"); env.put(Context.PROVIDER_URL, "t3://localhost:8001"); return new InitialContext(env); } public static byte[] doDownload(String fileName) { FileInputStream fis; byte[] data = null; FileChannel fc; try { fis = new FileInputStream(fileName); fc = fis.getChannel(); data = new byte[(int)(fc.size())]; ByteBuffer bb = ByteBuffer.wrap(data); fc.read(bb); } catch (FileNotFoundException e) { // TODO } catch (IOException e) { // TODO } return data; } }If you send messages with this EJB Session or WS then you can take a look at the application client in the UMS service overview.
Here you can download my example workspace.
Hi Edwin,
ReplyDeleteThanks for this wonderful post, it helped me a lot. I am trying to have this EJB deployed in a remote server and connect to some other UMS server, isn't this possible? I tried by setting the params.put(ApplicationInfo.SDPM_SERVER_JNDI_PROVIDER_URL, "t3://:7001"); in the SessionEJBBean.java file in the Messaging project, but this didn't work. Can you please throw some light here?
Thanks,
Sudan
Ok,
ReplyDeletecan you check if the port 8001 is the right one, it runs on the soa server.
can you try from a java class with a main , if that works, it should also work on a remote server.
thanks
Hi Edwin,
ReplyDeleteThanks for the response. My exact problem is when I run the below code
sendConfig.put(ApplicationInfo.APPLICATION_NAME, "app1");
sendConfig.put(ApplicationInfo.APPLICATION_INSTANCE_NAME,"appInstance1");
sendConfig.put(ApplicationInfo.SDPM_SERVER_JNDI_PROVIDER_URL, "t3://xyz.com:7001");
MessagingClientFactory.createMessagingClient(sendConfig);
and running this in a UMS server, say abc.com and trying to connect to the UMS server xyz.com running at 7001. It always sends message through the abc.com ums server only..How can I make it to use the xyz.com UMS server..Is my setting for JNDI_PROVIDER_URL is wrong?
Thanks,
Sudan
Hi,
ReplyDeleteI think everything works on the SOA server so use that port. 7001 is the adminserver , and this is only the case when you do a developer SOA install.
It's probably 8001
And I think you don't need to set this property here . You need to do this in the enterprise manager web app. And off course enable everything about humantasks in the em
Thanks Edwin
Hi Edwin,
ReplyDeleteThanks for the nice article. I have a simple java class to send a message using UMS java API.
public String sendNotification(String senderId, String recipientId, String subject, String msg, String channel ){
ApplicationInfo appInfo = new ApplicationInfo();
appInfo.setApplicationName("ServiceApp");
appInfo.setApplicationInstanceName("ServiceAppInstance");
appInfo.setJNDIInitialFactory("weblogic.jndi.WLInitialContextFactory");
appInfo.setSecurityPrincipal("weblogic");
appInfo.setSecurityCredentials("weblogic1");
appInfo.setServerJNDIProviderURL("t3://abc.com:7012");
mClient = MessagingClientFactory.createMessagingEJBClient(appInfo);
String messageId = mClient.send(message);
}
abc.com:7012 is where the soa_server is running.
when I invoke the above method from the main() it throws,
oracle.sdp.messaging.MessagingException: Error occured while creating the Messaging Client instance: : null
Cause: Need to specify class name in environment or system property, or as an applet parameter, or in an application resource file: java.naming.factory.initial
at oracle.sdpinternal.messaging.MessagingClientFactoryInternal.createMessagingEJBClient(MessagingClientFactoryInternal.java:219)
at oracle.sdp.messaging.MessagingClientFactory.createMessagingEJBClient(MessagingClientFactory.java:115)
I configured everything as per ur post.
Can you please throw some light here?
Hi Edwin,
ReplyDeleteIs it possible to use the UMS Java API in a plain Java Class instead of EJB session bean to send the messages?
Also, Is it possible to register(through Messaging Client API) the java class with the SOA/ UMS server without deploying it?
thanks,
Nag
Hi,
ReplyDeleteDon't know if you can do it from a java client. I think I got some security exceptions or it is not supported
mClient = MessagingClientFactory.createMessagingClient(params);
So I deployed it to the soa server and invoke my web service.
thanks
Dear Edwin,
ReplyDeleteI have a requirement of sending Fax from SOA. But couldnot get anything regardimg the same. Is it possible for you to help me with this.
Thanks in advance.
Regards
Vaibhav
Hi,
DeleteI know some products who are integrated in the email server , so you can send it like a email.
but do you want to build it yourself.
thanks
Hi Edwin,
ReplyDeleteThanks for ur response. Posting a new comment as I was not able to reply to ur comment.
Well I am thinking of building it myself. Can you suggest how can I start with it.
However if there are products who are already integrated I would like to know them too.
I have to send sms also.. for that I am trying to use SMPP. Did all some config on server but still have to find SMS Server. Can you help me wth that too???
I have a question, why is it that NotificationService.wsdl already has FaxNotificationMessagetype if it is not supported.
************************************************
************************************************
Thanks.
Vaibhav
Sorry you have to do it yourself,
DeleteFax is old technology and there many applications which you can buy and does it really well and you got support. Else it will take months with lot of bugs, not worth it doing it yourself.
and look for a commercial sms server, there is no free one, you need to buy a package bundle of 10.000 text messages.
thanks
In Patch Set 2 of Soa Suite 11g Oracle added a simple java API for UMS. Can UMS be exposed as is as a web service? Do we really need to write an EJB session bean with remote interface and then expose it? It just looks like something that should have already be done by Oracle rather than having every body develop their own version of the web service. Iwould appreciate you thoughts on this.
ReplyDeleteIndeed, they do it for HumanTask.
DeleteI think it is supposed to be for SOA only and not for the whole company. But they did it for human workflow. But then you probably get one with ws-security which you need to implement.
In PS5 you get a beta UMS soa adapter and then you can make your own service.
thanks
Hi Edwin,
ReplyDeleteWe are using Oracle UMS driver to connect to a SMSC gateway service. Our SOA suite version is 11.1.1.5.0 on Weblogic server 10.3.5.0. We have two sets of installations with this configuration.
But in one of the installations the driver name is showing as "umsmessagingdriver-smpp" whereas in the other it is showing as "sdpmessagingdriver-smpp" in the EM console.
Could you please throw some light on this issue with different names?
Thanks in advance.
Regards,
Ranit
Hi,
DeleteSorry don't know the answer. make ask support.
thanks
Hi,
DeleteCould you let me know how you connect the UMS driver to SMSC gateway.
How to identify SMSC address? Please help.
Hi,
DeleteCould you let me know how you connect the UMS driver to SMSC gateway.
How to identify SMSC address? Please help.
Hi, please I need help.
ReplyDeleteI built one using BPEL for sending SMS via SMPP.
He is communicating perfectly, but when occurrs fault is not thrown one exception.
Example: when I make a request with the SMPP server DOWN the bpel returns a messageID for me, instead of fault (remoteException).
Thanks!
Hi,
DeleteYou got a reference to the ums messaage, which you can use to track down the status.
I think UMS is async and UMS should handle these errors and send it on a later time
Thanks
We are using SOA 11.1.1.6. We have a requirement of receiving SMS, process it in BPEL and send back to the user.
ReplyDeleteCould you please throw some light on receiving SMS using UMS Driver at SOA level.
Hi,
ReplyDeleteWhen your SMS provider supports UMS SMPP, but I never tested this.
but for the rest it should work the same as email etc.
Thanks
When I send a message with an attachment, the attachment is not readable.
ReplyDeleteI tried plain text and jpeg files, none of them worked.
I have created a Human task actionable notification and enabled task from embedding in to it.In the email being send the ACtions link appears at the top of the email and then the Task From content appears.
ReplyDeleteI want to move the Actions link below the task form in the email. Is there a way to achieve this?
Thanks in advance.
Hi Edwin,
ReplyDeleteIs it possible to change the From address of the email to set dynamically from the payload. Need Urgent Help..
TIA
Swetha