Advertisements

Adding Code Source grants from EM

Often there is a need to interact with credential or policy store from java/ADF code which requires code source grants/system policies. Typically the application’s jazn file will have these values like the following.


<grant>
<grant>
<grantee>
<codesource>
<url>file:${domain.home}/servers/AdminServer/upload/HumanTaskApiTestService/-
</codesource>
</grantee>
<permissions>
<permission>
<class>oracle/security/jps/service/credstore/CredentialAccessPermission
<name>context=SYSTEM,mapName=admin/security,keyName=ADMIN_KEY</name>
<actions>read</actions>
</permission>
<permission>
<class>oracle.security.jps.service.policystore.PolicyStoreAccessPermission</class>
<name>context=APPLICATION,name=*</name>
<actions>*</actions>
</permission>
</permissions>
</grant>
</grant>

Use the following steps to provide these grants through EM Console.

Login to EM Console and navigate to Weblogic Domains -> <> -> Security (on right click) -> System Policies

create

grant

grant1.jpg

grant2

Advertisements

Using BPM Java API – WorkflowContext

 

Once the human task instance is created, we can perform several actions like:

  • Withdraw
  • Delegate
  • Update Task outcome
  • Add Attachment
  • Add Comments
  • Query Task details
  • etc..

If we observe these actions, we can guess that all users of the system should not be able to perform these actions and should be controlled through roles/privileges/permissions. So all these actions requires a user context to determine these permissions. BPM APIs accept this user context in form of WorkflowContext. WorkflowContext is a session object maintained by SOA server tied to an user.

How to create workflowcontext for a specific user?

Task Query service has authenticate method that accepts user credentials and returns a WorkflowContext as shown below.


public IWorkflowServiceClient getWfServiceClient()
 {
 IWorkflowServiceClient wfSvcClient = null;

wfSvcClient = WorkflowServiceClientFactory.getWorkflowServiceClient(WorkflowServiceClientFactory.REMOTE_CLIENT);
return wfSvcClient;
 }

public IWorkflowContext getUserWorkflowContext()
 {
 IWorkflowContext wfCtx = null;
 try
 {
 wfCtx = getWfServiceClient().getTaskQueryService().authenticate("weblogic", "weblogic1".toCharArray(), null);
 }
 catch(WorkflowException wex)
 {
 wex.printStackTrace();
 }

 return wfCtx; 
 }

How to create workflowcontext for a logged in user?

Same Task Query service is used to get workflowcontext for the logged in user as shown below. Make sure that your java/web application is security enabled.

 public IWorkflowContext getLoggedinUserWorkflowContext()
 {
 IWorkflowContext wfCtx = null;
 try
 {
 wfCtx = getWfServiceClient().getTaskQueryService().getWorkflowContextForAuthenticatedUser();
 }
 catch(WorkflowException wex)
 {
 wex.printStackTrace();
 }

 return wfCtx; 
 }

How to create workflowcontext on behalf of a user?

In some of the cases, password may not be available to get the user context but the task actions should be performed by this user. In those cases, we can create admin workflow context and use authenticateOnBehalfOf method of Task Query Service as shown below. Here the user weblogic is admin i.e. having BPMWorkflowAdmin role.

 public IWorkflowContext getOnbehalfOfUserWorkflowContext()
 {
 IWorkflowContext wfCtx = null;
 try
 {
 wfCtx = getWfServiceClient().getTaskQueryService().authenticate("weblogic", "weblogic1".toCharArray(), null);
 wfCtx = getWfServiceClient().getTaskQueryService().authenticateOnBehalfOf(wfCtx, "svgonugu");
 }
 catch(WorkflowException wex)
 {
 wex.printStackTrace();
 }
 return wfCtx; 
 }

How to assign BPMWorkflowAdmin role to an User?

  • Login to EM console and navigate to Weblogic Domain -> <<domainName>> -> Security -> Application Roles.
  • Search for BPMWorkflowAdmin role by choosing soa-infra as application stripe.

search.jpg

  • Click Edit to assign this role to an user and click Add. Note that weblogic user will have admin role by default so the screenshots presented here are only demo purpose.

add.jpg

  • Search for the user weblogic and click ok.

add1

add3.jpg

  • You will observe the following error when try to use authenticateOnBehalfOf method using the workflowcontext created using non-admin user.

