Sunday, September 15, 2024

Oracle Integration Gen2 PCS to Gen3 OPA Upgrade: Part 7

In series of articles, I discuss some challenges you may face when upgrading Oracle Integration Gen2 (OIC 2) Process (PCS) to Gen3 (OIC 3) Oracle Process Automation (OPA) applications. In this episode I discuss a challenge you may face with task assignment to an individual (instead of the default role assignment) when migrating from Oracle OIC 2 Process (PCS) to OIC 3 Oracle Process Automation (OPA). The previous article can be found here.

Disclaimer: The below provides a snapshot at the time of writing. Things may have changed by the time you read it. It is also important to mention that this does not necessarily represent the view of Oracle.

In the following example I have 2 Human Tasks, of which 1 is assigned based on the swimlane, and the other by assigning it to a specific person:



The first task has assignment set to “Any member of current swimlane role”:


 

And the other has it set to some task payload element, which is TaskAssignmentForm.processRequest.id:


 

When running this process, in Workspace you can see the first being assigned to the process-specific role, which is SMP Task Assignment.ProcessOwner. The “(R)” at the end confirms the assignment is role-based:

 

The second task is assigned to me directly:



The Challenge

I can import, validate and activate the process without issues. Looking at the properties all looks good for the first task:


 

And the second one:


 


When running the process, the first task is assigned to the swimlane role, as it was for PCS:


However, the second one runs into an error


The message points out that the element with name input_taskAssignmentForm cannot be resolved.

On closer inspection of the design-time task assignment you can see it has been migrated to use input.TaskAssignmentForm.processRequest.id, which as such looks OK as it basically is the same element as it was for PCS:


 


However, the issue is that on assignment this element is not initiated yet. So, practically speaking this is a kind-of NullPointerException.


The Remedy

The resolution is quite simple, I should use an expression pointing to an element of the process payload itself instead, which in my case is called taskAssignmentFormDataObject:


 

When I now run the process, also the second task is assigned properly:


 

Note: in PCS you don’t have access to the process payload in the task assignment expression editor. So, there is no way I could have prevented this issue in PCS already.


Previous articles on the subject:

Wednesday, September 11, 2024

Oracle Integration Gen2 PCS to Gen3 OPA Upgrade: Part 6

In series of articles, I discuss some challenges you may face when upgrading Oracle Integration Gen2 (OIC 2) Process (PCS) to Gen3 (OIC 3) Oracle Process Automation (OPA) applications. In this episode I add to and partly correct the previous one where I talked about the correlation challenge. I also discuss challenges with the interface of the Message Start. The previous article can be found here.

Disclaimer: The below provides a snapshot at the time of writing. Things may have changed by the time you read it. It is also important to mention that this does not necessarily represent the view of Oracle.

For PCS to OPA migration you are also referred to the following:


Process Receive Interface

Last time I discussed how correlation of inter-process calls with a Send-Receive combination only works when you use a separate, simple type argument to correlate on.

As it turns out, for a Send-Receive combination the Receive does not support exposing an interface based on a (complex) Business Type at all. So, what I missed the previous time is that with a complex type argument the mapping failed completely as none of the request elements were mapped. The following explains the challenge in detail as well as the remedy.

In in the following example, I have a simple PCS process with a complex Business Type.

The following first (parent) process has a Send - Receive combination which is calling the second (child) process that has a Message Start and which does a call back to the first by means of a Send activity.

 


The Receive of the first process exposes an interface based on the Complex Type, which I can map 1:1. As explained in the previous article, correlation happens based on the person.id element.

In PCS this all works just fine.

The Challenge

I can import and activate the process in OPA without getting a validation error. Already knowing that correlation only works when I have a simple type id in the payload, I already fixed that. However, when I run the process the mapping of the Receive fails "silently" meaning I don’t get a runtime error, but instead of mapping the approvedPerson input argument back to the person data object, it has mapped what appears to be (part of) the JSON schema of the input argument. This is what I literally get back from the mapping:

{number=false, boolean=false, null=false, string=false, array=false, dataFormatName=application/json, nodeType=OBJECT, value=false, object=true}

For most processes this probably makes it fail in the next step as the business object got corrupted, but you only find out runtime.

The Remedy

The remedy basically is the same as for the correlation challenge: use root-level, simple types. Meaning, that you must create an interface where each data element to pass on, is at the root-level:

 

And (obviously) you must map each element individually in both the Send back to the child process as well as in the Receive of the parent:

 

Message Start Interface

All PCS Structured Processes I have designed with a Message Start use a complex Business Type. Main reason being that for PCS this can make the input mapping easier, as it supports mapping of the parent element only, which makes it simple and prevents the need to cater for empty elements. 

I also normalize the data structure. For example, instead of having a flattened data structure with top-level elements name, streetName, houseNumber, postalCode and city, I have an interface with at top-level name and address, and then streetName, etc. as child elements of the address element based on a separate Address Business Type. This does not only help to better understand the structure and usage of the interface, but also makes it more resilient to change. 

For example, to add a correspondence address, I can easily reuse the Address Business Type to add a correspondenceAddress next to address (instead of having to work around it by adding correspondenceStreetName, etc.

The Challenge

Currently, OPA only supports a Message Start with either simple type, root-level arguments or based on a complex Business Type of 1 level deep. So, in the example mentioned before I still must use top-level elements for streetName, and all the others including the array.

The following shows the interface of a dummy application I created in PCS and then migrated to OPA to verify that indeed the results I had with a real-live migrated application was caused by this.

First, I tried with a more complex type having a sub-element based on a SubType Business Type of 2 elements, and another sub-element that is an array of a Project Business Type with 1 element.


When I try to start an instance of this process using this request:

{
  "params": {
    "applicationName": "SMPMessageStartComplexRequest",
    "processName": "SMPMessageStartComplexRequest"
  },
  "dataObject": {
    "complexTypeIn": {
      "name": "john",
      "subType": {
        "approve": "yes",
        "reject": "no"
      },
      "projects": [
        {
          "projectNumber": "1"
        },
        {
          "projectNumber": "2"
        }
      ]
    }
  }
}

The result is an empty mapping:

 

The Remedy

The challenge can be remedied by flattening the request so that the approve and reject elements are at the same level as name as is the list with projects.


When I start an instance of this, using the request:

{
  "params": {
    "applicationName": "SMPMessageStartComplexRequest",
    "processName": "SMPMessageStartSimpleRequest"
  },
  "dataObject": {
    "nameIn" : "John",
    "simpleTypeIn": {
      "approve": "yes",
      "reject": "no"
    },
    "projectsIn": [
      {
        "projectNumber": "1"
      },
      {
        "projectNumber": "2"
      }
    ]
  }
}

The result is as I would expect it to be:





Of course, internally I can map the individual input arguments to a data objects that is based on the complex Business Type.

Next articles on the subject:

Previous articles on the subject: