Corticon.js Service Callout APIs let you add, set, and remove associations between entities. The parameters are:
  • entityParent - The Entity for the association
  • roleName - The association roleName
  • entityChildren - The Entity's association

addAssociation

addAssociation(entityParent, entityChild, roleName)

function addFlightPlanToCargo(corticonDataManager) {
	let childEntity;
	let parentEntity;
	let aircraftEntity;
	const entities = corticonDataManager.getEntitiesByType('Cargo');
    entities.forEach(entity => {
        if((entity['container'] === 'reefer') && entity['volume'] === 10 && entity['weight'] === 1000) {
            //Update the attribute value to something else
            parentEntity = entity;
        }
    });
	
	const entitiesChild = corticonDataManager.getEntitiesByType('FlightPlan');
    entitiesChild.forEach(entity => {
        if(entity['flightNumber'] === 737) {
            childEntity = entity;
        }
    });
	
	//Add Association
	corticonDataManager.addAssociation(parentEntity, childEntity, 'flightPlan');
	
}	

setAssociation

setAssociation(entityParent, entityChild, roleName) - Updates an association between a parent and child entity for the rolename:
const updateFlightPlan = {
    func: 'updateFlightPlanToCargo',
    type: 'ServiceCallout',
    description: {'en_US': 'associates FlightPlan to Cargo'},
    extensionType: 'SERVICE_CALLOUT',
    ret: 'Void',
    name: { 'en_US': 'updateFlightPlan' }
};
	
function updateFlightPlanToCargo(corticonDataManager) {
    let childEntity;
    let parentEntity;
    const entities = corticonDataManager.getEntitiesByType('Cargo');
    entities.forEach(entity => {
        if((entity['container'] === 'reefer') && entity['volume'] === 10 && entity['weight'] === 1000) {
            //Get the parent Entity
            parentEntity = entity;
        }
    });
    
    const entitiesChild = corticonDataManager.getEntitiesByType('FlightPlan');
    entitiesChild.forEach(entity => {
        if(entity['flightNumber'] === 737) {
            //Get the child Entity
            childEntity = entity;
        }
    });
    
    //Set Association
    corticonDataManager.setAssociation(parentEntity, childEntity, 'flightPlan');
    
}	

removeAssociation

removeAssociation(entityParent, entityChild, roleName) - Deletes an association between a parent and child entity for the rolename:
const removeFlightPlan = {
    builtin: false,
    func: 'removeFlightPlanImpl',
    type: 'ServiceCallout',
    description: {'en_US': 'removes FlightPlan associated with Cargo'},
    extensionType: 'SERVICE_CALLOUT',
    ret: 'Void',
    name: { 'en_US': 'removeFlightPlan' }
};	
function removeFlightPlanImpl(corticonDataManager) {
    let childEntity;
    let parentEntity;
    const entities = corticonDataManager.getEntitiesByType('Cargo');
    entities.forEach(entity => {
        if((entity['container'] === 'reefer') && entity['volume'] === 10 && entity['weight'] === 1000) {
            //Get the parent Entity
            parentEntity = entity;
        }
    });
    
    const entitiesChild = corticonDataManager.getEntitiesByType('FlightPlan');
    entitiesChild.forEach(entity => {
        if(entity['flightNumber'] === 737) {
            //Get the child Entity
            childEntity = entity;
        }
    });
    
    //Remove Association
    corticonDataManager.removeAssociation(parentEntity, childEntity, 'flightPlan');
    
}
Note: Example of adding an association

Create an entity and associate it with another entity, as shown:

Code to Create Association: UpdateProductServiceCallout.js



When run in a browser deployment, the payload has the following output:


Here is an example with two providers:


You can see that the total cost of the first item, A-123, is ((2*11.22)+15.33+21.10)=58.87, the sum of both provider deliveries.

addEntitiesAndAssociations

