Recently, I have been working on a project to test the inter-operability of Microsoft tool-sets with IBM services and queuing. Having a local MQ server was something that I found very valuable for testing. I found that the install of WebSphere MQ and basic setup of a development MQ server to be sensitive. After a couple days and some guidance from IBM developers, here is what I came up with as steps to install a local WebSphere MQ server on a Windows 7 machine, and things to avoid. Keep in mind these steps are for a local development server. Please do not use these steps for a production system as it will leave you system open to anyone to do as they wish.
Step 1 (Download and install):
I downloaded WebSphere MQ 7.5 software from IBM. I would not attempt to install this on a windows profile based on a domain account. Create a local machine account and put it in the administrators group. I had issues when trying to install under a domain account on my machine, so I would say avoid this. Make sure that once you create the local user account and give it admin rights, log over to that profile and then begin the install.
Step 2 (Network setup):
Once the install wizard begins, you will see a screen like below. Click on the “Network Configuration” in the left panel and select “No” for configure a domain.
Once done, then click on the “WebSphere MQ Installation” in the left panel. Once you do this, the screen will change to like below.
From here, click on “Launch IBM WebSphere MQ Installer” for the installation to continue.
Step 3 (Installation level you wish):
While I did not show this, you can customize what is installed, or just take the typical. I installed everything just in case I need it tomorrow, I need not worry it is already there.
Step 4 (Instance name) :
Once the initial install is complete, the following dialog below will be shown. This is because a server can support multiple installations of WebSphere MQ. I called my instance DEVMQ. Since this was a local installation and the only one, I made it the primary installation.
Once you click on next, you will get a screen asking if there are any domain controllers. Since this is a local development installation, select “No” and click next. Once beyond this screen, the installation should finish. Once it is finished it will launch the “Prepare WebSphere MQ Wizard”. Just exit out of this, we will prepare it later.
Step 5 (User Group Changes):
Once the installation is finished, go into the computer management and add the user that you are logged in with into the “mqm” group. This group is what WebSphere uses to know who is allowed to manage the MQ instance. Without this, some of the commands that need to happen can not be executed by this user. At this point reboot your machine. If you do not, then all the changes from the installation and changes to group membership will interfere with being successful in following steps.
Step 6 (Prepare MQ Wizard):
Once rebooted, in order to be able to start setting up a queue manager and queues, you need to launch the Prepare MQ Wizard. This will be located program/IBM WebSphere MQ. The following screen will show as it inspects your network configuration.
After completed the inspection, the following dialog will show. Please select the “No” option since we are creating a local development installation of MQ.
Once this is complete, it will ask to launch MQ Explorer, which you should be able to do now and to begin the setup of queue manager, channel, and queues.
Step 7 (Creating a queue manager):
If you are not already in MQ Explorer, open it up and you will see something similar to below. Follow the image below and right click to create a new queue manager.
Once you click to create a new queue manager, a screen like below will show. Fill it out like I have it below. Please keep in mind that WebSphere MQ is case sensitive, so if you decide to change any of the names, it is probably best to keep them all in caps. Also make a note of what you name things as these will be important when you are connecting to put or get messages. Also, make sure the dead-letter queue is spelled exactly as below, as this is a system defined dead-letter queue and will not work if spelled incorrectly.
You should be able to click on finished at this point, and you will see a screen like below where the queue manager is being started.
Once the queue manager is started, you should see MQ Explorer with the queue manager showing similar to below.
Step 8 (Setup channel):
Once the queue manager is created, go to the left pane of MQ Explorer and create a server connection channel as is below.
Once you click to create a server connection channel, the screen below will come up. You can name this as you wish, just keep in mind it too is case sensitive.
Click on next. A screen like below will come up. Navigate in the left bar to the MCA and enter the MCA user id exactly as below. This user id is an id that WebSphere MQ creates to manage everything. What you are telling this is, when someone hits the queue, impersonate this user. This would be a big no-no in a production environment!!
Once this is filled in, you can click on finished which then should show something like the following upon the channel being created.
Step 9 (Queues setup):
Once the channel is created, navigate like below to create a queue from the context menu.
Create a local queue. I create one called REQUEST and one called REPLY. This would be for a situation where there is a request / response from the calling client, but the queue does all the routing. It can be as easy as to create one queue called REQUEST. Just as a note, if you have a client with a contract expecting a request / response, both a request and reply queue will be needed.
Step 10 (Turn off client authorization):
The final step is to turn off client authorization, so that way MQ does not reject clients connecting. By running the command below at a command prompt, it will turn off client authorization for a queue manager. If it says that you are not authorized, it is likely because the user you are logged-in as is not in the mqm group, or that you have not logged out and back in.
At this point, you should be able to login as anyone on your machine, and pass or listen to messages.
Please keep in mind this does not go into the finer points of security on MQ or how to do the connection with another client. I plan on following up with how you can connect using .NET 4.0 WCF client in a future post.
Recently, I was involved in coming up with a way to integrate Dynamics 2011 with other data sources that would be in XML format as well as data feeds into SQL tables. I was asked to limit the scope of integration to .NET and BizTalk tool-sets for a POC in the Microsoft stack of technologies. I started looking at BizTalk, but realized that with Microsoft not officially supporting the Dynamics adapter for the 2011 version, and that generating contracts and messages to a key/value pair service that Dynamics platform very cumbersome and difficult, I decided there should be a better way of doing this. (To see more information on this approach, read Richard Seroter’s article on this integration difficulty with BizTalk and Dynamics 2011).
So my next step was looking at the XRM SDK for Dynamics 2011. There was a nice little tool in there call crmsvcutil, that allowed me to generate the entity model and datacontext for any given Dynamics 2011 environment. Once I realized this, I knew this had potential.
The one challenge I had early on was, I wanted to decouple much of the details of data that was coming in, and the standard CRUD operations needed to save the data. So I implemented an abstract CRUD class that required an alternate key look-up against an entity. I did this by using generics, that way when implementing a concrete CRUD class, it would know what the return types would be and the abstract class required an implementation of getting a record by an alternate key, so the appropriate insert/update action could be taken.
I did the same type of things for a transaction against any given entity, having a base class that allowed for specific implementation, and allowed for overriding the save operation. The idea being that there could be a more complex multi-step transaction that needs to not use the base code, as it would commit incorrectly as an atomic unit of work. So having these base classes, I was able to implement them against any code generated by the crmsvcutil, and quickly create saves to entities, and override if I needed it to act differently. Cool thing was, most of the time I did not need to change much that was already implemented in the base.
Two other challenges I faced was, when the contract is generated from the data model, it does not include the values from the drop down lists. The second challenge I faced was when I mapped from an external contract to and entity, and then called into a transaction to save an entity, that entity was not a part of the data context, which was fine when there was no matches for the alternate key, but problematic when there was.
So, after doing a little reading on Microsoft site about the XRM framework, I realized there could be executed against the service the get a RetrieveEntityResponse which contains the metadata about an entity and all its attributes, by populating a RetrieveEntityRequest. The items in the request were, the logical name of the entity and filters you wished on the metadata. So I found this to be a very good candidate function to put in my entity base class that way every entity I implemented, would have this function to look up the metadata come along for the ride. Also, I noted this was a good candidate for implementing some type of caching, because these values I would consider to be slow to change and setting an appropriate expire interval on cache within a configuration file would be good. I also found this would be good for catching if an attribute was required by not part of the data passed in.
So for the second challenge I faced in mapping a new entity to an existing entity, I realized I should be able to use the list of attributes of the entity, and map the updates over to the one existing within the datacontext. Leveraging the metadata about an entity, I was able to create a generic mapper for any entity that can map all the attributes to the entity managed by the datacontext.
With this foundation of code written, I was able to expose a service contract and pass in data and map it over to the appropriate entity and call the appropriate transaction class for saving the data.
Form an architectural perspective a few things. There are tools out there such as Scribe for getting data into and even out of Dynamics CRM, so this approach is not the correct approach for all situations. The appropriate buy versus build analysis should be done. Secondly, I would challenge if the data being put into Dynamics CRM really will be mastered there. This is an important question as mapping data into a Dynamics CRM data structure through any integration is costly. It would be my suggestion if the data does not live in Dynamics or is not such a base object to most operations like customers and contacts, to have the system of record expose a service. If that is not possible and data is being shipped or mined, I would recommend looking at .NET Entity Framework ability to expose a service from data received against a data-store. This has the advantage that if in the future a service can get the data from the system of record, then changes to Dynamics are not needed. It also has the advantage of not needing populate custom entities within Dynamics, which can be costly on performance depending on the size of the data.
If you have any questions or different experiences with integration of Dynamics 2011, I would love to hear about them.
How appropriate this sample article would start with “Hello World”, since most software developers begin with such a program. This blog I am going to be focusing on different software packages, and how I approach integration with them. I will admit while I strive to be a perfectionist, I am perfect by no means. So I encourage those with experience in any given area to give feedback, and if you learn something, let me know this as well. I hope this blog can be a learning experience for everyone, me included!
The Integration Guy.