Skip to main content
This revision made January 15, 2013 21:38, by Olivier LeDiouris
« earlier revision revert to this « later revision

How to bypass external references

When a Composite (or any service) consumes external references (Credit Card number validation, SSN Validation, etc), it might be required to bypass and fake the standard behavior of such resources.
There is in this project a Proxy implementation that can achieve this kind of goals.
Using the Config Plan when deploying the Composite with external reference(s), we will patch the composite.xml file so it targets the proxy when doing external requests. This way, the original composite remains untouched.


This works for both Web Services external references, and JCA Adapters. The two paths are slightly different though. We will explain, in two different sections.
In the WebServices external reference case, we will be using an HTTP Proxy to filter and possibly re-direct the requests and responses.
In the case of the JCA Adapters, we'll use some kind of trick... We will be patching the external reference to turn whatever request addressed to a JCA Adapter to a request done to the SocketAdapter (which is a JCA Adapter too, coming with the product) behind which we will plug a Socket Proxy to handle the requests and responses, just like in the WebService case.
Note: In the JCA Adapter case, there is currently no way to let the call go to the original Adapter. A 'default' case should be implemented.

How it works

The idea is to create a proxy server that will by default just shuffle the requests and responses back and forth.
In addition, it has the possibility to detect a condition - based on the HTTP request - where some action is required, like not calling the service, and returned a pre-defined or reworked payload to the service client.
A working example comes with this project, show how to bypass an external reference.
See the Composite named CompositeWithExternalReferences, it invokes the synchronous service in SOACompositeForInstallationTests.

The proxy is launched on a given port, to manage the requests made to a specific server running on a given port. Its behavior is driven by a properties file. An example of such a proxy implementation is in util.httputil.proxyimpl.ReferenceProxy.
To start it:

 prompt> java util.httputil.proxyimpl.ReferenceProxy -remote-host -remote-port 7001 -proxy-port 7101 -prop-file -debug-level 3

The properties file looks like this:

request.starts.with.1=POST /soa-infra/services/default/SOACompositeForInstallationTests/synchronousbpelprocess_client_ep HTTP/1.1
# response.payload.string.1=<processResponse xmlns=""><result>PATCHED</result></processResponse>
Note: Properties request.condition.xpath.X and request.condition.value.X are optional.
You can see that several interceptions of a request can be done, the properties names are suffixed with a number.
The request.starts.with.X describes the request to intercept. If the http request begins with this string, then the next properties are used and applied.
In addition, the request.condition.xpath.X and request.condition.value.X are also considered. The payload will be substituted to response.payload.string.X or response.payload.file.X if the value pointed by request.condition.xpath.X is the one contained in request.condition.value.X.

For the requests to be re-directed to the proxy, we use a Configuration Plan when deploying the composite (the one with external references).
Here is an example of such a deployment plan:
<?xml version="1.0" encoding="UTF-8"?>
<SOAConfigPlan xmlns:jca="" xmlns:wsp="" xmlns:orawsp="" xmlns:edl="" xmlns="">
      <reference name="ExternalReference">
         <!--Add search and replace rules for the binding properties-->         
         <binding type="ws">
            <attribute name="port">
            <attribute name="location">
                | This patch is used for the Proxy Bypass stuff.
            <property name="weblogic.wsee.wsat.transaction.flowOption">
Notice the searchReplace elements, the server where the external reference lives is replaced with localhost, and same for the port. Localhost is the machine where the proxy is running, and the port is the one the proxy is listening to.
The build-file named basic-service-test.with.references.proxy.xml gives a working example of those features.
See in this file the target named "with.bypassed.references". It starts the proxy, deploys the composite with the right configuration plan, runs the test - with bypassed references, and shuts down the proxy.

NB: It works also for asynchronous-two-ways service invocations.

Scenario for Validation

Here is a way to visualize the behavior of the proxy:

  • Deploy the Composite named SOACompositeForInstallationTests
  • Deploy (without config plan) the Composite named CompositeWithExternalReferences (this one consumes the above)
  • Run the CompositeWithExternalReferences , providing any string as input, like 'Foo'.

It should return something like 'Hello Foo', which is what SOACompositeForInstallationTests returns.
Now, let's use the proxy, to override the behavior of SOACompositeForInstallationTests.

  • Start the proxy, using a command like this:
 Prompt> java util.httputil.proxyimpl.ReferenceProxy -remote-host -remote-port 7001 -proxy-port 7101 -prop-file -debug-level 0