ORABPEL-30509

exception.code:30509
exception.type: ERROR
exception.severity: 2
exception.name: Insufficient privileges to authenticate on behalf of another user.
exception.description: User siva cannot authenticate on behalf of user svgonugu without admin privil
eges.
exception.fix: Only users with admin privileges can authenticate on behalf of another user.

Do we have any timeout settings for WorkflowContext?

As mentioned earlier, Workflowcontext is a session object maintained by SOA/BPM server in heap memory. So creating more and more workflowcontexts might cause out of memory errors on the server. So whenever we are done with workflowcontext we should always destroy the context. Also BPM runtime has a default timeout of 60 min after which the workflowcontext object is destroyed. This timeout setting can be modified by navigating to Weblogic Domain -> <<domain name>> -> System MBean Browser -> Application Defined MBeans -> oracle.as.soainfra.config -> Workflow Config -> WorkflowServiceSesionTimeoutInMinutes as shown below.

timeout

If we use workflowcontext after timeout, we will get WorkflowException.

How to destroy WorkflowContext?


getWfServiceClient().getTaskQueryService().destroyWorkflowContext(wfCtx);

Using BPM Java API – wf_client_config.xml

In previous posts (post1 & post2), we have seen how to use SOAP and Remote clients to work with BPM Java APIs. One immediate problem we can see is using server urls in the code which makes deployment across environments difficult. In this post, we will see how to take care of this.

WorkflowServiceClientFactory class has different overloaded methods to get the client. When we don’t pass any properties like below, BPM run time will look for a file wf_client_config.xml in classpath of ear file.


private IWorkflowServiceClient getWfServiceClient()
{
IWorkflowServiceClient wfSvcClient = null;

wfSvcClient = WorkflowServiceClientFactory.getWorkflowServiceClient(WorkflowServiceClientFactory.REMOTE_CLIENT);
return wfSvcClient;
}

We can create wf_client_config.xml with the following contents having the server details and information pertaining to both SOAP and REMOTE clients. The file can be placed in a folder like conf under our project folder.


<?xml version="1.0" encoding="UTF-8"?>
<workflowServicesClientConfiguration xmlns="http://xmlns.oracle.com/bpel/services/client">
<server name="default" default="true">
<remoteClient>
<serverURL>t3://localhost:7005/soa-infra</serverURL>
<userName>weblogic</userName>
<password>weblogic1</password>
<initialContextFactory>weblogic.jndi.WLInitialContextFactory</initialContextFactory>
<participateInClientTransaction>false</participateInClientTransaction>
</remoteClient>
<soapClient>
<rootEndPointURL>http://localhost:7005</rootEndPointURL>
<identityPropagation mode="dynamic" type="saml">
<policy-references>
<policy-reference enabled="true" category="security"
uri="oracle/wss10_saml_token_client_policy"/>
</policy-references>
</identityPropagation>
</soapClient>
</server>
</workflowServicesClientConfiguration>

Include this file in the ear deployment profile using the below steps i.e. corresponding to ADF BC Service project. Create new file group APP-INF/classes as shown below.

app-inf

Add the contributor pointing to conf directory having wf_client_config.xml file.

app-inf1.jpg

Now filters section of APP-INF/classes group should be shown like below.

app-inf2.jpg

Deploy the ear file and re-test your webservice method.

During testing, if the following error is seen in the logs make sure that <?xml version = ‘1.0’ encoding = ‘UTF-8’?> is present as first line in wf_client_config.xml file.

[Exception [EclipseLink-25008] (Eclipse Persistence Services – 2.6.4.v20160829-44060b6): org.eclipse.persistence.exceptions.XMLMarshalException
Exception Description: A descriptor with default root element workflowServicesClientConfiguration was not found in the project]

Since the server details are externalized you can use tokens in wf_client_config.xml and replace them using actual server urls before deploying to specific environments.

 

Using BPM Java API – Creating Human Task (Contd..)

In the previous post, we used SOAP client to invoke BPM java APIs to create a human task. As i mentioned, we will not be able to test remote interface unless we create some java application and deploy to WLS. So in this post, i will create ADF BC Service project to demonstrate this and assume the readers have basic understanding on how to create ADF BC Services.

Following code snippet shows getting the remote client to invoke BPM java API. note the usage of URL.


//admin credentials
private static final String wlsUser = "weblogic";
private static final String wlsPassword = "weblogic1";

//soa-infra url
private static final String soaURL = "t3://localhost:7005/soa-infra";

private Map<CONNECTION_PROPERTY, String> getClientProp(String clientType)
{
Map<CONNECTION_PROPERTY, String> properties = new HashMap<CONNECTION_PROPERTY, String>();

if (WorkflowServiceClientFactory.REMOTE_CLIENT.equals(clientType))
{
properties.put(CONNECTION_PROPERTY.EJB_INITIAL_CONTEXT_FACTORY,
"weblogic.jndi.WLInitialContextFactory");

//soa-infra url
properties.put(CONNECTION_PROPERTY.EJB_PROVIDER_URL, soaURL);

//admin user
properties.put(CONNECTION_PROPERTY.EJB_SECURITY_PRINCIPAL, wlsUser);

//admin pwd
properties.put(CONNECTION_PROPERTY.EJB_SECURITY_CREDENTIALS, wlsPassword);
}
else if (WorkflowServiceClientFactory.SOAP_CLIENT.equals(clientType))
{
properties.put(CONNECTION_PROPERTY.SOAP_END_POINT_ROOT,
"http://localhost:7005");
properties.put(CONNECTION_PROPERTY.SOAP_IDENTITY_PROPAGATION, "non-saml");
}
return properties;
}

private IWorkflowServiceClient getWfServiceClient()
{
IWorkflowServiceClient wfSvcClient = null;

wfSvcClient =
WorkflowServiceClientFactory.getWorkflowServiceClient(WorkflowServiceClientFactory.REMOTE_CLIENT,getClientProp(WorkflowServiceClientFactory.REMOTE_CLIENT),null);
return wfSvcClient;
}

The AM method code which is exposed as webservice method remains similar as shown below.


private Element getTaskPayload() throws Exception
{
String payloadStr =
" <payload xmlns=\"http://xmlns.oracle.com/bpel/workflow/task\">" +
"<EmployeeExpenseInput xmlns=\"http://xmlns.oracle.com/expenses/approval/schema\">" +
" <employeeId></employeeId> " + " <firstName></firstName> " + " <lastName></lastName>" +
" <expenseType></expenseType>" + " <expenseDescription></expenseDescription>" +
" <expenseLocation></expenseLocation>" + " <expenseDate></expenseDate>" +
" <amount></amount>" + "</EmployeeExpenseInput>" + " </payload>";
Document doc = null;

try
{
doc = XMLUtil.parseDocumentFromXMLString(payloadStr);
}
catch (Exception e)
{
throw new Exception("Exception in parsing string to xml");
}
return doc.getDocumentElement();
}

public String createHumanTask(String taskTitle)
{
String taskId = null;
IInitiateTaskResponse taskResponse = null;

try
{
ObjectFactory of = new ObjectFactory();
Task newTask = of.createTask();

//set required attribute before calling BPM task api
newTask.setTaskDefinitionId(taskNameSpace);
newTask.setPayloadAsElement(getTaskPayload());
newTask.setCreator(wlsUser);
if(taskTitle == null || taskTitle.isEmpty())
{
newTask.setTitle("BPM API TESTING USING CREATE HUMAN TASK");
}
else
{
newTask.setTitle(taskTitle);
}

newTask.setCategory("TESTING");
newTask.setIdentificationKey("587776676");

taskResponse = getWfServiceClient().getTaskService().initiateTask(newTask);

if (taskResponse != null)
{
newTask = taskResponse.getTask();
taskId = newTask.getSystemAttributes().getTaskId();
}
}
catch (Exception e)
{
e.printStackTrace();
}
return taskId;
}

When the service method is invoked for the first time, we may observe the following error.


