onsdag, april 16, 2008

Re-Configuring a Web Service DataControl to Point to Another WSDL

A common issue that occurs in all projects is the question about moving an Application between different environments; for example, moving from the Development environment to the Test environment or from the Test environment to the Production environment. Normally this is not a big issue, you just make some modifications to your build scripts (Ant, Maven or whatever you use), or you already have different targets within them for the different environments, and within these targets you point the Application to use the appropriate resources (like Databases) for the different environments. Quite convenient. For most type of resources this approach works fine, however when you use an ADF Application that accesses Web Services via a DataControl exactly how-to do this is not that obvious.

Suppose that you have a Web Services available in a Test and in a Production environment. The URLs are:

Test:
http://MyTestHost/myContext/TheWebServiceSoapHttpPort?WSDL

Production:
http://MyProductionHost/myContext/TheWebServiceSoapHttpPort?WSDL

Now, you create a new JDeveloper project with a Web Service DataControl that point to the Test URL. You then start to browse the project and you find a file called DataControls.dcx. Within this file you find a pointer to a WSDL file (under DataControlConfigs -> AdapterDataControl -> Source -> definition). Great! This must the pointer to my Web Service you think, which is reasonable to believe cause there is no single other reference to a WSDL available within your whole project. So, you modify your Ant build script, creates deployment targets for the different environments that points to the respective WSDL and you deploy to the Test environment. This works fine (well, since the Web Service was generated towards this WSDL, it should). Next, you deploy to the Production environment but now when you run the Application, you still see data from the Test environment. What the ¤%&" going on???

The answer here is that there is a little more to the story then what appears at first sight. If you have a look in the WAR file for the Application, you will notice a file called connections.xml, sounds promising, right, as the connections seems to be the problem here? If you open it, you will find some interesting information, but first...

If you go back and have another look at your DataControls.dcx under the definitions section, you see an element like:

<service name="TheWebService" namespace="http://testwsdcx/" connection="ClientService">

as the connection here is the same as the name in the definition it is easy to believe that this point to the definition, however, that is not the case. The connection attribute points instead to the corresponding Reference element in the connections.xml file. Further, in the Reference section, you will find the real pointers that the DataControl uses to communicate with the Web Service. I said pointers, cause there are two for each Reference element; one to the WSDL (under wsconnection) and one to the Port (under service -> port -> soap).

I might at this point just add for reference that JDeveloper adds this file automatically to the WAR file during deployment; however, I think you have figured that one out already...

So, based on the above discussion we can now solve the problem in two ways:

Option A: Let your build script modify the connections.xml file and point to the correct.

Option B: Copy the whole Reference section for your Web Service connection and give it another name, for example ClientServiceTest and ClientServiceProd. You can then choose which connection to use by pointing the connection attribute in the DataControls.dcx to the correct definition, like:

<service name="TheWebService" namespace="http://testwsdcx/" connection="ClientServiceTest">

Or:

<service name="TheWebService" namespace="http://testwsdcx/" connection="ClientServiceProd">

and of course, you need to handle this in your build script. So far I haven't found any major differences between the approaches, however I think that Option B looks a bit cleaner, but the choice is really yours.

Oh, I almost forgot... The connections.xml file is found on the Application level, not on the Project level, for JDeveloper. It is not visible in the IDE, but you can find it in the .adf/META-INF folder for your Application.

I'm assuming that the Web Services in the example above are identical; just that they are deployed to different machines...

1 kommentar: