Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 62 additions & 2 deletions src/controllers/orchestration.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
'use strict'
const { bodyValueReplacer } = require('@helpers/bodyValueReplacer')
const { routesConfigs } = require('@root/configs/routesConfigs')
const routes = routesConfigs.routes

const removeArraySuffix = (obj) => {
if (Array.isArray(obj)) {
Expand Down Expand Up @@ -55,10 +57,52 @@ const packageRouterCaller = async (req, res, responses, servicePackage, packages
}
return true
}
/**
* Calls a custom merge handler defined in one of the packages based on the provided merge configuration.
*
* @async
* @function
* @param {Array<Object>} result - An array of response objects from service packages to be merged.
* @param {Object} mergeOption - The merge configuration object.
* @param {string} mergeOption.basePackageName - Identifier used to find the relevant package.
* @param {string} mergeOption.functionName - The name of the custom merge handler function to invoke.
* @param {string} mergeOption.packageName - The package name (used for validation).
* @param {Array<Object>} packages - Array of package objects, each expected to have a `packageMeta.basePackageName` and a `customMergeFunctionHandler` function.
* @returns {Promise<Object>} The result of the custom merge function.
*/
const customMergeFunctionCaller = async (result, mergeOption, packages) => {
const selectedPackage = packages.find((obj) => obj.packageMeta.basePackageName === mergeOption.basePackageName)

// Validate package exists
if (!selectedPackage) {
throw new Error(`Package "${mergeOption.basePackageName}" not found in available packages`)
}

// Validate handler exists and is callable
if (typeof selectedPackage.customMergeFunctionHandler !== 'function') {
console.warn(
`Package "${mergeOption.basePackageName}" does not implement customMergeFunctionHandler, falling back to default merge`
)
// Fallback to default merge logic
return result.reduce((acc, curr) => ({ ...acc, ...curr }), {})
}

try {
return await selectedPackage.customMergeFunctionHandler(result, mergeOption.functionName, packages)
} catch (error) {
console.error(`Custom merge handler failed for package "${mergeOption.basePackageName}":`, error)
// Fallback to default merge
return result.reduce((acc, curr) => ({ ...acc, ...curr }), {})
}

}

const orchestrationHandler = async (packages, req, res) => {
try {
const { targetPackages, inSequence, responseMessage } = req
let sourceRoute = req.sourceRoute;
let selectedRouteConfig = routes.find((obj) => obj.sourceRoute === sourceRoute);
let mergeOption = selectedRouteConfig?.mergeConfiguration || {}
const responses = {}
let asyncRequestsStatues = []
if (inSequence)
Expand All @@ -78,6 +122,7 @@ const orchestrationHandler = async (packages, req, res) => {
})
)
let response = {}
let responseArray = []
for (const servicePackage of targetPackages) {
let body
if(servicePackage.merge == true && servicePackage.mergeKey != ''){
Expand All @@ -87,9 +132,24 @@ const orchestrationHandler = async (packages, req, res) => {
} else {
body = responses[servicePackage.basePackageName]?.result
}
response = { ...response, ...body }
response = bodyValueReplacer(response, servicePackage.responseBody)
body = bodyValueReplacer(body, servicePackage.responseBody)
responseArray.push(body)
}

// Check if custom merge options are provided in the configuration
if (mergeOption && mergeOption.basePackageName && mergeOption.functionName && mergeOption.packageName) {
// If all required fields for custom merging exist,
// call the custom merge function to handle merging logic
let result = await customMergeFunctionCaller(responseArray,mergeOption, packages)
response = result
}else {
// Fallback to default merging behavior
for(let resp of responseArray){
response = { ...response, ...resp }
}
}


if (!asyncRequestsStatues.includes(false))
res.status(200).send({
responseCode: 'OK',
Expand Down