Many people make use of different mechanisms for creating e-mail messages. Most of them use some kind of SMTP client to do so. For the more adventurous, there is MAPI that allows you access to a Microsoft Mail based client to do a few things over and above just plain mail. These are things that people do on a daily basis.
A couple of months back, a gentleman who has now become a friend and business partner, Jim Ford of Ford Audio-Visual, came to me and asked me if there was any way to get at all the calendar items in his sales organization's calendars with the intention of integrating it with his Progress OpenEdge CRM system. Jim is using Exchange 2007 for his e-mail and calendaring solutions.
I was aware that Microsoft had released a new API for Exchange in Exchange 2007 called Exchange Web Services (EWS), and so I said that I needed to do a little research on the API, but I was pretty sure that it was possible. Sure enough, MSDN has some documentation of the API and Microsoft is touting it as the replacement for all APIs that communicate with Exchange. Web Services – how hard can it be?
The Production Environment
In the production environment, an OpenEdge client running on a Unix server needs to initiate a WebService call to Exchange to create, update and delete appointments for sales people. These appointments will be created in the user interface for the CRM application.
Sales people then need to be able to change and delete these appointments from their Outlook clients or their Blackberry/iPhones. Any changes to the appointments need to be recorded as history updates in the CRM system, so Exchange needs to notify the OpenEdge CRM system of these changes.
So the updates to appointments need to happen from both directions and the communication is going to happen cross-platform (Unix to Windows and vice-versa).
My initial plan was to create a prototype that did the two-way communication directly from OpenEdge to EWS. I just wanted to prove that it was possible. The first step was to build an OpenEdge WebServices Client that created a calendar item in the Exchange store. Unfortunately, for various reasons, this is much harder than I thought it would be.
First, the EWS WSDL is not a standard WSDL. EWS is installed as part of the Client Access Server (CAS) component of Exchange. In production, you can have multiple Mailbox Servers and the CAS has to discover which mailbox server services a client. As a result, the URL that is used to actually call EWS is different depending on which Mailbox Server hosts the mailbox. The WSDL therefore does not contain a "service" node and the OpenEdge WSDL parser cannot parse the WSDL. I tried working around that by creating a dummy WSDL with a service node inside it.
The second problem was that I ran into all kinds of problems with the complex type structure that exist in the WSDL. The types and messages live in a separate XSD file and the WSDL parser did not like some of the message definitions as they included optional types.
The last straw was that the connection to EWS is an SSL connection that, by default, wants to use NTLM authentication and I battled for hours to get this to work. I would probably have figured the problem out earlier if I had had some more clear indications from OpenEdge of exactly what the problem was, but I finally decided to go and try the connection from Java.
Before I started on the Java example, I decided that I should probably test that I could even make this happen in .NET. Even that is no small feat. The examples that come with the Exchange SDK are about as useful as an udder on a bull, and I eventually decided to bite the bullet and look for a book on the subject.
I normally avoid Microsoft Press books because, more often than not, they simply regurgitate the standard Microsoft examples and contribute very little additional value. That is not the case with Inside Microsoft Exchange 2007 Web Services. Authors David Sterling, Benjamin Spain, Michael Mainer, Mark Taylor, and Huw Upshall have done an outstanding job of creating a book that really gets to the heart of the technology. They are all members of the Exchange development team, and it shows. The book provides enough background information that it is essential reading for anyone trying to do this stuff.
Java to EWS
Armed with my new reference, I now set about building a Java client that could create an appointment in Exchange, figuring that I could expose the Java client as a Web Service that OpenEdge could consume.
Now, before you throw your toys out your crib and tell me that that is a very expensive way to do things from a performance point of view, let me just clarify that I would have ended up going down this road eventually, anyway. Ultimately, the solution will be exposed as a service on an ESB, and that ESB is likely to be based on a JMS MOM, like Apache ActiveMQ, or SonicMQ. So this is not a wasted exercise. The reason that I need this on an ESB is that the events that flow in each direction need to be available to other services, too.
Java to EWS was not a lot easier to get working. I still had to work around the WSDL not having a "service" node issue, but Java gives you finer-grained control of the parsing of the WSDL. Moreover, in my initial implementation, I did not use JAX-WS or any other WebServices technologies like Axis. I simply used an HTTP request to the WebService to get through the issues. This made life a whole lot easier.
The SSL problem reared its ugly head again, but this time I quickly learned 2 things:
- Exchange creates a default certificate for you when you install it. Either you have to install the certificate as a trusted certificate in the certificate store, or you have to set up a certificate authority on your Windows Server and build signed certificates. I went with the former idea and that resolved the first part of the SSL problem.
- Exchange is installed to support only NTLM authentication, but NTLM authentication is a pain to work with from non-Microsoft technologies. You can change the settings of the EWS virtual directory on the Microsoft IIS Server that runs on the CAS to support basic and digest authentication. For testing, I set this up as basic, but I now have digest working. I will probably go back and revisit NTLM again later, but it is very hard to find any information to help with solving problems, so I may simply require digest authentication.
Once I got past these issues, creating the calendar item was actually very simple.
OpenEdge through the Java WebService
The next step was to take what I had created and expose it as a Java Web Service. I went with Glassfish V3 as the application server just to test this and in about a half hour I had the Web Service up and running and soapUI was creating appointments through the Java Web Service without any problems.
I then went back to OpenEdge and used its WSDL analyzer to analyze the WSDL. It worked really well. I then built a quick client that called the Java Web Service from OpenEdge and it worked first time.
Although this is now a working prototype, it is exactly that – a prototype. There are several pieces that still have to be proven:
- I need to subscribe to change updates from Exchange.
- I need to get to updates for all sales person mailboxes. This means I need to use Exchange Impersonation and that has a number of security risks associated with it.
- I need to make sure these updates get through to OpenEdge efficiently which means I need a test harness that can generate several thousand appointments a minute and have them update the OpenEdge AppServer without breaking it.
Having said that, I am really excited and very optimistic about how this is turning out. I have learned more about Windows Server, Microsoft Exchange, Active Directory, Exchange Web Services, OpenEdge Web Services, and Java Web Services than I had ever imagined possible.
In the next few weeks I will be providing an update on where I finally ended up with this from an architectural point of view.