Working around messy REST references using WSDL interfaces in JDeveloper
I recently ran into multiple issues with Oracle JDeveloper 12.2.1.4 when trying to call external REST web services from a BPEL project. It was quite painful and pretty much what I concluded is that even this latest version of JDeveloper remains to be buggy when it comes to REST development.
My Scenario
I want to invoke a REST service from my BPEL project. This external REST web service is accessible at http://soatest/test/
.
I thus create a REST reference against http://soatest/test/{identifier}
, wherein {identifier}
is a variable that I can dynamically manipulate. For example, this allows me to do a POST against this service at http://soatest/test/ahmed
.
Creating the REST Reference
Adding a REST reference is simple enough. In the screenshot below, I chose not to select the Reference will be invoked by components using WSDL interfaces option.
I then created a Resource Path /test/{identifier}
and created a POST method. Now, as you can see in the screenshot, JDeveloper is smart enough to understand that {identifier}
is a parameter and creates a Runtime Property for you that you can reference in your Invoke activity later on.
Now in my Invoke activity, and I copy a variable to the runtime property rest.template.identifier
which was defined in the adapter earlier. So far, so good.
For some crazy reason, although the code is developed correctly, I got an error during runtime. After enabling TRACE in the logs, I was getting an HTTP 400 error upon invocation:
[2021-08-17T19:01:01.125-06:00] [soa_server1] [TRACE:16] [] [oracle.wsm.agent.handler.jaxrs.RESTClientFilter] [tid: [ACTIVE].ExecuteThread: '21' for queue: 'weblogic.kernel.Default (self-tuning)'] [userId: ] [ecid: c94d4151-e2bc-4185-bd1d-c29d554e6334-81400023,0:1:1] [APP: soa-infra] [partition-name: DOMAIN] [tenant-name: GLOBAL] [oracle.soa.tracking.FlowId: 171470] [oracle.soa.tracking.InstanceId: 543970] [oracle.soa.tracking.SCAEntityId: 514000] [composite_name: myBpelProject!1.0] [FlowId: d6G1X4yE400000T0000NhMldMpEcLkqwwf] [SRC_CLASS: oracle.wsm.agent.handler.jaxrs.RESTClientFilter] [SRC_METHOD: filter] ENTRY org.glassfish.jersey.client.ClientRequest@241cd9a0 ClientResponse{method=POST, uri=http://soatest/test/ahmed, status=400, reason=400}
Essentially an HTTP 400 is a "Bad Request", which means it's on the client side (i.e., my BPEL process). In fact, the target service never received a call.
Oracle Support states that when creating the REST adapter, I should have selected the Reference will be invoked by components using WSDL interfaces option.
The Problem with the Oracle Support Solution
Similar to the steps above, I added a REST reference but now selected the option Reference will be invoked by components using WSDL interfaces.
The problem is that there's no longer any Runtime Property!
This is a real problem actually.
As an ugly workaround, I manually added an existing property to the Expression, so I selected salesforce.LocaleOptions.language
which I knew I would never use.
This is how my adapter looked like in the end:
Now in the Invoke activity, I simply copied my variable over to the jca.salesforce.LocalOptions.language
property, which the adapter then used to override the identifier
parameter.
This surprisingly worked.