<?xml version="1.0" encoding="UTF-8"?><env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
<env:Header/>
<env:Body>
<env:Fault>
<faultcode>env:Server</faultcode>
<faultstring>JBO-29000: Unexpected exception caught: java.lang.NoClassDefFoundError, msg=oracle/bpel/services/workflow/task/model/ObjectFactory</faultstring>
<detail>
<tns:ServiceErrorMessage xmlns:tns="http://xmlns.oracle.com/adf/svc/errors/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<tns:code>29000</tns:code>
<tns:message>JBO-29000: Unexpected exception caught: java.lang.NoClassDefFoundError, msg=oracle/bpel/services/workflow/task/model/ObjectFactory</tns:message>
<tns:severity>SEVERITY_ERROR</tns:severity>
<tns:detail xsi:type="tns:ServiceErrorMessage">
<tns:message>oracle/bpel/services/workflow/task/model/ObjectFactory</tns:message>
<tns:severity>SEVERITY_ERROR</tns:severity>
<tns:exceptionClassName>java.lang.NoClassDefFoundError</tns:exceptionClassName>
</tns:detail>
<tns:exceptionClassName>oracle.jbo.JboException</tns:exceptionClassName>
</tns:ServiceErrorMessage>
</detail>
</env:Fault>
</env:Body>
</env:Envelope>

This error can be resolved by adding oracle.soa.workflow.wc as library reference in weblogic-application.xml. The file can be found in Application Resources -> Descriptors -> META-INF in JDeveloper.


	<library-ref>
	<library-name>oracle.soa.workflow.wc</library-name>
</library-ref>

Testing

Input

input

Output

output

output2

output3.jpg

The sample ADF BC service project can be found here.

Using BPM Java API – Creating Human Task

In the previous post, I described how different participant types work when we use Named User, Approval Group, Application Role etc in the assignment. Now we will see how to use BPM Java APIs in a series of post. I used 12.2.1.2.0 release for demonstration. This article assumes basic working knowledge of Human Workflows and does not get into finer details of the same.

SOA/BPM exposes number of human workflow services as listed below and all these services can be invoked either using SOAP or remote interface with an exception of Identity service which can be invoked only through SOAP interface. You can refer to url for more information on accessing the service and functionality exposed by each. In this post, we will see how to use Task Service to create a human task from java code.

  • Task service
  • Task query service
  • Identity service
  • Task metadata service
  • User metadata service
  • Task report service
  • Runtime config service
  • Evidence store service

Steps:

  • Create a Human Workflow in a SOA composite and deploy to SOA Server.
  • Create a java project in Jdeveloper with a java class having main method.
  • Add BPM Workflow library by navigating to Project properties -> Libraries and Classpath. This jar will have necessary classes to work with human workflow services mentioned above. Note that the libraries Oracle XML Parser V2 and JAX-WS client also need to be added.
  • To call any of the human workflow services, we need to get workflow service client as the first step which can either SOAP or REMOTE. Following snippet of code shows how to get a SOAP based workflow service client.
private IWorkflowServiceClient getWfServiceClient()
{
IWorkflowServiceClient wfSvcClient = null;
wfSvcClient =
WorkflowServiceClientFactory.getWorkflowServiceClient(WorkflowServiceClientFactory.SOAP_CLIENT,
getClientProp(WorkflowServiceClientFactory.SOAP_CLIENT),null);
return wfSvcClient;
}

private Map<CONNECTION_PROPERTY, String> getClientProp(String clientType)
{
Map<CONNECTION_PROPERTY, String> properties = new HashMap<CONNECTION_PROPERTY, String>();
if (WorkflowServiceClientFactory.REMOTE_CLIENT.equals(clientType))
{
properties.put(CONNECTION_PROPERTY.EJB_INITIAL_CONTEXT_FACTORY,"weblogic.jndi.WLInitialContextFactory");

//soa-infra url
properties.put(CONNECTION_PROPERTY.EJB_PROVIDER_URL, soaInfraURL);

//admin use
properties.put(CONNECTION_PROPERTY.EJB_SECURITY_PRINCIPAL, wlsUser);

//admin pwd
properties.put(CONNECTION_PROPERTY.EJB_SECURITY_CREDENTIALS, wlsPassword);
}
else if (WorkflowServiceClientFactory.SOAP_CLIENT.equals(clientType))
{
properties.put(CONNECTION_PROPERTY.SOAP_END_POINT_ROOT, "http://host:soaPort");
properties.put(CONNECTION_PROPERTY.SOAP_IDENTITY_PROPAGATION, "non-saml");
}
return properties;
}
  • Use the following code to create a task using Task service. You can get task namespace from .task file and is the targetNamespace mentioned there. The Task payload preparation should be as per payload defined in Data section of the human task. Note the usage of workflow service client to get the task service.

