First, connect to exchange server via EWS Java API as
1 2 3 4 5 6 7 8 9 10 11 | ExchangeService service; private void init() throws Exception { service = new ExchangeService(ExchangeVersion.Exchange2010_SP2); // Provide Crendentials ExchangeCredentials credentials = new WebCredentials("my_login_id", "nypassword", "my_login_domain"); service.setCredentials(credentials); service.setUrl(new URI("https://somepoint.company.com/EWS/exchange.asmx")); } |
then, talk to exchange server to subscribe to push notification as
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | private void subscribeToPush() throws Exception { WellKnownFolderName wkFolder = WellKnownFolderName.Inbox; FolderId folderId = new FolderId(wkFolder); List<FolderId> folder = new ArrayList<FolderId>(); folder.add(folderId); URI callback = new URI("http://my_notification_listener_host:7777/podm/rs/emailnotification"); PushSubscription pushSubscription = service.subscribeToPushNotifications( folder, callback /* The endpoint of the listener. */, 5 /* Get a status event every 5 minutes if no new events are available. */, null /* watermark: null to start a new subscription. */, EventType.NewMail); System.out.println("PushSubscription = " + pushSubscription); BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); System.out.print("Enter String"); String s = br.readLine(); } |
The push notification listener is implemented as Restful Web Service in Java as
1 2 3 4 5 6 7 8 9 | @POST() @Path("/emailnotification") @Produces(MediaType.TEXT_XML) public Response onNotificationReceived() throws Exception { logger.debug("received EWS notification"); File file = new File("C:\\Users\\XYZ\\workspace\\POC\\ews_notification_response.xml"); String responseXMLStr = IOUtils.toString(new FileInputStream(file)); return Response.ok(responseXMLStr).build(); } |
Once deployed to JBoss AS 7.1, below are the traffic back end force between notification listener and exchange server as
on new email arrived in INBOX, exchange server notify our registered notification listener via SOAP message as
notification SOAP message header:
POST /podm/rs/emailnotification HTTP/1.1 Content-Type: text/xml; charset=utf-8 Accept: text/xml SOAPAction: http://schemas.microsoft.com/exchange/services/2006/messages/SendNotification Host: my_notification_listener_host:8080 Content-Length: 1492 Connection: Close
notification SOAP message body:
<?xml version="1.0" encoding="UTF-8"?> <soap11:Envelope xmlns:soap11="http://schemas.xmlsoap.org/soap/envelope/"> <soap11:Header> <t:RequestServerVersion xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types" xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages" Version="Exchange2010_SP2" /> </soap11:Header> <soap11:Body> <m:SendNotification xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages" xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types"> <m:ResponseMessages> <m:SendNotificationResponseMessage ResponseClass="Success"> <m:ResponseCode>NoError</m:ResponseCode> <m:Notification> <t:SubscriptionId>EABnaXphLWZlLm93ZmcuY29tEAAAAA4cC3zQY3VAn3vY0tY6uAZ8uvK7TlLSCA==</t:SubscriptionId> <t:PreviousWatermark>AQAAAB0YmFETCChLogUFZRl0jsftgtkCAAAAAAA=</t:PreviousWatermark> <t:MoreEvents>false</t:MoreEvents> <t:NewMailEvent> <t:Watermark>AQAAAB0YmFETCChLogUFZRl0jscHg9kCAAAAAAE=</t:Watermark> <t:TimeStamp>2015-05-01T17:52:40Z</t:TimeStamp> <t:ItemId Id="AAMkADAzNTU1N2I2LWY1MTgtNDFmMC1iMzY0LWQ0YzE0NzJiNTBlYwBGAAAAAACwfA0zVZM5SIQ183rvBHkaBwAgnojIUDF8R5DPCbpjOk1jAAAATOY4AAAgnojIUDF8R5DPCbpjOk1jAAAATidsAAA=" ChangeKey="CQAAAA==" /> <t:ParentFolderId Id="AQMkADAzNTUBN2I2LWY1MTgtNDFmMC1iMzY0LWQ0YzE0NzJiNTBlYwAuAAADsHwNM1WTOUiENfN67wR5GgEAIJ6IyFAxfEeQzwm6YzpNYwAAAUzmOAAAAA==" ChangeKey="AQAAAA==" /> </t:NewMailEvent> </m:Notification> </m:SendNotificationResponseMessage> </m:ResponseMessages> </m:SendNotification> </soap11:Body> </soap11:Envelope>
Once our notification listener receives a notification from exchange server, it sends back a ACK response to exchange server and also let exchange server know it's still alive:
notification response message header:
HTTP/1.1 200 OK Server: Apache-Coyote/1.1 Content-Type: text/xml Content-Length: 474 Date: Fri, 01 May 2015 17:52:41 GMT Connection: close
<?xml version="1.0" encoding="UTF-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages" xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <soap:Body> <m:SendNotificationResult> <m:SubscriptionStatus>OK</m:SubscriptionStatus> </m:SendNotificationResult> </soap:Body> </soap:Envelope>
More traffic output:
14:38:29,151 DEBUG [jwang.poc.ejbs.EmailProcessorSB] (ServerService Thread Pool -- 64) subscription id=EABnaXphLWZlLm93ZmcuY29tEAAAAGcHwXOH1UFIuzwCceWIzEw2k58eE1vSCA==
14:38:29,152 INFO [jwang.poc.ejbs.EmailProcessorSB] (ServerService Thread Pool -- 64) resumed subscription to push notification on exchange server with previous watermark = AQAAAB0YmFETCChLogUFZRl0jscNWfACAAAAAAA=
*** notification with events
<?xml version="1.0" encoding="UTF-8"?>
<soap11:Envelope xmlns:soap11="http://schemas.xmlsoap.org/soap/envelope/">
<soap11:Header>
<t:RequestServerVersion xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types" xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages" Version="Exchange2010_SP2" />
</soap11:Header>
<soap11:Body>
<m:SendNotification xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages" xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types">
<m:ResponseMessages>
<m:SendNotificationResponseMessage ResponseClass="Success">
<m:ResponseCode>NoError</m:ResponseCode>
<m:Notification>
<t:SubscriptionId>EABnaXphLWZlLm93ZmcuY29tEAAAAGcHwXOH1UFIuzwCceWIzEw2k58eE1vSCA==</t:SubscriptionId>
<t:PreviousWatermark>AQAAAB0YmFETCChLogUFZRl0jscE+vACAAAAAAE=</t:PreviousWatermark>
<t:MoreEvents>false</t:MoreEvents>
<t:NewMailEvent>
<t:Watermark>AQAAAB0YmFETCChLogUFZRl0jsd/BPECAAAAAAE=</t:Watermark>
<t:TimeStamp>2015-05-12T21:39:07Z</t:TimeStamp>
<t:ItemId Id="AAMkADAzNTU1N2I2LWY1MTgtNDFmMC1iMzY0LWQ0YzE0NzJiNTBlYwBGAAAAAACwfA0zVZM5SIQ183rvBHkaBwAgnojIUDF8R5DPCbpjOk1jAAAATOY4AAAgnojIUDF8R5DPCbpjOk1jAAAATigPAAA=" ChangeKey="CQAAAA==" />
<t:ParentFolderId Id="AQMkADAzNTUBN2I2LWY1MTgtNDFmMC1iMzY0LWQ0YzE0NzJiNTBlYwAuAAADsHwNM1WTOUiENfN67wR5GgEAIJ6IyFAxfEeQzwm6YzpNYwAAAUzmOAAAAA==" ChangeKey="AQAAAA==" />
</t:NewMailEvent>
</m:Notification>
</m:SendNotificationResponseMessage>
</m:ResponseMessages>
</m:SendNotification>
</soap11:Body>
</soap11:Envelope>
** notification status ping from server without events
<?xml version="1.0" encoding="UTF-8"?>
<soap11:Envelope xmlns:soap11="http://schemas.xmlsoap.org/soap/envelope/">
<soap11:Header>
<t:RequestServerVersion xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types" xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages" Version="Exchange2010_SP2" />
</soap11:Header>
<soap11:Body>
<m:SendNotification xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages" xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types">
<m:ResponseMessages>
<m:SendNotificationResponseMessage ResponseClass="Success">
<m:ResponseCode>NoError</m:ResponseCode>
<m:Notification>
<t:SubscriptionId>EABnaXphLWZlLm93ZmcuY29tEAAAAGcHwXOH1UFIuzwCceWIzEw2k58eE1vSCA==</t:SubscriptionId>
<t:PreviousWatermark>AQAAAB0YmFETCChLogUFZRl0jsd/BPECAAAAAAE=</t:PreviousWatermark>
<t:MoreEvents>false</t:MoreEvents>
<t:StatusEvent>
<t:Watermark>AQAAAB0YmFETCChLogUFZRl0jscbCPECAAAAAAE=</t:Watermark>
</t:StatusEvent>
</m:Notification>
</m:SendNotificationResponseMessage>
</m:ResponseMessages>
</m:SendNotification>
</soap11:Body>
</soap11:Envelope>
By observation, exchange server seems generate new subscription id for every new subscription to push notification request (even with valid previous watermark parameter). After JBoss AS restars and new email arrives in inbox, exchange server will send notification event to all subscriptions (old and new). When we received a notification, we can check if its notification id matches our current active notification id, if not, we can response with "unscribe" to the exchange server to unscribe the stale subscription.
Unsubscribe response as:
<?xml version="1.0" encoding="UTF-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages" xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <soap:Body> <m:SendNotificationResult> <m:SubscriptionStatus>Unsubscribe</m:SubscriptionStatus> </m:SendNotificationResult> </soap:Body> </soap:Envelope>
as for the notification of current active notification id, we can response with OK to tell the exchange server we got the message and we're still alive:
OK response as:
<?xml version="1.0" encoding="UTF-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages" xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <soap:Body> <m:SendNotificationResult> <m:SubscriptionStatus>OK</m:SubscriptionStatus> </m:SendNotificationResult> </soap:Body> </soap:Envelope>
Hi, i'm trying to make this work with the ews java API but i can't. I hope you can help me !
ReplyDeleteI do the following steps:
1)Connect to the exchange web service
ExchangeService newService = new ExchangeService(ExchangeVersion.Exchange2010_SP2);
newService.setUrl("https://myurl/ews/Exchange.asmx");
ExchangeCredentials credentials = new WebCredentials("asd","asd123");
newService.setCredentials(credentials);
2) Then subscribe to the push notifications:
callback = new URI("http://localhost:8081/rest/emailnotification/incomingevent");
pushSubscription = service.subscribeToPushNotifications(getFoldersForSubscription(), callback, 5, null, EventType.NewMail, EventType.Deleted);
3) Then developed my Listener, a Restful webservice (i've tested with dummy method and it's working)
@Path("/emailnotification")
public class ExchangeNotificationListener {
@Path("/incomingevent")
@POST()
@Produces(MediaType.TEXT_XML)
public Response onNotificationReceived(){ //..my code...}
But i set the breakpoint and send me an email but nothings happens.. What i am doing wrong???
Thanks !
Thanks! This post was helpful
ReplyDeletePlease can you provide full code for your example on how to implement Push Notification Listener in java
ReplyDeleteThanks for sharing this useful info. Check it on: advertising agencies in st louis
ReplyDeleteReally great post, Thank you for sharing This knowledge.Excellently written article, if only all bloggers offered the same level of content as you, the internet would be a much better place. Please keep it up!
ReplyDeleteData Science Training in Chennai
Data Science course in anna nagar
Data Science course in chennai
Data science course in Bangalore
Data Science course in marathahalli
Great post! I am actually getting ready to across this information, It’s very helpful for this blog.Also great with all of the valuable information you have Keep up the good work you are doing well.
ReplyDeleteBest Devops Training in pune
Devops Training in Bangalore
Microsoft azure training in Bangalore
Power bi training in Chennai