addEntitiesAndAssociations(entityType,payload)
To enrich the data and the working memory, you can add entities and associations using this API. The entities will be added as top level entities. This api takes two parameters, the entityType and the payload. The entityType is the type of entity (defined in the vocabulary) at the root of the payload. The payload itself can either be a JSON Object or a JSONArray. If passing in a JSONObject, the entityType should match the entityType at the root of the JSONObject.
Sample using Cargo
Say you want to add another Cargo to the payload for your rules to execute. You can create 
a service callout and append that cargo to the working memory.
For example:
{
        "volume": 10,
        "container": null,
        "flightPlan": {
            "aircraft": {
                "aircraftType": "Airbus",
                "maxCargoWeight": null,
                "tailNumber": null,
                "maxCargoVolume": "30.000000"
            },
            "flightNumber": 380
        },
        "weight": 1000
}
The above JSON payload has a Cargo at root and its associations nested in the JSON. 
You can use the API to add this Cargo to the working memory.
//Sample Code for using the API as below 
//Metadata for the Service Callout
const asyncAddCargoEntity = {
    func: 'asyncAddCargoEntityFct',
    type: 'ServiceCallout',
    description: {'en_US': 'This function is used to add some data to the working memory.'},
    extensionType: 'SERVICE_CALLOUT',
    name: {'en_US': 'asyncAddCargoEntity'}
};
//Service Callout Function
async function asyncAddCargoEntityFct(corticonDataManager) {
	const logger = corticonDataManager.getLogger();
	//Define the payload i.e your JSON Object
	const payload = {
        "volume": 10,
        "container": null,
        "flightPlan": {
            "aircraft": {
                "aircraftType": "Airbus",
                "maxCargoWeight": null,
                "tailNumber": null,
                "maxCargoVolume": "30.000000"
            },
            "flightNumber": 380
        },
        "weight": 1000
    };
try {
	//Api to add the Cargo to the root. Takes the entity Type and the payload.    
	const returnCode = corticonDataManager.addEntitiesAndAssociations('Cargo', payload);
		if(returnCode === success)
			logger.logDebug(`*** Cargo has been Added`);
	}
	catch ( e ) {
		logger.logError(`*** Error adding entity: ${e}`);
	}    
}
exports.asyncAddCargoEntityFct = asyncAddCargoEntityFct;
In the above example the API will add a Cargo at root and 
also add the nested association FlightPlan and the association Aircraft to the working memory.
Note: Check your vocabulary before you pass in the payloads, or use the role name. Make sure the payload has the JSON overrides specified in each JSON Element Name, as illustrated for an attribute where the flightNumber is the full flightCode (carrier+flight number):


Similarly, an association might have a preferred JSON Element name as illustrated where the aircraft association is mapped as plane:


An Entity's JSON Path has no use in this context.

Multiple Cargos

You can also add multiple Cargos to the working memory. In that case, you can pass in a JSONArray of Cargo instead of a JSONObject.
To pass a JSONArray
//Metadata for the Service Callout
const asyncAddCargoEntity = {
    func: 'asyncAddCargoEntityFct',
    type: 'ServiceCallout',
    description: {'en_US': 'This function is used to add some data to the working memory.'},
    extensionType: 'SERVICE_CALLOUT',
    name: {'en_US': 'asyncAddCargoEntity'}
};
//Service Callout Function
async function asyncAddCargoEntityFct(corticonDataManager) {
	const logger = corticonDataManager.getLogger();
	const payload = [
    {
        "volume": 10,
        "container": null,
        "flightPlan": {
            "aircraft": {
                "aircraftType": "Airbus",
                "maxCargoWeight": null,
                "tailNumber": null,
                "maxCargoVolume": "30.000000"
            },
            "flightNumber": 380
        },
        "weight": 1000
    },
    {
        "volume": 40,
        "container": null,
        "weight": 1000,
		"flightPlan": {
            "aircraft": {
                "aircraftType": "Boeing",
                "maxCargoWeight": null,
                "tailNumber": null,
                "maxCargoVolume": "50.000000"
            },
            "flightNumber": 737
        }
    },
    {
        "volume": 20,
        "container": null,
        "weight": 30000
    },
    {
        "volume": 10,
        "container": null,
        "needsRefrigeration": true,
        "weight": 1000
    }
];
try {
	//API to add Cargo's to the working memory
	//In the above example, 4 Cargo entities will be added to working memory    
	const returnCode = corticonDataManager.addEntitiesAndAssociations('Cargo', payload);
		if(returnCode === success)
			logger.logDebug(`*** Cargos have been Added`);
	}
	catch ( e ) {
		logger.logError(`*** Error adding entity: ${e}`);
	}    
}
//Exports
exports.asyncAddCargoEntityFct = asyncAddCargoEntityFct;

addAssociationsToEntity

addAssociationsToEntity(parentEntity,rolename,payload)
To enrich the data and the working memory, you can add nested associations to existing entities using this API. The entity to which you want to add associations should be in the working memory. The entity can be at any level in the input tree. This api takes three parameters, the parentEntity the rolename and the payload. The parentEntity is the entity in the working memory to which you want to add the association. The rolename is the association you want to add (defined in the vocabulary). The payload itself can either be a JSON Object or a JSONArray.
To add a flightPlan association to Cargo, the JSON payload might look like this:									
{
            "aircraft": {
                "aircraftType": "Airbus",
                "maxCargoWeight": null,
                "tailNumber": null,
                "maxCargoVolume": "30.000000"
            },
            "flightNumber": 380
}
									