private Element getTaskPayload()
throws Exception
{
String payloadStr =
" <payload xmlns=\"http://xmlns.oracle.com/bpel/workflow/task\">" +
"<EmployeeExpenseInput xmlns=\"http://xmlns.oracle.com/expenses/approval/schema\">" +
" <employeeId></employeeId> " + " <firstName></firstName> " + " <lastName></lastName>" +
" <expenseType></expenseType>" + " <expenseDescription></expenseDescription>" +
" <expenseLocation></expenseLocation>" + " <expenseDate></expenseDate>" +
" <amount></amount>" + "</EmployeeExpenseInput>" + " </payload>";
Document doc = null;

try
{
doc = XMLUtil.parseDocumentFromXMLString(payloadStr);
}
catch (Exception e)
{
throw new Exception("Exception in parsing string to xml");
}
return doc.getDocumentElement();
}

public String createHumanTask()
{
String taskId = null;
IInitiateTaskResponse taskResponse = null;

try
{
ObjectFactory of = new ObjectFactory();
Task newTask = of.createTask();

//set required attribute before calling BPM task api
newTask.setTaskDefinitionId(taskNameSpace);
newTask.setPayloadAsElement(getTaskPayload());
newTask.setCreator(wlsUser);
newTask.setTitle("BPM API TESTING USING CREATE HUMAN TASK");
newTask.setCategory("TESTING");
newTask.setIdentificationKey("587776676");

taskResponse = getWfServiceClient().getTaskService().initiateTask(newTask);

if (taskResponse != null)
{
newTask = taskResponse.getTask();
taskId = newTask.getSystemAttributes().getTaskId();
}
}
catch (Exception e)
{
e.printStackTrace();
}
return taskId;
}

  • Similarly, other human workflow services can be accessed using workflow service client. Note that you may not be able to test the remote client from java main method. You need to deploy this to WLS to see it in action.
  • You can download the java project from here.

Human Workflow Participant Types Behavior

Recently I got a chance to work on one of the interesting assignments where I had explored BPM APIs, mainly Human workflow related. I want to share my learning in this blog through a series of articles. This article assumes the basic terminology associated with Human workflow, otherwise one can read the documentation here.

The main focus of this article is to present how notifications will be sent and how many approvals are required for different participant types Single, Parallel, Serial and FYI.I used business rules with Named User, Application Role, Approval Group and Hierarchies (Supervisor/Job/Position) and used 12.2.1.2 version for demonstration. Please note that you should have BPM (just not SOA Suite) installed to try with a few of the assignment types described here.

Assignment Type Participant Type Behavior
Named User

Note that, multiple assignment users can be given for value based setup too.

Single Notifications will be sent at same time to all the users derived in rule evaluation. Only one approval is enough for completion.  A user may have to claim before providing approval.
Parallel Notifications will be sent at same time to all the users derived in rule evaluation. The number of approvals for completion depends on the voting percentage.
Chain/Serial Notifications will be sent at same time to all the users derived in rule evaluation as there is no serial relationship defined among users. Approvals from all assignees are required for completion.
FYI Notifications will be sent at same time to all the users derived in rule evaluation and no approval is required.
Application Role Single Notifications will be sent at same time to all the users having the application role used in rules. Only one approval is enough for completion. A user may have to claim before providing approval.
Parallel
Chain/Serial
FYI Notifications will be sent at same time to all the users having the application role used in rules and no approval is required.
Approval Group Single Notifications will be sent at same time to all the users of approval group. Only one approval is enough for completion.  A user may have to claim before providing approval.
Parallel Notifications will be sent at same time to all the users of approval group. The number of approvals for completion depends on the voting percentage.
Chain/Serial Notification will be sent in sequential manner as setup in approval groups i.e. if approval group has user1 and user2 first notification will be sent to user1 and then to user 2. Approvals from all assignees are required for completion.
FYI Notifications will be sent at same time to all the users of approval group and no approval is required.
Supervisor Hierarchy

Position Hierarchy

Job Hierarchy

