Skip to main content
This revision made January 10, 2013 21:29, by Olivier LeDiouris

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.

Attention

For now, this works only for external references relying on HTTP. This Proxy we talk about is a flavor of some HTTP Proxy.

How it works

The idea is to create a proxy server that will by default just shuffle the requests and response 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 130.35.95.19 -remote-port 7001 -proxy-port 7101 -prop-file proxy.properties -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
request.condition.xpath.1=//{http://xmlns.oracle.com/soatesthelper/SOACompositeForInstallationTests/SynchronousBPELProcess}input
request.condition.value.1=whatever
response.payload.file.1=generic-sync.output.proxy.xml
# response.payload.string.1=<processResponse xmlns="http://xmlns.oracle.com/soatesthelper/SOACompositeForInstallationTests/SynchronousBPELProcess"><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="http://platform.integration.oracle/blocks/adapter/fw/metadata" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:orawsp="http://schemas.oracle.com/ws/2006/01/policy" xmlns:edl="http://schemas.oracle.com/events/edl" xmlns="http://schemas.oracle.com/soa/configplan">
 .....
      <reference name="ExternalReference">
         <!--Add search and replace rules for the binding properties-->         
         <binding type="ws">
            <attribute name="port">
               <replace>http://xmlns.oracle.com/soatesthelper/SOACompositeForInstallationTests/SynchronousBPELProcess#wsdl.endpoint(synchronousbpelprocess_client_ep/SynchronousBPELProcess_pt)</replace>
            </attribute>
            <attribute name="location">
               <!--
                | This patch is used for the Proxy Bypass stuff.
                +-->
               <!--replace>http://130.35.95.19:7001/soa-infra/services/default/SOACompositeForInstallationTests/synchronousbpelprocess_client_ep?WSDL</replace-->
               <searchReplace>
                 <search>130.35.95.19</search>
                 <replace>localhost</replace>
               </searchReplace>
               <searchReplace>
                 <search>7001</search>
                 <replace>7101</replace>
               </searchReplace>
            </attribute>
            <property name="weblogic.wsee.wsat.transaction.flowOption">
               <replace>WSDLDriven</replace>
            </property>            
         </binding>
      </reference>
   </composite>
 .....
</SOAConfigPlan>
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 130.35.95.19 -remote-port 7001 -proxy-port 7101 -prop-file proxy.properties -debug-level 0

In the line above, 130.35.95.19 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.

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
response.payload.file.1=generic-sync.output.proxy.xml # response.payload.string.1=PATCHED # '''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.
 
 
Close
loading
Please Confirm
Close