Support multiple outputs from a state in APEX-PDP

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. POLICY-3324: Design a solution for sending notifications to Kafka & Rest in apex-pdp policiesClosedwas actually  created to support this.

But supporting multiple outputs from a state - POLICY-3336: APEX CLI/Model: multiple outputs for nextState NULLClosedcan 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:

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:

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:

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:

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.