Single Notifications will be sent at same time to users part of hierarchy used in rules. Only one approval is enough for completion.  A user may have to claim before providing approval.
Parallel Notifications will be sent at same time to users part of hierarchy used in rules. The number of approvals for completion depends on the voting percentage.
Chain/Serial Notification will be sent in sequential manner as setup in hierarchy i.e. if hierarchy is user1 and user2 first notification will be sent to user1 and then to user 2. Approvals from all assignees are required for completion.
FYI Notifications will be sent at same time to users part of hierarchy and no approval is required.

Observations:

  • The behavior of single participant type is same irrespective of assignment type user, role etc… i.e. only one approval is required for completion. To verify this, do multiple user assignment for single participant type, run human workflow and query WFTASK table. Here we can observe that the ASSIGNEES column having all these users with ‘,’ as separator.
  • The behavior of using application role is same irrespective of participant type i.e. only one user can provide the approval having that application role.
  • To get Chain/Serial behavior we should always go for approval groups or hierarchies. In all other scenarios the serial participant behavior is same as parallel with 100% voting.

Branching in Native REST Services

In previous post, we are introduced to native REST services (Typed and Un-typed) support in 12.2.1. But we can observe following issues there:

  • We used only GET method for demonstration and typically this would not be the case as REST service can also support other HTTP methods (POST, PUT and DELETE).
  • No branching in Typed REST Services when multiple HTTP methods are supported.
  • No branching in Un-Typed REST Services when multiple HTTP methods are supported.

In this post, we will try to cover above aspects. Note that all of this discussion is related to native REST services unless stated otherwise.

Branching in Typed REST Services:

Add POST method support for typedEmployees resource as shown below.

typedbranch

typedbranch1

typedbranch2

typedbranch3

Since Typed REST Service uses WADL and contains Operation name annotated with soa:name, we can simply make use of Operational Branch.

opbranch 

You can use URL like below to access REST Service.

http://localhost:7003/restDemo/typedService/typedEmployees

Branching in Un-Typed REST Services:

Since Un-Typed REST services does not use WADL, we can’t use Operational Branch as above. So in this release, OSB introduced a new node called  REST Branch for this purpose.

restbrnch

Add REST Branch in pipeline by dragging it from Components.

rest1

For each REST branch, give supported Media Types, Resource Path and HTTP method mandatorily.

branch

Use + icon to add media types and give other information as shown below. This means we are creating a REST resource called  untypedEmployees which supports GET and supported media types are  application/xml, application/ json.

rest2

Modify REST branch name in General section of Properties. We can add more branches using highlighted icon below.

rest3

We can add POST method support for same resource path as shown below.

post

post1

post3

Test Proxy as shown below. Note that we had specified required parameters in HTTP headers.

test

test2

You can use URL like below to access this REST Service and make sure that Content-Type is passed without fail.

http://localhost:7003/restDemo/untypedService/untypedEmployees

Observations:

  • OSB parses payload based on  HTTP header Content-Type in request. We can Use Log activity to see $body contents. Refer  to this post to enable logging.
  • When Content-Type is application/xml, $body is logged as below.

PostPipelinePair, request-ab047b9.N47e0f03.0.15591b0ca2c.N7d1d, Stage1, REQUEST] CreateEmployeeLog: <soapenv:Body xmlns:soapenv="http://schemas. xmlsoap.org/soap/envelope/">[[<a><b>1233333</b></a></soapenv:Body>]]

  • When Content-Type is application/json, $body is logged as below.

[PostPipelinePair, request-ab047b9.N47e0f03.0.15591b0ca2c.N7d1d, Stage1, REQUEST] CreateEmployeeLog: <soapenv:Body xmlns:soapenv="http://schemas.xmlsoap.org/ soap/envelope/">{"a":1234,"b":3455}</soapenv:Body>

  • OSB binds a globally-scoped object called process and can be used as process.body or process.var which is similar to $body and $xyz XPath variables. This notation is used for Java Script expressions. Use Log activity as below in Java Script expressions to verify the same.

logjs

logjs1

logjs2

  • When Content-Type is application/xml, process.body is logged as below

