vrijdag 25 maart 2016

EJB Adapter quirck?

On the internet, you can find many blog posts about the Soa Suite 12c. This is not one of them. It is about the EJB adapter, running on 11g, and recently we experienced an issue with it. There are many excellent tutorials and blogs about the EJB adapter. For instance, enjoy this one. I know we did. The bean method we wanted to invoke from within our bpel process looked like this:

@Webresult(name="result")
String getResult(@Webparam(name="

param1") String param1, @Webparam(name="param2") Long param2) { .... }

As you may have noticed, this is a simplified example but it serves it's purpose. We followed the blog, created the reference in our composite and invoked the method with parameters from within our bpel process. And, lo and behold, we got our expected result back!

All was well......not!

In some cases, the second argument (param2) could be empty. This meant that in our bpel, the inputvariable to the bean method would look like this:

<param1>someString</param1>
<param2/>


And suddenly, we did not get our expected result back! No error message, no beautiful stack dump, just an empty response. What was happening?

As it turned out, when not supplying a value to the argument, somewhere along the way, the adapter uses the default value. For type Long, this is 0L. To prevent this behaviour, you have to explicitly provide a null value. So our input had to look like this:

<param1>someString</param1>
<param2 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>


This solved the issue for us. Many thanks to Lida van Losser for helping us fix the problem!

woensdag 20 augustus 2014

Dynamically setting the CSF-key

In one of my projects I faced the challenge of invoking, from within my SOA Suite 11g composite, a webservice that was secured with HTTP basic authentication. I decided to use the owsm policy oracle/wss_http_token_client_policy. Because I didn't want the username and password of the referenced webservice to be visible in the audit trail, I also decided to use the Credential Store Framework. There are some excellent blog posts describing exactly how to do this, for instance here and here. I happily implemented this solution and after some basic testing deployed my composite on our test environment. Unfortunately, all was not well and good. It turned out that in some situations the referenced webservice required a different set of credentials, depending on the value of an element in the payload of the message. Now I faced a real challenge! Perhaps because of my poor googling skills, the world wide web didn't provide me with a solution. But this blog post wouldn't have seen the light of day if I hadn't been able to crack it. Here is how it goes.

In the composite.xml, after defining a referenced webservice, applying the owsm policy and overriding the csf-key, this is how it looks in the binding section of the referenced service:

<wsp:PolicyReference URI="oracle/wss_http_token_client_policy"
                           orawsp:category="security" orawsp:status="enabled"/>
      <property name="csf-key">my-csf-key</property>


The trick is to override this csf-key property in the Invoke activity in the BPEL process. I couldn't do this from within the graphic design mode in JDeveloper, so I changed the source code manually:

<invoke ...>
    <bpelx:toProperty name="csf-key" variable="myOtherCsfKeyVariable"/>
</invoke>
 
As you can see, in the BPEL Invoke activity, it is possible to set this property using a variable. The value of this variable can be derived from the message payload in combination with for instance a Domain Value Map lookup.

vrijdag 2 augustus 2013

TaskQueryService with SAML

In this blogpost, I will look at the TaskQueryService with SAML. As an example, I’ll take the authenticateOnBehalfOf operation. In this blogpost, Edwin Biemond explains how to use the TaskQueryService without SAML. The weblogic username and password are visible in the WorkflowContext. This may not be desirable and can be avoided if we use the SAML port. I created a simple composite called getUserToken with a BPEL process and a reference to the TaskQueryService. Looking at the composite.xml, there are two bindings: 


Keep the binding with the TaskQueryServicePortSAML and delete the other one. This is the composite:

  
Next, add some OWSM policies. By default, the TaskQueryServicePortSAML uses oracle/wss10_saml_service_policy. As the getUserToken composite is the client of the TaskQueryService, add the oracle/wss10_saml_client_policy to the external reference. Right-click on the TaskQueryService reference and choose “Configure WS Policies...”.


Add oracle/wss10_saml_token_client_policy.
 

Before the composite is able to use the SAML policy, a security context has to be set. Do this by securing the composite with another policy, in this case use oracle/wss_username_token_service_policy. Right-click on the exposed service bpelprocess1_client_ep and choose “Configure WS Policies...”. Add oracle/wss_username_token_service_policy.
 
The BPEL process itself is quite simple. The input is used to invoke the operation authenticateOnBehalfOf of the partnerlink TaskQueryService. The output is returned in the response.



 The AssignOutput activity:


The AssignInput activity requires extra care:
 


It is essential to remove the element workflowContext before invoking the TaskQueryService. If left in, this error will pop up:

<bpelFault><faultType>1</faultType><processingErrorFault xmlns="http://xmlns.oracle.com/bpel/workflow/taskQueryService"><part name="payload"><taskQueryServiceFaultResponse xmlns="http://xmlns.oracle.com/bpel/workflow/taskQueryService"><message xmlns="http://xmlns.oracle.com/bpel/workflow/taskQueryService">ORA-30010:Error in creating reply message for Web Services. Error in creating reply message for Web Services. The Web Service input could be invalid causing this exception. Check the Web Service input for correctness. The input could also be validated against XML schema definition that describes the operation input. It being valid, this is a system error. </message></taskQueryServiceFaultResponse></part></processingErrorFault></bpelFault>

 Deploy the composite to the server and test it. I have used the test console in the Enterprise Manager but you can use any soap client you like, e.g. SoapUI.


Do not forget to enter the security credentials. As input string I have entered “samltestcase”, this is a user that I have created via the Weblogic Administration Console. After invoking the web service, this is the response:

donderdag 21 februari 2013

Changing DVM in clustered environment.

This post is not about how to edit, delete or add values to your DomainValue Map at runtime using the SOA Composer. The Oracle® Fusion Middleware Developer's Guide for Oracle SOA Suite 11g Release 1 (11.1.1.6.2), chapter 48, basically says it all. The one thing I bumped into was when I tried to do this in a clustered environment. Adding a new value was easy. Committing the chances was also easy. Later, I found out that the chances only took effect on the machine on which I committed those changes. I had to start the SOA Composer on the other machine as well, only to commit the DVM to the runtime. A thing to keep in mind!

zaterdag 29 september 2012

Sharing a File-based MDS repository

If you want to use a file-based MDS repository within JDeveloper, most textbooks explain that you have to create this repository in a very specific directory: <Jdev home>/jdeveloper/integration/seed. In this directory, you have to create the subdirectory 'apps' and your project MDS repositories. This is all very well when you're the only developer in the project, once you're in a team this is a nuisance. Especially in the early stages of a project, the MDS artifacts and structure that your team creates change frequently. If you're not using a database-based MDS during development, you'd like your file-based MDS to be on a share. Thanks to a tip I got from Geoffrey de Lamalle during a SOA summer camp, it is possible to do just that! This is how you do it:

Create, within in your application, a generic project in JDeveloper, call it what you like, for instance myProjectMDS. Create it on a share (e.g. Z:/mds/myApplicationMDS) and create the following subdirectory structure:

(Z:/mds/myApplicationMDS)/src/apps/myMDS/xsd

This directory will hold the XML schema's that are shared in this project (obviously this is a very simplified example). You can extend or change this structure as you like.

Now, how do we let JDeveloper know where this project specific MDS repository is located?

First, change the file jdev.conf, you can find it in the map <Jdev home>/jdeveloper/jdev/bin. Add the following line:

AddVMOption -Dmyapp.home=Z:\mds

Next, change the file ant-sca-compile.xml, found in the map <Jdev home>/jdeveloper/bin. You have to add to <target name ="scac"> the following line:

<jvmarg value="-Dmyapp.home=Z:\mds"/>

Finally, change one more file, called adf-config.xml. It is located in your application directory in the subdirectory .adf/META-INF. Here, you will tell your application which metadata stores to use. Add the following lines:

<metadata-namespaces>
...
   <namespace path="/apps/myMDS" metadata-store-usage="mstore-usage_2"/>
...
</metadata-namespaces>

 <metadata-store-usages>
...
<metadata-store-usage id="mstore-usage_2">
    <metadata-store class-name="oracle.mds.persistence.stores.file.FileMetadataStore">
      <property value="${myapp.home}/myApplicationMDS" name="metadata-path"/>
      <property value="src" name="partition-name"/>    
   </metadata-store>
 </metadata-store-usage>
...
</metadata-store-usages>
  
Restart JDeveloper and the changes should take effect.

Manually deleting MDS entries

The MDS in the Oracle Soa Suite 11g is a very powerful concept. We use it a lot in our projects. At the start of each project, we enthusiastically add all kinds of artifacts, only to find out later that we didn't really need them, that the folder structure of our project in the MDS has changed, that we didn't like the names we gave the artifacts etc etc. Sounds familiar? Eventually, obsolete items start to clutter our projects. Recently I got a tip on how to manually delete items from the MDS and I would like to share this valuable piece of information. It goes like this:

  • Go to the Enterprise Manager
  • Go to the SOA Infrastructure menu
  • Go to Administration -> System MBean Browser


  • Scroll down to the entry "oracle.mds.lcm"
  • expand Server: (your servername) -> Application: soa-infra -> MDSAppRuntime, here you will find the bean MDSAppRuntime

  • Go the the tab called "Operations" and click the link "deleteMetadata" (I always choose the first one)
  • if you click on the pencil next to the item "docs", you can add the documents you want to delete. Wildcards are permitted!

  • once you're done adding the artifacts you wish to delete, click on the button "OK'. Back in the previous screen, you now click on "Invoke".
That's it! Your project MDS is neat and tidy again. Of course, be careful not to remove essential, internal SOA Suite artifacts...