In the line above, is the address of the server where the service to bypass is running.
The properties file is the one listed above in this page, making the service call to return 'PATCHED' when 'whatever' is sent as a request.
Note: the Proxy must be visible from the server the service to bypass runs on.
This being done:

  • Re-deploy CompositeWithExternalReferences, with the config plan named CompositeWithExternalReferences_cfgplan.xml (you might need to modify it to match your environment). This config plan replaces host name and port name of the external reference.
  • Run the CompositeWithExternalReferences, providing any string as input, like 'Foo'.
  • You should see 'Hello Foo', just like before, because the condition mentioned in the properties file is not met.
  • Run again the CompositeWithExternalReferences, providing the string 'whatever'.
  • You should see 'PATCHED', as the condition mentioned in the properties file is met.

This means that the proxy has done its job. And you can see in the Audit Trail that the external reference has indeed not been invoked, as expected.

The JCA Adapters case

The JCA Adapters use abstract WSDLs, that make the story describe above a little bit different. It is today (Jan-2013) to substitute a reference using abstract WSDL to a reference using concrete ones. This is one we switch the reference from whatever it is to a reference to the SocketAdapter, which is also a jca Adapter.
Another glitch: The Configuration Plan cannot currently patch the binding.jca element of the composite.xml. We use a utility written for the occasion.
Here is a typical Ant task

  <target name="with.bypassed.jca-references">
    <property name="proxy.port" value="9876"/> <!-- 9876 is the value of the port patched in the config-plan -->
    <property name="" value=""/>
    <echo message=">> Step 1. Starting Proxy on port ${proxy.port}"/>
    <java classpathref="classpath" fork="no" classname="util.httputil.proxyimpl.ReferenceProxy">
      <arg line="-remote-host ${}"/>
      <arg line="-remote-port ${soa.port.number}"/>
      <arg line="-proxy-port ${proxy.port}"/>
      <arg line="-prop-file ${}"/>
      <arg line="-debug-level 5"/>
    <echo message=">> Step 2. Patching delpoyment plan, deploying composite with faked references"/>
    <!-- Backup -->
    <copy file="../CompositeWithAdapter/composite.xml" tofile="../CompositeWithAdapter/composite.backup.xml"/>
    <!-- Generate SocketAdapter_tcp.jca -->
    <copy file="./SocketAdapter.config.jca" tofile="../CompositeWithAdapter/SocketAdapter_tcp.jca"/>
    <!-- Patch deployment plan? -->    
    <echo message=">> Step 3. Patching the composite.xml with SocketAdapter (binding.jca)"/>
    <java classpathref="classpath" fork="no" classname="util.xmlutil.CustomConfigPlan">
      <arg line="-composite-location ../CompositeWithAdapter/composite.xml"/>
      <!-- &#034; are double quotes -->
      <arg line="-path-to-node &#034;//{}reference[@name = 'HRAccess']&#034;"/>      
      <arg line="-new-node-content ./newContent.xml"/>
    <echo message=">> Step 4. Packaging..."/>
    <antcall target="package.composite"/>
    <echo message=">> Step 5. Deploying..."/>
    <antcall target="deploy.composite"/>  <!-- Also patches the tcp port, 9876 -->
     | The actual test is here.
    <echo message=">> Step 6. Service test, with faked references."/>
    <antcall target="unit.test.synchronous"/>
     | The actual test is done.
    <echo message=">> Step 7. Stopping Proxy (port ${proxy.port})."/>
    <java classpathref="classpath" fork="no" classname="util.httputil.proxyimpl.StopProxy">
      <arg line="${proxy.port}"/>
    <echo message=">> Step 8. Restoring composite.xml"/>
    <!-- Restore Backup -->
    <copy file="../CompositeWithAdapter/composite.backup.xml" tofile="../CompositeWithAdapter/composite.xml" overwrite="yes"/>
    <!-- TODO? Redeploy with the real references ? -->
    <echo message=">> Done!"/>
See where the util.xmlutil.CustomConfigPlan class is invoked. Is patches the element <binding.jca>, not supported by the Configuration Plan.

Warning Note

This approach is probably suitable for Unit Tests.
But as the proxy - as it is for now - is implemented as a small standalone java class, it is certainly NOT suitable for load tests. For load tests, if such a bypass is required, the requests to be bypassed should be re-directed to a service running on a server that would behave like the original one, under stress. Such a re-direction can be taken care of by the config plan, but the rest of the bypass implementation will not be the same...

Difference compared to previous revision

'''''Note:''''' In the JCA Adapter case, there is currently ''no way'' to let the call go to the original Adapter. A 'default' case should be implemented. == How it works == The idea is to create a proxy server that will by default just shuffle the requests and responses back and forth.
In addition, it has the possibility to detect a condition - based on the HTTP request - where some action is required, like not calling the service, and returned a pre-defined or reworked payload to the service client.
Please Confirm