[PostPipelinePair, request-ab047b9.N47e0f03.0.15591b0ca2c.N7d1d, Stage1, REQUEST] CreateEmployeeLog: <a>[[<b>1233333</b></a>]]

  • When Content-Type is application/json, process.body is logged as below

     [PostPipelinePair, request-ab047b9.N47e0f03.0.15591b0ca2c.N7d1d, Stage1, REQUEST]         CreateEmployeeLog: {"a":1234,"b":3455}

  • Though REST service supports JSON/XML payload, there is no automatic conversion takes place at runtime and to be done programmatically in native REST services.
  • When using End-to-End XML, use XQuery/XSLT for transformation.
  • When using End-to-End JSON, use Java script for transformation.

References:

https://docs.oracle.com/middleware/1221/osb/develop/GUID-FE2CAC5B-E4DF-49DE-AD3C-36EEAF750BFE.htm#OSBDV-GUID-BAE387C8-F1BE-49CF-8789-EFE220D216DB

Enabling Logging in Service Bus

To enable pipeline logging in Service Bus, steps remain same as below but the location where do we do this activity changed. The screenshots shown in this post

  • Enable logging in Global Settings
  • Enable logging at Pipeline level

Global Settings

Login to EM Console and navigate to SOA –> service-bus (Admin Server) as shown below.

gbtree

Click on Global Settings tab and set Logging Enabled property. We can also enable Monitoring, Alerts, Reporting and Result Cache as shown below.

osbglobal

Pipeline Settings

In EM Console, navigate to SOA –> service-bus –> <<Service Bus Project>>.

proxylog

Go to Operations tab and query for Pipelines. Here we can see all monitoring related properties for Pipelines.

proxylog1

Click on Pipeline and go to Properties tab to enable Logging as shown below. We can set other Monitoring and Tracing related properties as well. We can also set log level so that it will be shown in log files.

pplog

This logging information is shown in <<osbservername>>-diagnostic.log.

Another related blog entry: https://thecattlecrew.net/2015/12/23/oracle-soa-12c-quicktip-enable-servicebus-message-tracing-in-defaultdomain/

Service Bus 12.2.1 – REST Support

In this blog, we will review native REST service support added in 12.2.1. And you can refer to post to find information about same from 12.13 perspective.

Before discussing further, we will first see how 12.2.1 provides the backward compatibility with 12.1.3. In 12.1.3, REST Proxy Service converts native REST payload to SOAP before calling a Pipeline/Split-Join and REST Business Service convert SOAP to REST native payload i.e. the internal communication happen using WSDL interfaces only.

In 12.13, while creating REST binding as Proxy or Business service check the option as shown below and other steps remain same.

We can see WSDL and WADL gets created in your project.

wadl

req1

req2

To access REST resource use url like http://localhost:<<OSB Port>/<<proxy endpoint>>/<<resource name>>  so it will be http://localhost:7003/restDemo/REST1213WayPS/employees

To access design-time WADL use url like http://localhost:<<OSB Port>/sbresource?WADL/<>/<>  so it will be http://localhost:7003/sbresource?WADL/RESTIn1213way/WSDL/REST1213WayPS

To access effective WADL use url like http://localhost:<<OSB Port>/sbresource?(PROXY or BIZ)/<<project path>>/<<proxy or biz service name>>  so it will be http://localhost:7003/sbresource?PROXY/RESTIn1213way/ProxyServices/REST1213WayPS

Now in 12.2.1, we have native REST support and no need of creating WSDL for internal communication. This native support is broadly classified into following categories:

  • Un-typed Proxy/Business Service –  For which method information is available at design time so no WADL is involved.
  • Typed Proxy/Business Service – For which the method information is available at design time so WADL is used/created having this information.

REST binding can be used to create both Proxy and Business services that fall into above categories. In this post, we discuss from Proxy Service perspective and same can be followed for business services.

Creating Typed Proxy Service:

We use REST binding to create native REST service. So drag REST binding from Components to Proxy Services swim lane or right click to choose REST option.

typedbind1

Provide name for REST binding and do not select WSDL interfaces check box as we are creating native REST services. Click Next.

typed1

Create a new REST resource as shown below.

typedemp

typedemp2

Create a REST method using following steps by clicking + icon in Methods.

typedreq

typedresp

typedfinish

Now verify that WADL file is generated automatically with method information as defined above. Now create pipeline using the following steps.

typedpp

typedpp1

typedpp2

typedpp3

