8 Source/Target Mapping
Launch Integration uses a mapping service which enables you to create proxy API that can pull data into Launch and push data into external applications. The mapping service also allows customers to modify the seeded mapping rules using extensions. For more information, see "Handling Extensions".
API Mapping
The API mapping enables you to create a proxy API that can map APIs between the source and target systems.
- Source API Mapping
- Target API Mapping
Source mapping allows you to orchestrate calling APIs on a source system and then map them to a set of target APIs. In case of publishing, the source is Launch and target is the external application and is vice versa in the case of migration.
Refer to respective OAS to understand more on the APIs.
Data Mapping
Data mapping enables you to create mappings between the target API schema and the logical source schema created using the source API Mapping. The mapping is done using JSON path expressions. The framework provides additional functions to simplify complex mapping that can't be supported using the JSON path.
You can use these built-in functions to map third-party catalog consuming apps using the supported functions and application constants.
Supported Functions
Table 8-1 lists the functions available for use in the data transformation, refer to the description column to understand the use of a function.
Table 8-1 Supported Functions
Function Name | Signature | Description |
---|---|---|
@toUpper |
@toUpper(json path) |
Converts data to upper case. |
@toDataType |
@toDataType(value json path, data type json path, boolean true value, boolean false value) |
Converts data to data type if the source data doesn't conform to the given data type or uses custom data type |
@toFlatten |
@toFlatten(source json path, relative depth json path) |
Flattens an object or array to the given depth. |
@indexOf |
@indexOf(array json path) |
Returns index of an array element. |
@replaceValue |
@replaceValue(jsonPath/ function/default constants, header key) |
Uses header value passed in the request. The name of the parameters should be in this form - User- Project-Name. The first letter and the subsequent letters after hyphen(-) must be capitalized. Examples: @replaceValue($,User- Project-Id) # correct @replaceValue($,User-Project- Name) # correct @replaceValue($,user-project-name) # Incorrect |
@invokeRest |
@invokeRest(function name, argument list...) |
Tenant implements end point and configures it in the Industry Framework. |
@valueMap |
@valueMap(condition json path/function, default, json path/function, source, target) |
Maps the value found at the third argument using a variable number of source/target values. Keep in mind that when the target field uses an Open API type of "oneOf": [...], this function will not be able to cast mapped values to types unless the target type is declared with an explicit Open API "type" instead of "oneOf". |
@conditionValueMap |
@conditionValueMap (json path/function, default, trueValue, falseValue) |
Returns trueVal if the first argument resolves to anything non- null that is not an empty list. Returns falseValue if the first argument resolves to an empty list. Returns the default value if the first argument resolves to null. |
@defaultValue |
@defaultValue (json path/function, default value) |
Returns the value found after evaluating the first argument. Returns the default value if the first argument is null. |
@distinctValues |
@distinctValues(json path array, arg1, arg2, ...) |
Returns the distinct values based on the parameter passed. The first argument should return an array. The other arguments contain fields that are used to find distinct elements. |
@alterValue |
@alterValue(condition json path, json path or value, mathematical operator, json path or value, precision(optional), rounding mode(optional)) |
It performs a mathematical operation on its operands and produces a number according to the specified precision and rounding mode. |
@toArrayLength |
@toArrayLength(condition json path, json path or function) |
It calculates the length of an array and produces a number according to that. |
@concatValues |
@concatValues(condition, arg1, arg2, ...) |
Returns the concatenated string based on the parameters passed. The 1st argument (function or JSON path) is a condition. If the first argument evaluates to not null, then the function will return the concatenated value else it will return null. |
@compareValue |
@compareValue(condition json path, json path or value or header param or query param, relational operator, json path or value, dataType optional) |
It compares the left and right operands using the relational operators like (<,>,<=,>=,==,!=), based upon the dataType mentioned and returns a Boolean value as result. |
@conditionalConvertValue |
@conditionalConvertValue(conditionJson Path, jsonPath, regex, index, case identifier) |
This function is used to split and convert the case of an input text passed in its 2nd arg to the user requested case passed in 3rd arg, 4th arg, and 5th arg. |
@convertCase |
@convertCase(condition json path/function, json path/function/constants, case identifier) |
This function is used to split and convert the case of an input text passed in its2nd arg to the user requested case passed in 3rd arg. |
@dateConverter |
@dateConverter(condition 'json path',date 'json path', default date(optional), source date format(optional), target date format(optional)) |
Based on the condition, it converts date from source format to target format if provided or uses default date format. If the date resolves to null and then returns default date converted in target format, if default date is also null then returns null. |
@evaluateDataType |
@evaluateDataType( jsonPath, dataType, format Optional) |
It checks if the value of that jsonPath returns the specified data type or not. In case of date format has to be passed. |
@filterArray |
@filterArray(conditionalJsonPath, filteredArrayJsonPath, minLengthForComparing, operator, additionalCondition) |
Filter the array based on the condition provided. |
@getArrayElementByIndex |
@getArrayElementByIndex(condition json path or function, json path or function, integer constant or json path or function returning integer index) |
It returns an array element present at specified index passed in 3rd argument. |
@getFilteredArrayElement |
@getFilteredArrayElement(condition,jsonpath, filterCriteria, index, fieldsJsonpath) |
Based on the condition, it substitutes the search string with replace string in the data and returns the transformed data. |
@infixToPrefix |
@infixToPrefix($, $.['stringExpression'], operator_map('REQU IRES','req','NOT','!'), type_map('REQUIRE S','binary','!','unary'), operand_map(), exp_json_path($.id, productId), apply_Siebel_Format (true)) |
This function is used to convert infix expression to its prefix form. |
@objectToStringExp |
@objectToStringExp (jsonPath, keyValueSep, fieldSep, mode, [replaceString], [enclosedBy]) |
Function to convert a json object to a string, with the ability to ignore empty fields and separate fields, values, and field-value pairs, as well as wrap each field value pair with a string. |
@prefixToInfix |
@prefixToInfix(condition json path, json path, source_system_siebel (true/false), operator_map('source-system- operator','eqv- target-system- operator', ….…. ),type _map('source- system- operator','operator- type', ….... ),operand _map('custom- source-system- operand','regex-exp-to-be-used or way to resolve custom operand in target system', ….... ),exp_json_path(entity(entity _Type_Identifier_In_ Target_System, JsonPath to identify ID in stitched payload), ... )) |
This function is used to convert prefix expression to infix expression. |
@splitString |
@splitString(conditionJsonPath, jsonPath, regex, defaultValue, index) |
It splits any string based on a regex and returns list of values if no index given in the argument else returns that specific value based on the index mentioned in the argument. |
@substituteValues |
@substituteValues(condition 'json path or function', data 'json path or value or function' , search string 'json path or value or function' , replace string 'json path or value or function', ….…....) |
Based on the condition, it substitutes the search string with replace string in the data and returns the transformed data. |
Supported Application Constants
Table 8-2 lists the application constants available for use in data transformation, refer to the description column to understand the use of respective application constants.
Table 8-2 Supported Application Constants
Name | Sample Payload | Description |
---|---|---|
@jobId |
|
The current job ID. |
@applicationName |
|
Returns the name of the source system. |
@epochTime |
|
Returns the epoch time based on system time. |
@recordNum |
|
Returns the number of records when the JSON path returns multiple objects in API map. |
@replace(key) |
|
Replaces a value from given header key. |
@pathParam(key) |
|
Used in query map to pass value for a path parameter key. |
Supported Templates
The API configuration allows you to define template files for the source API calls. They are configured as part of the mapping file definition.
Templates used by Siebel CRM
Table 8-3 lists template files that are referenced by the source API configuration during the migration event.
Table 8-3 Templates used by Siebel CRM
Template | Description |
---|---|
catalogPOSTTemplate.json |
Used to retrieve catalog from Siebel. |
attributePOSTTemplate.json |
Used to retrieve attributes from Siebel. |
classPOSTTemplate.json |
Used to retrieve product class from Siebel. |
plPOSTTemplate.json |
Used to retrieve product lines from Siebel. |
productPOSTTemplate.json |
Used to retrieve product from Siebel. |
promotionPOSTTemplate.json |
Used to retrieve promotion from Siebel. |
skuPOSTTemplate.json |
Used to retrieve Smart Part Number from Siebel. |
adjustmentGroupPOSTTemplate.json |
Used to get Product-Based Adjustment for discount matrices from Siebel. |
bulkPromotionPostTemplate.json |
Used to get bulk of promotions from Siebel. |
productComponentsPOSTTemplate.json |
Used to get the CP full structure from Siebel. |
recommendationRulePOSTTemplate.json |
Used to get recommendation rules from Siebel. |
promotionPostIdsTemplate.json |
Used during nested job processing for Siebel promotion. |
ProductPostIdsTemplate.json |
Used during nested job processing for Siebel products. |
Table 8-4 Templates used by Siebel CRM
Template | Description |
---|---|
catalogIDTTemplate.json |
Used to retrieve Catalog ID from Siebel. |
productClassIDTemplate.json |
Used to retrieve Product Class ID from Siebel. |
productLineIDTemplate.json |
Used to retrieve Product Line ID from Siebel. |
productIDTemplate.json |
Used to retrieve Product ID and Promotion ID from Siebel. |
Managing Mapping File Versions
- One-time migration: the siebel_launch.json file that contains the mapping with source as Siebel and target as Launch.
- Publish to Siebel: the launch_siebel.json file that contains the mapping with source as Launch and target as Siebel.
GET - {{APIGW}}/mappingSchema/cx/industry/apiIntegration/v1/mappingSchema
Headers to be passed:
Source System <<SourceName>>
X-Destination-System <<DestinationName>>
Any additional extensions that you need to bring into the mapping is done using the versioning of the mapping file using the seeded grammar file as the starting point.
Note:
The seeded files should never be modified as all release updates make it into these files.To use versioning of the grammar files you can pass a unique version as part of Mapping APIs using the X-Version header. But it’s optional. If the header is not passed, the default version of the mapping is used.
After creating the grammar files using different versions, you can pass the desired version in the header X-Version to run the migration job. The migration and publish job will identify the grammar file by the version and will use it to run the job. For more information on how to extend using the seeded grammar files, refer to the "Handling Extensions" section below.
Handling Extensions
It is quite common for Siebel customers to have extensions to Product definitions to meet their business needs.
Mapping definitions are preconfigured for both publish and migration jobs with the required template files for the out-of-the-box Siebel fields. To accommodate extensions to entities, the seeded mapping must be updated, or new mapping configurations can be created using the REST APIs.
All extensions to Launch for the identified Siebel extensions to product definitions must be done using Launch Extensibility. See Launch Cloud Service Implementation Guide for more details. For example, the extensions are made to productOfferingOracle.yml file to create productOfferingCustomerName.yml file. Once the schema between the two applications are in place, the next step is to incorporate these extensions into the Migration and Publish grammar files.
The steps to add extension in grammar files:
Migration Mapping File
-
Get the seeded mapping file for migration to Launch. The seeded mapping file can be retrieved by using GET grammar call with details mentioned below. For Siebel migration to Launch, the X-Source-System header should be “siebel” and X-Destination-System should be “launch”.
Endpoint : {{FA_APIGW}}/mappingSchema/cx/industry/apiIntegration/v1/mappingSchema
Method Type: GET
Headers to be passed:- X-Source-System : siebel
- X-Destination-System : launch
- X-Seeded-Version : true
-
Once the grammar file is retrieved, the next step is to make the mapping edits to extend the base schema. Open the mapping file in any text editor of your choice.
Let’s say we extend the Launch ProductOfferingOracle resource for a simple offer and assume name of the extended resource is ProductOfferingCustomer with extended fields as rating, a free-form text and priceType being a bounded picklist.
Below steps to be formed in mapping file:- Get the name of base schema in the mapping file responsible for preparing transformed payload for simple offer. The base schema generally has a relevant name in mapping file schemas section.
- Define a new schema in the mapping file extending the base
schema identified in step 1.
Note:
Provide a unique name to the new schema in the mapping file. Else, the following error is displayed while updating the file in UCM (Content Store): “The File Content is not adhering valid OpenAPI standard”. - Use the below sample snippet to define a new schema
extending the OOB schema with the additional extended properties. We use
Swagger OpenAPI allOf construct to extend existing
schema.
"ProductOfferingCustomerName": { "title": " ProductOfferingCustomerName", "type": "object", "allOf": [ { "$ref": "#/components/schemas/<base-schema-name-in-mapping-file-to-be-extended>" }, { "properties": { "@type": { "type": "string", "x-oracle-map-data": { "json_path": "$.dummyField", "mapType": "TO_FIELD", "default": "<@type-value-of-new-extended-resource-in-launch>" } }, "resourceExtension": { "type": "object", "title": "resourceExtension", "x-oracle-map-data": { "json_path": "$", "mapType": "TO_OBJECT" }, "properties": { "rating": { "type": "integer", "x-oracle-map-data": { "mapType": "TO_FIELD", "json_path": "<json-path-to-map-to-siebel-system-field>" } }, "Price Type": { "type": "string", "x-oracle-map-data": { "json_path": "<json-path-to-map-to-siebel-system-field>", "mapType": "TO_FIELD", "value_map": { "pre_transform": false, "key_value_set": { "One-Time": "ONE_TIME_PRICE_PLAN", "Recurring": "RECURRING_PRICE_PLAN", "Usage": "USAGE_PRICE_PLAN" } } } } } } } } ] }
Make the following changes to the above sample snippet:- $ref in allOf needs to point to the extended base schema.
- Override base schema @type field to the newly extended schema @type value.
- Write the JsonPath for extended fields in the new schema to map them to their corresponding fields in Siebel stitched data.
-
Identify all the target_request_spec in the mapping file responsible for doing transformation for identified base schema and change its component field to point to new schema. Note that target_request_spec component field controls the selection of schema to be picked for transformation.
-
Update the modified mapping file in UCM (Content Store) using the following endpoint:
Endpoint : {{FA_APIGW}}/mappingSchema/cx/industry/apiIntegration/v1/mappingSchema
Method Type: PUT
Headers to be passed:- X-Source-System : siebel
- X-Destination-System : launch
Body to be passed:
File <File-to-be-uploaded>
-
Once the file is updated in UCM (Content Store), do a get call to verify if the file is updated correctly in UCM.
Endpoint : {{FA_APIGW}}/mappingSchema/cx/industry/apiIntegration/v1/mappingSchema
Method Type: GET
Headers to be passed:- X-Source-System : siebel
- X-Destination-System : launch
Another way to verify if the file is updated in UCM is by logging in to UCM (Content Store) in web browser. Download the file from UCM and verify the file content.
-
Once the mapping file is updated and content is verified, start migrating the data from Siebel to Launch.
Publish Mapping File
-
Get the seeded mapping file for publishing to Siebel. The seeded mapping file can be retrieved by using GET grammar call with details mentioned below. For publishing to Siebel, the X-Source-System header should be “launch” and X-Destination-System should be “siebel”.
Endpoint: {{FA_APIGW}}/mappingSchema/cx/industry/apiIntegration/v1/mappingSchema
Method Type: GET
Headers to be passed:- X-Source-System : launch
- X-Destination-System : siebel
- X-Seeded-Version : true
-
Once the grammar file is retrieved, make the mapping edits to extend the base schema. Open the mapping file in any text editor of your choice. Let’s say we extend the Launch ProductOfferingOracle resource for a simple offer and assume name of the extended resource is ProductOfferingCustomer with extended fields as rating, a free-form text.
Below steps to be formed in mapping file:- Get the name of base schema in the mapping file responsible for preparing transformed payload for simple offer. The base schema generally have a relevant name in the mapping file schemas section.
- Define a new schema in the mapping file extended the schema identified
in step 1.
Note:
Provide a unique name to the new schema in the mapping file. Else, the following error is displayed while updating the file in UCM (Content Store): “The File Content is not adhering valid OpenAPI standard”. - Identify the position of extended fields that Siebel API expect Launch system to pass in its request body during publish. Get the required info by describing the Siebel API. Maintain the same structure while extending fields in the new extended schema.
-
Below is one sample snippet extending the base schema and adding the extended field under [SWI Product Definition VBC]. We use Swagger OpenAPI allOf construct to extend existing schema.
"ProductOfferingCustomer": { "title": " ProductOfferingCustomer", "type": "object", "allOf": [ { "$ref": "#/components/schemas/<base-schema-name-in-mapping-file-to-be-extended>" }, { "properties": { "SiebelMessage": { "type": "object", "title": "SiebelMessage", "x-oracle-map-data": { "json_path": "$", "mapType": "TO_OBJECT" }, "properties": { "ListOfSWIProductIntegrationIO": { "type": "object", "title": "ListOfSWIProductIntegrationIO", "x-oracle-map-data": { "json_path": "$", "mapType": "TO_OBJECT" }, "properties": { "SWI Product Integration VBC": { "type": "array", "x-oracle-map-data": { "json_path": "$", "mapType": "TO_ARRAY" }, "items": { "type": "object", "properties": { "ListOfSWI Product Definition VBC": { "type": "object", "title": "ListOfSWI Product Definition VBC", "x-oracle-map-data": { "json_path": "$", "mapType": "TO_OBJECT" }, "properties": { "SWI Product Definition VBC": { "type": "array", "x-oracle-map-data": { "json_path": "$", "mapType": "TO_ARRAY" }, "items": { "type": "object", "properties": { "SiebelExtendedField": { "type": "string", "x-oracle-map-data": { "json_path": "<json-path-to-map-to-launch-system-field>", "mapType": "TO_FIELD" } } } } } } } } } } } } } } } } ] }
Make the following changes to the above sample snippet:- $ref of allOf swagger construct needs to point to the extended base schema.
- Write the JsonPath for newly extended fields in siebel to map them to their corresponding fields in Launch stitched data.
Note:
In the above example, a new field SiebelExtendedField is added inside SWI Product Definition VBC. Existing fields will be inherited from base schema, only the tree hierarchy needs to be maintained.
-
Identify the target_request_spec in the mapping file responsible for transformation for base schema and do below set of changes:
-
Change the eligibility_check_json_path and source_data_path fields of identified target_request_spec to include the new extended resource @type. Refer the following JsonPath.
"$..projectItems[?(@.isBundle == 'false' && @.['@referredType'] IN ['ProductOfferingOracle','<extended-resource-@referredType-value>'])]"
Note:
Put the new extended launch resource type @referredType value in the above JsonPath expression. Reason for using IN operator above is to include all entities with base schema resource type as well as entities with extended resource type. - Additionally, change the component field of target_request_spec to point to the new extended schema in mapping file. Note that target_request_spec component field controls the selection of schema to be picked for transformation.
-
-
Update the modified mapping file in UCM using the following endpoint:
Endpoint : {{FA_APIGW}}/mappingSchema/cx/industry/apiIntegration/v1/mappingSchema
Method Type: PUT
Headers to be passed:- X-Source-System : launch
- X-Destination-System : siebel
Body to be passed:
File <File-to-be-uploaded>
-
Once the file is updated in UCM (Content Store), do a get call to verify if the file is updated correctly in UCM.
Endpoint : {{FA_APIGW}}/mappingSchema/cx/industry/apiIntegration/v1/mappingSchema
Method Type: GET
Headers to be passed:- X-Source-System : launch
- X-Destination-System : siebel
Another way to verify if the file is updated in UCM is by logging in to UCM in web browser. Download the file from UCM and verify the file content.
-
Once the mapping file is updated and verified, start publishing the data from Launch to Siebel.
Supported UCM Calls
UCM is the content store where the grammar files are stored in folders with versioning of the changes. You can create a new mapping file, retrieve the latest to make updates and upload the changes made..
Create Mapping OAS File
POST - {{APIGW}}/mappingSchema/cx/industry/apiIntegration/v1/mappingSchema
• Headers to be passed:
o X-Source-System <<sourceName>>
o X-Target-System <<targetName>>
• Body to be passed
o File. <<file to be uploaded>>
For more details on header key usage, see Supported Header Keys in this guide.
Update Mapping OAS File
PUT - {{APIGW}}/mappingSchema/cx/industry/apiIntegration/v1/mappingSchema
• Headers to be passed:
o X-Source-System <<sourceName>>
o X-Target-System <<targetName>>
• Body to be passed
o File. <<file to be uploaded>>
Troubleshooting Integration Errors
This section describes the common issues that could occur either during catalog sync or during publish or migration.
Table 8-5 Troubleshoot Integration Errors
Error Scenario | Error Description | Troubleshooting Tips |
---|---|---|
Publish is successful, however Product is not created in Siebel CRM. |
No error in the UI will be shown. |
Offers with at least one offer only will be published to Siebel CRM. Ensure that the offer has pricing defined. |
Publish does not get initiated |
HTTP 404 error in browser console |
Ensure that Destination is configured correctly. |
Publish fails with error |
Processing Failure |
Use REST APIs in test mode to analyze further. |
Publish status of the initiative does not change even after running for a long time. |
No visible error reported. |
PATCH the publish job as FAILED using REST API and then republish the initiative. |
Gateway timeout in test mode. |
Launch REST APIs returns error when run in test mode. |
Publish - filter the results by adding the header Component-Name Migration – Run the migration job in Async- Mode. |
Migration fails with error "A bundle product offer must be provided when the isBundle is true" |
Not Applicable |
Siebel CRM supports Customizable Product without having any component products. But Launch does not allow to create a Bundle Offer without adding any component products to it. |
Migration fails with error “The subresource characteristic entity with the (xyz) value combination already exists. Enter unique values.” |
This issue comes up when an attribute is used more than once in the product class. Here xyz in error msg is the attribute name being used more than once in a class. |
In Siebel, attribute is a top-level entity and a class can have same attribute definition more than once with different name. But Launch does not allow to use same attribute definition more than once. Hence migration fails. |
For additional information on errors on Publish to Siebel CRM, see the Siebel CRM REST API Guide https://www.oracle.com/documentation/siebel-crm-libraries.html.