Create a processing information for business logical extension
/publisher/apiManagement/processingInformation/shoppingcartAdapter/shoppingCart/v4/schemas/oracle/buying/{component_name}
JavaScript Methods that need to be overriden in Processing Information
Method Name | Usage |
---|---|
handleTaskSplittingResult() | This is pre-processing method which gets executed before shoppingCart is created. This is callled "pre-processing" logic. |
handleSignal() | This is post-processing method which gets executed after shoppingCart is created.This is callled the functionality defined here the "post-processing" logic. |
Task Signals definations for ShoppingCart that need to be used in Processing Information
Task Signal Name | Usage |
---|---|
shoppingcart-pre-process | This signal name is used to read the ShoppingCartOracle object from shoppingcart service as pre processing payload before cart is created and business logical extensions applied on the payload and return ShoppingCartOracle object as response. |
shoppingcart-post-process | This signal name is used to read the ShoppingCartOracle object from shoppingcart service as post processing payload after cart is created and business logical extensions applied on the payload and return ShoppingCartOracle object as response. |
audit-info-signal-pre-process | This signal name is used to update the audit details inside Processing Information for pre-processing business logic and emit this task signal. |
audit-info-signal-post-process | This signal name is used to update the audit details inside Processing Information for post-processing business logic and emit this task signal. |
Status codes that need to be used in Processing Information
Status code | Usage |
---|---|
SUCCESS | This status code is used when successful response from spoke system. |
WARNING | This status code is used when error response from spoke system and still want to process the ShoppingCart and return error to user. |
FAILURE | This status code is used when successful response from spoke system and don't want to process the ShoppingCart and return error to user. |
Example-1:Basic Skeleton of the Processing Information JavaScript Code
import { MappingContext, SignalDefinition } from "src/it/resources/com/oracle/cx/sdk/providers/it/lib/oracle-builtins.mjs";
import { DataSignal, DIRECTION, ActionableDataSignal, SignalMetaMap, SPOKE_ID, ACTION } from "src/it/resources/com/oracle/cx/sdk/providers/it/lib/signals.mjs";
export const spokeDiscriminator = () => "oracle";
export const providedSignals = () => [];
export const handleSignal = async (payload, ctx, signalInfo) => {
}
export const handleTaskSplittingResult = async (requestJson, ctx, {apiName, apiVersion, pathId, requestHTTPMethod, sourcePropertyName}) => {
}
Example-2:Processing Information code sample calling with signals and calling external system Two signals in this example- callAddressValidation and addressValidateResponseSignal. The callAddressValidation signal is the outbound signal that will tell the framework to make the call to the address validation system. The first argument specifies the signal name as a string, which can be any value you want. It makes sense to give it an appropriate name for what the signal is doing, so in this case we name it "address-validate-request". The second argument is the HTTP method to be used for the request, in this case it is a POST. The third argument should always be DIRECTION.FROM_MODEL. The framework derives the baseURL of the call from the 4th argument, which is pre-registered with the framework. The fifth argument is where you specify the name of the response signal. As mentioned previously, the calls are happening asynchronously, so once a signal is fired, we have to explicitly wait for the framework to come back with a response in the form of another signal (which carries the response data and metadata from the API we are calling).
import { MappingContext, SignalDefinition } from "src/it/resources/com/oracle/cx/sdk/providers/it/lib/oracle-builtins.mjs";
import { DataSignal, DIRECTION, ActionableDataSignal, SignalMetaMap, SPOKE_ID, ACTION } from "src/it/resources/com/oracle/cx/sdk/providers/it/lib/signals.mjs";
export const spokeDiscriminator = () => "oracle";
let addressValidateResponseSignal = new DataSignal("address-validate-reply", DIRECTION.FROM_MODEL);
let callAddressValidation = new ActionableDataSignal("address-validate-request", ACTION.POST, DIRECTION.FROM_MODEL, SPOKE_ID.RMS_SPOKE_ID, "address-validate-reply");
export const providedSignals = () => [callAddressValidation];
Example-3:Processing Information code sample calling with signals and calling external system To actually fire the signal (and therefor call the desired API), we can do so by following these steps-
1.Create a signal metamap. This will contain necessary meta information about the signal to make the call to the API.
2.Add the API path to the signal metamap.
3.Emit the signal, possibly containing the payload if it is a POST or PATCH to the desired API. The emit signal method takes a map that is expected to have 3 keys-
a.signalName - string value of the outbound signal we have defined
b.signalValue - the payload (if any) which we want to send to the external system. For a POST and PATCH, it cannot be null. For a GET, it must be null.
c.signalMetaMap - signal metamap containing meta information about the call to make, like the API path to add onto the registered base path.
4.Wait for the reply signal if you need to access something about the response, whether it be the response's payload or response's HTTP status code. We wait for the response signal by calling ctx.dependOn, and since it is an asynchronous call that returns a promise, we need to add "await" in front of it to wait for the response. The value we get back is an object that has the fields "payload" and "meta" present, among others. "payload" is the response payload, and "meta" is an object containing information about the network call that took place, like the response time, status code, URL called, etc.
/* * Copyright (c) 2020, 2022, Oracle and/or its affiliates. */ import {MappingContext, SignalDefinition} from "src/it/resources/com/oracle/cx/sdk/providers/it/lib/oracle-builtins.mjs"; import { DataSignal, DIRECTION, ActionableDataSignal, SignalMetaMap, SPOKE_ID, ACTION } from "src/it/resources/com/oracle/cx/sdk/providers/it/lib/signals.mjs";
export const spokeDiscriminator = () => "oracle";
let addressValidateResponseSignal = new DataSignal("address-validate-reply", DIRECTION.FROM_MODEL);
let callAddressValidation = new ActionableDataSignal("address-validate-request", ACTION.POST, DIRECTION.FROM_MODEL, SPOKE_ID.RMS_SPOKE_ID, "address-validate-reply");
export const providedSignals = () => [callAddressValidation];
export const handleSignal = async (payload, ctx, signalInfo) => {
} /** * * @param requestJson {ITObject} the request object acting as input * @param ctx {MappingContext} the mapping context */ export const handleTaskSplittingResult = async (requestJson, ctx) => { console.log("In pre processing logic in PI"); let shoppingCart = ctx.workOnTaskSignalPayload("shoppingcart-pre-process");
const validateAddressMetaMap = ctx.createMeta(); validateAddressMetaMap.apiPath = "/api/shoppingCart/v4/validateBillingAddress";
for (let cartItemIndex in shoppingCart.cartItem) { let cartItem = shoppingCart.cartItem[cartItemIndex]; let addressToValidate = cartItem.shippingAddress;
//call spoke system ctx.emitSignal({ signalName:"address-validate-request", //based on signal name, the EDK knows which system to go to signalValue:addressToValidate, signalMetaMap:validateAddressMetaMap });
//wait for reply from spoke system let validateAddressResponse = await ctx.dependOn("address-validate-reply", undefined, false); let responsePayload = JSON.stringify(validateAddressResponse.payload()); let responseMeta = JSON.stringify(validateAddressResponse.meta()); } }
Example-4:Helper function for audit logging for pre and post processing.
export const sendSpokeResponseInfo = async (spokeCallResponseBody, spokeCallResponseMeta, signalName, ctx, successValue) => { console.log("Sending audit info for signal " + signalName);
//we have to emit a signal that is a regular json obj, not a SignalMetaMap obj type let metaObj = JSON.parse(JSON.stringify(spokeCallResponseMeta)); let payloadObjStr = JSON.stringify(spokeCallResponseBody); let auditInfoObj = {}; auditInfoObj['meta'] = metaObj; auditInfoObj['responsePayload'] = payloadObjStr; auditInfoObj['status'] = successValue;
let meta = ctx.createMeta(); ctx.emitSignal({ signalName:signalName, signalValue:auditInfoObj, signalMetaMap:meta, signalScope:"audit" }); }
Example-5:Complete flow example with Signals and Status and Audit information calls taking Address Vaidation use case with simulator.
import {MappingContext, SignalDefinition} from "src/it/resources/com/oracle/cx/sdk/providers/it/lib/oracle-builtins.mjs"; import { DataSignal, DIRECTION, ActionableDataSignal, SignalMetaMap, SPOKE_ID, ACTION } from "src/it/resources/com/oracle/cx/sdk/providers/it/lib/signals.mjs";
export const spokeDiscriminator = () => "oracle";
let addressValidateResponseSignal = new DataSignal("address-validate-reply", DIRECTION.FROM_MODEL);
let callAddressValidation = new ActionableDataSignal("address-validate-request", ACTION.POST, DIRECTION.FROM_MODEL, SPOKE_ID.RMS_SPOKE_ID, "address-validate-reply");
export const providedSignals = () => [callAddressValidation];
export const handleSignal = async (payload, ctx, signalInfo) => {
} /** * * @param requestJson {ITObject} the request object acting as input * @param ctx {MappingContext} the mapping context */ export const handleTaskSplittingResult = async (requestJson, ctx) => { try { console.log("In pre processing logic in PI"); let shoppingCart = ctx.workOnTaskSignalPayload("shoppingcart-pre-process"); const validateAddressMetaMap = ctx.createMeta(); validateAddressMetaMap.apiPath = "/api/shoppingCart/v4/validateBillingAddress";
for (let cartItemIndex in shoppingCart.cartItem) { let cartItem = shoppingCart.cartItem[cartItemIndex]; let addressToValidate = cartItem.shippingAddress; //call spoke system ctx.emitSignal({ signalName:"address-validate-request", //based on signal name, the EDK knows which system to go to signalValue:addressToValidate, signalMetaMap:validateAddressMetaMap });
//wait for reply from spoke system let validateAddressResponse = await ctx.dependOn("address-validate-reply", undefined, false); let responsePayload = JSON.stringify(validateAddressResponse.payload()); let responseMeta = JSON.stringify(validateAddressResponse.meta()); if (validateAddressResponse.meta().error != null) { console.log("Error calling the address validation system"); sendSpokeResponseInfo(validateAddressResponse.payload(), validateAddressResponse.meta(), "audit-info-signal-pre-process", ctx, "FAILURE"); } else { console.log("Successfully called the address validation system"); sendSpokeResponseInfo(validateAddressResponse.payload(), validateAddressResponse.meta(), "audit-info-signal-pre-process", ctx, "SUCCESS"); }
}
} catch (e) { console.log("Error encountered in PI."); console.log(e.stack); console.log(e.name); console.log(e.message); } }
export const sendSpokeResponseInfo = async (spokeCallResponseBody, spokeCallResponseMeta, signalName, ctx, successValue) => { console.log("Sending audit info for signal " + signalName);
//we have to emit a signal that is a regular json obj, not a SignalMetaMap obj type let metaObj = JSON.parse(JSON.stringify(spokeCallResponseMeta)); let payloadObjStr = JSON.stringify(spokeCallResponseBody); let auditInfoObj = {}; auditInfoObj['meta'] = metaObj; auditInfoObj['responsePayload'] = payloadObjStr; auditInfoObj['status'] = successValue; let meta = ctx.createMeta(); ctx.emitSignal({ signalName:signalName, signalValue:auditInfoObj, signalMetaMap:meta, signalScope:"audit" }); }
Request
-
component_name(required): string
Identifier of the TMF Component
- application/javascript;charset=utf-8
-
oAuth2AuthCodeForSupportSpecialistRole: oauth2
Type:
oauth2
Description:The DX4C BuyingX Rest APIs are protected with OAuth2.0 Token-based Authentication and Role-based Authorization. The Roles are segregated based on different sets of Rest APIs. This OAuth2 Security scheme represents the below Role. This scheme is added to all the required Rest end-points protected by the below role. <ul> <li><b>Support Specialist</b> : Grants full access to BuyingX Runtime Rest APIs in the context of an Agent</li> </ul>
Response
- application/json;charset=utf-8
201 Response
400 Response
"code" "CXI-BUY-0022", "reason" "Invalid body", "message" "Action specified on the cart items [cartItem[0]] is either empty or not one of the supported types. "
object
-
@baseType: string
When sub-classing, this defines the super-class.
-
@schemaLocation: string
(uri)
A URI to a JSON-Schema file that defines additional attributes and relationships
-
@type: string
When sub-classing, this defines the sub-class entity name.
-
code(required): string
Application relevant detail, defined in the API or a common list.
-
message: string
More details and corrective actions related to the error which can be shown to a client user.
-
reason(required): string
Explanation of the reason for the error which can be shown to a client user.
-
referenceError: string
(uri)
URI of documentation describing the error.
-
status: string
HTTP Error code extension
401 Response
object
-
@baseType: string
When sub-classing, this defines the super-class.
-
@schemaLocation: string
(uri)
A URI to a JSON-Schema file that defines additional attributes and relationships
-
@type: string
When sub-classing, this defines the sub-class entity name.
-
code(required): string
Application relevant detail, defined in the API or a common list.
-
message: string
More details and corrective actions related to the error which can be shown to a client user.
-
reason(required): string
Explanation of the reason for the error which can be shown to a client user.
-
referenceError: string
(uri)
URI of documentation describing the error.
-
status: string
HTTP Error code extension
403 Response
object
-
@baseType: string
When sub-classing, this defines the super-class.
-
@schemaLocation: string
(uri)
A URI to a JSON-Schema file that defines additional attributes and relationships
-
@type: string
When sub-classing, this defines the sub-class entity name.
-
code(required): string
Application relevant detail, defined in the API or a common list.
-
message: string
More details and corrective actions related to the error which can be shown to a client user.
-
reason(required): string
Explanation of the reason for the error which can be shown to a client user.
-
referenceError: string
(uri)
URI of documentation describing the error.
-
status: string
HTTP Error code extension
405 Response
object
-
@baseType: string
When sub-classing, this defines the super-class.
-
@schemaLocation: string
(uri)
A URI to a JSON-Schema file that defines additional attributes and relationships
-
@type: string
When sub-classing, this defines the sub-class entity name.
-
code(required): string
Application relevant detail, defined in the API or a common list.
-
message: string
More details and corrective actions related to the error which can be shown to a client user.
-
reason(required): string
Explanation of the reason for the error which can be shown to a client user.
-
referenceError: string
(uri)
URI of documentation describing the error.
-
status: string
HTTP Error code extension
409 Response
object
-
@baseType: string
When sub-classing, this defines the super-class.
-
@schemaLocation: string
(uri)
A URI to a JSON-Schema file that defines additional attributes and relationships
-
@type: string
When sub-classing, this defines the sub-class entity name.
-
code(required): string
Application relevant detail, defined in the API or a common list.
-
message: string
More details and corrective actions related to the error which can be shown to a client user.
-
reason(required): string
Explanation of the reason for the error which can be shown to a client user.
-
referenceError: string
(uri)
URI of documentation describing the error.
-
status: string
HTTP Error code extension
500 Response
"code" "CXI-BUY-0001",
"reason" "Internal Server Error"
object
-
@baseType: string
When sub-classing, this defines the super-class.
-
@schemaLocation: string
(uri)
A URI to a JSON-Schema file that defines additional attributes and relationships
-
@type: string
When sub-classing, this defines the sub-class entity name.
-
code(required): string
Application relevant detail, defined in the API or a common list.
-
message: string
More details and corrective actions related to the error which can be shown to a client user.
-
reason(required): string
Explanation of the reason for the error which can be shown to a client user.
-
referenceError: string
(uri)
URI of documentation describing the error.
-
status: string
HTTP Error code extension