The above JSON has FlightPlan and nested Aircraft.
You can add this association to the existing Cargo using the sample below -
//Metadata for the Service Callout
const asyncAddFlightPlanAssociationEntity = {
    func: 'asyncAddFlightPlanEntityFct',
    type: 'ServiceCallout',
    description: {'en_US': 'This function is used to add some flight plan to the cargo entity.'},
    extensionType: 'SERVICE_CALLOUT',
    name: {'en_US': 'asyncAddFlightPlanAssociationEntity'}
};
//Service Callout Function
async function asyncAddFlightPlanEntityFct(corticonDataManager) {
	const logger = corticonDataManager.getLogger();
	const payload = {
            "aircraft": {
                "aircraftType": "Airbus",
                "maxCargoWeight": null,
                "tailNumber": null,
                "maxCargoVolume": "30.000000"
            },
            "flightNumber": 380
        };
try {
		//This API gets the Cargo entities in working memory
		const entities = corticonDataManager.getEntitiesByType('Cargo');
		/* Logic to determine which Cargo you want to associate this
		   Flight Plan with.
		   In this example we are using volume and if the volume of the Cargo
		   equals 10 then we are going to attach the flight plan to the Cargo
		   The logic determines the parent entity and that parent entity in passed
		   to the API below
		*/
		let entityParent;
		for (let entity of entities) {
			if(entity['volume'] === 10) {
				entityParent = entity; //Determines the parent Entity to be used.
				break;
			}
		}
		/* This call then passes in the parent entity, the role name FlightPlan as defined
		in the vocabulary and the above payload. If there are no errors, success is returned from the API
		and the association will be attached to the Cargo */
		const success = corticonDataManager.addAssociationsToEntity(entityParent, "FlightPlan", payload);
		logger.logDebug(`*** Data Added`);
	}
	catch ( e ) {
		logger.logError(`*** Error adding entity: ${e}`);
	}  
}	
//Exports
exports.asyncAddFlightPlanEntityFct = asyncAddFlightPlanEntityFct;		

Multiple nested associations

You can also add multiple nested associations to an entity. If you want to add multiple associations to an entity, it must be supported in the vocabulary. To add multiple associations you must pass in a JSONArray.
const asyncAddFlightPlanAssociationEntity = {
    func: 'asyncAddFlightPlanEntityFct',
    type: 'ServiceCallout',
    description: {'en_US': 'This function is used to add some flight plan to the cargo entity.'},
    extensionType: 'SERVICE_CALLOUT',
    name: {'en_US': 'asyncAddFlightPlanAssociationEntity'}
};
async function asyncAddFlightPlanEntityFct(corticonDataManager) {
	const logger = corticonDataManager.getLogger();
	const payload = [{
		"aircraft": {
			"aircraftType": "Airbus",
			"maxCargoWeight": null,
			"tailNumber": null,
			"maxCargoVolume": "30.000000"
		},
		"flightNumber": 380
	},
	{
		"aircraft": {
			"aircraftType": "Boeing",
			"maxCargoWeight": null,
			"tailNumber": null,
			"maxCargoVolume": "30.000000"
		},
		"flightNumber": 737
	},
	{
		"aircraft": {
			"aircraftType": "Airbus",
			"maxCargoWeight": null,
			"tailNumber": null,
			"maxCargoVolume": "30.000000"
		},
		"flightNumber": 350
	},
	{
		"aircraft": {
			"aircraftType": "Boeing",
			"maxCargoWeight": null,
			"tailNumber": null,
			"maxCargoVolume": "30.000000"
		},
		"flightNumber": 747
	}
	];
try {
		//This API gets the Cargo entities in working memory
		const entities = corticonDataManager.getEntitiesByType('Cargo');
		/* Logic to determine which Cargo you want to associate this
		   Flight Plan with.
		   In this example we are using volume and if the volume of the Cargo
		   equals 10 then we are going to attach the flight plan to the Cargo
		   The logic determines the parent entity and that parent entity in passed
		   to the API below
		*/
		let entityParent;
		for (let entity of entities) {
			if(entity['volume'] === 10) {
				entityParent = entity; //Determines the parent Entity to be used.
				break;
			}
		}
		/* This call then passes in the parent entity, the role name  FlightPlan as defined
		in the vocabulary and the above payload. If there are no errors, success is returned from the API
		and the association will be attached to the Cargo. It will add 4 Flight Plan to the Cargo  */
		const success = corticonDataManager.addAssociationsToEntity(entityParent, "FlightPlan", payload);
		logger.logDebug(`*** Data Added`);
	}
	catch ( e ) {
		logger.logError(`*** Error adding entity: ${e}`);
	}  
}	
exports.asyncAddFlightPlanEntityFct = asyncAddFlightPlanEntityFct;