Connect Proxy Service, Pipeline and Business Service as shown below. Use the same business service as we used earlier.

sboverview

Finish the message flow as shown below.

ppmflow

routing

Deploy and test your project in Service Bus console. Observe that you can see all media types supported by REST service are shown in Accept choice list.

typedtestreq

typedtestresp

Now we will see how to use an existing WADL to create Typed REST services.

Again drag the REST binding from Components to Proxy Services swim lane or right click in swim lane to choose REST option.

untypedbind1

Provide name for REST binding and do not select WSDL interfaces check box as we are creating native REST services. Click Next.

typedproxy

Choose REST1213WayPS.wadl. This confirms that WADLs generated by 1213 REST services are supported here. Observe that REST methods are populated automatically from selected WADL.

typed

wadlselect

wadloper

Click Finish and verify that new WADL is generated again for this Proxy Service.

wadl

Now finish pipeline message flow as above using WADL created in above step.

typedexistingpp

sboverview1

To access REST resource use url http://localhost:7003/restDemo/typedService/typedEmployees

To access design-time WADL use url http://localhost:7003/sbresource?WADL/RESTTypedServices/TypedRestService

To access effective WADL use url http://localhost:7003/sbresource?PROXY/RESTTypedServices/TypedRestService

Observations:

  • WADL is always created for Typed native REST services when one is not chosen during creation.
  • No where we are able to give the input/output message structure (XML or JSON schema) for REST methods. I think this may be improved in later releases.
  • When a native REST Proxy Service supports multiple content types (XML, JSON), automatic payload conversion (XML to JSON and vice-versa) is not happening as we see in WSDL based REST services. I will try to cover more on this in later posts.
  • Content-Type HTTP header is used by OSB for content parsing and we can see this set automatically when media type is chosen in test console.
  • Value given for soa:name in WADL is populated for $operation context variable in pipeline.
  • 1213 WADL is not supported for creating pipelines but can be used to create Proxy, however a new WADL will be generated by OSB as we saw above.

Creating Un-typed Proxy Service:

Create a Proxy Service using following steps. Observe the usage of Transport and no where we define REST resource or methods.

untypedps

untypedps1

untypedps2

untypedps3

Create pipeline using following steps and observe that we are not selecting any WADL as we did earlier.

untypepp

untypedpp1

Connect all these pieces as shown below and complete Message Flow as we did earlier.

sboverview2

Deploy and test your project in Service Bus console. Observe that you can see all media types supported by REST service are shown in Media Type choice list as we have not specified supported types any where. Service Bus uses the Content-Type HTTP header for parsing the payload and you can see this is set automatically when we choose the media type in Test Console.

typedtest

untypedtestresp

To access REST resource use url http://localhost:7003/restDemo/untypedService

Observations:

  • No WADL is used during creation of Un-typed native REST services.
  • Again, no where we are able to give the input/output message structure (XML or JSON schema) for REST methods.
  • Again, no automatic payload conversion will happen when REST Proxy supports multiple Content Types.
  • Content-Type HTTP header is used by OSB for content parsing and we can see this set automatically when media type is chosen in test console.

In above 2 sections, we created  both Proxy and Pipeline separately and we can observe that WADL is optional for REST based pipelines. So even Pipelines are classified into Typed and Un-typed  depending on usage of WADL.

So now the Q arises about compatibility between Proxy and Pipelines as both of them can be Typed /Un-Typed. Since Typed is more restrictive having REST methods we will be able to call both Un-Typed and Typed pipelines provided they used same WADL. In the same way, Un-Typed will be able to call both Un-typed and Typed Pipelines.

The source code used in this post can be downloaded from here and please note that you need to create DB connection pool to run this project with JNDI eis/DB/LocalDB.

Reference:

https://docs.oracle.com/middleware/1221/osb/develop/GUID-C346DF7D-041D-4E10-BE1C-451F50719106.htm#OSBDV89235

FMW 12.2.1.1 is released !!!

FMW 12.2.1.1 was released last week and it seems to be a patch release for 12.2.1. Some quick links related to SOA are given below.

 

 

 

 

 


Advertisements

Pages

Enter your email address to subscribe to this blog and receive notifications of new posts by email.

Join 342 other followers

Enter your email address to follow this blog and receive notifications of new posts by email.