Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Currently in APEX-PDP, there can only be 1 single output from a task and a state. But, there can be different use cases which require different outputs  from a state.

A typical use case would be to send log events to DMaaP/Kafka topic along with any action taken, say AAI/CDS call. 

Jira Legacy
serverSystem Jira
columnskey,summary,type,created,updated,due,assignee,reporter,priority,status,resolution
serverId4733707d-2057-3a0f-ae5e-4fd8aff50176
keyPOLICY-3324
was actually  created to support this.

But supporting multiple outputs from a state -

Jira Legacy
serverSystem Jira
columnskey,summary,type,created,updated,due,assignee,reporter,priority,status,resolution
serverId4733707d-2057-3a0f-ae5e-4fd8aff50176
keyPOLICY-3336
can be considered as more generic APEX solution compared to implementing a utility method for specifically sending an event to DMaaP/Kafka.


Solution

The solution is to allow multiple output events from a State only when that state is the final state and there are no next states to it, because multiple output events makes more sense at Apex Policy concept level.

When there are next states, or in case of task selection logic or state finalizer logic, there will still be only 1 event output from the current state.


Steps

1. Fix the way tasks are defined

Tasks currently take 1 input event and produce 1 output event which is then consumed by its state. The fields expected in the input event and output event are defined in the command file (.apex file).

For example:

Code Block
languageyml
task create name=HandleAAISuccessResponseTask
task inputfield create name=HandleAAISuccessResponseTask fieldName=vnf-id schemaName=SimpleStringType
task inputfield create name=HandleAAISuccessResponseTask fieldName=vnf-name schemaName=SimpleStringType
task inputfield create name=HandleAAISuccessResponseTask fieldName=vnf-type schemaName=SimpleStringType
task inputfield create name=HandleAAISuccessResponseTask fieldName=service-id schemaName=SimpleStringType
task inputfield create name=HandleAAISuccessResponseTask fieldName=prov-status schemaName=SimpleStringType
task inputfield create name=HandleAAISuccessResponseTask fieldName=orchestration-status schemaName=SimpleStringType
task inputfield create name=HandleAAISuccessResponseTask fieldName=in-maint schemaName=SimpleBooleanType
task inputfield create name=HandleAAISuccessResponseTask fieldName=is-closed-loop-disabled schemaName=SimpleBooleanType
task inputfield create name=HandleAAISuccessResponseTask fieldName=resource-version schemaName=SimpleStringType
task inputfield create name=HandleAAISuccessResponseTask fieldName=model-invariant-id schemaName=SimpleStringType
task inputfield create name=HandleAAISuccessResponseTask fieldName=model-version-id schemaName=SimpleStringType
task inputfield create name=HandleAAISuccessResponseTask fieldName=model-customization-id schemaName=SimpleStringType
task inputfield create name=HandleAAISuccessResponseTask fieldName=relationship-list schemaName=VnfRelationShipListType
task outputfield create name=HandleAAISuccessResponseTask fieldName=commonHeader schemaName=CDSRequestCommonHeaderType
task outputfield create name=HandleAAISuccessResponseTask fieldName=actionIdentifiers schemaName=CDSActionIdentifiersType
task outputfield create name=HandleAAISuccessResponseTask fieldName=payload schemaName=CDSRequestPayloadType
task contextref create name=HandleAAISuccessResponseTask albumName=EventDetailsAlbum
task logic create name=HandleAAISuccessResponseTask logicFlavour=JAVASCRIPT logic=LS
#MACROFILE:"src/main/resources/logic/HandleAAISuccessResponseTask.js"
LE


A lot of this task definition contains redundant information and can be cleaned up, as the inputfields and outputfields are already defined as part of the event definition.

After cleanup:

Code Block
languageyml
task create name=HandleAAISuccessResponseTask
task contextref create name=HandleAAISuccessResponseTask albumName=EventDetailsAlbum
task logic create name=HandleAAISuccessResponseTask logicFlavour=JAVASCRIPT logic=LS
#MACROFILE:"src/main/resources/logic/HandleAAISuccessResponseTask.js"
LE

Input event(single trigger event) and output events(multiple output events from a final state - if this gets implemented) can be populated to a task as part of the policy/state definition because the event tagging is done there anyway.


2. Change the state output definition to support multiple outgoing events, and make all the related changes

Once the task definition is simplified, and refactored to support multiple outputs, the state output definitions can also be changed to support multiple outgoing events.

From a policy author point of view, the change to support multiple output events will look something like this:

Code Block
languageyml
policy state output create name=AAISuccessResponseHandlerPolicy stateName=ReceiveAAISuccessResponseState outputName=AAISuccessStateOutput eventName=CDSConfigModifyRequestEvent nextState=NULL
policy state output create name=AAISuccessResponseHandlerPolicy stateName=ReceiveAAISuccessResponseState outputName=AAISuccessStateOutput eventName=LogEvent nextState=NULL

In the above example, ReceiveAAISuccessResponseState is the final state in AAISuccessResponseHandlerPolicy, and the state will have 2 outgoing events as part of the state output - CDSConfigModifyRequestEvent  and LogEvent


3. Updates to TaskLogic

With these changes, if multiple output events are expected from a task, then they can be populated in the logic.

For example:

Code Block
languagejs
var event1Fieldsmap = java.util.HashMap();
event1Fieldsmap.put("event1field", "val");

var event2Fieldsmap = java.util.HashMap();
event2Fieldsmap.put("event2field", "val");

executor.addFieldsToOutputList(event1Fieldsmap);
executor.addFieldsToOutputList(event2Fieldsmap);

A simple utility method "addFieldsToOutputList" can be added to TaskExecutionContext that matches the fields to the right event and updates its values.

If the use case doesn't really need multiple event outputs, then the policy author could go with either the above option - by adding only a single event's fields, or simple use the existing way - "executor.outfields.put(.......)"


Backward compatibility

For the upcoming release, the implementation will be backward compatible. But the inputfields and outputfields in the task definition will be deprecated simply ignored with a warning message.

In later releases, these fields will be competely removed. So to avoid breakage, cleanup the task definition as mentioned in step 1

Simply removing the inputfields and outputfields from the task definition should make everything else working as usual.