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 | ||||||||
---|---|---|---|---|---|---|---|---|
|
But supporting multiple outputs from a state -
Jira | ||||||||
---|---|---|---|---|---|---|---|---|
|
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 | ||
---|---|---|
| ||
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 | ||
---|---|---|
| ||
task create name=ApexExample_HandleAAISuccessResponseTask
task contextref create name=ApexExample_HandleAAISuccessResponseTask albumName=ApexExample_EventDetailsAlbum
task logic create name=ApexExample_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 | ||
---|---|---|
| ||
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 | ||
---|---|---|
| ||
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
With all these changes implemented, there will be 1 change required in all the existing policies 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 - even this change can be avoided if needed by simply logging a warning message and not actually use the fields definition at the task level.