blob: 591fd5ba101bbe8839558a48030c2bdd9aaddeb1 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
const restData = require("./rest");
const graphData = require("./graphql");
const path = require("path");
const _ = require("lodash");
const fs = require("fs");
const confirmTravelForm = require("./forms/ConfirmTravel");
const applyForVisaForm = require("./forms/ApplyForVisa");
const hrInterviewForm = require("./forms/HRInterview");
const itInterviewForm = require("./forms/ITInterview");
const emptyForm = require("./forms/EmptyForm");
const formData = require("../MockData/forms/formData");
const customDashboardData = require("../MockData/customDashboard/data");
const hiringSchema = require("./process-forms-schema/hiring");
const { v4: uuidv4 } = require("uuid");
const tasksUnableToTransition = [
"047ec38d-5d57-4330-8c8d-9bd67b53a529",
"841b9dba-3d91-4725-9de3-f9f4853b417e",
"5fe852de-8d00-4197-9936-3842c648fe12345",
"5fe852de-8d00-4197-9936-3842c648fe123422",
];
const taskWithoutForm = ["475e3eb3-1de4-4f68-a146-79c236353a03", "615b9143-1468-4028-b454-6122e2139f5c"];
const taskWithEmptyForm = ["45a73767-5da3-49bf-9c40-d533c3e77ef3", "809aae9e-f0bf-4892-b0c9-4be80664d2aa"];
const formsUnableToSave = ["html_hiring_ITInterview", "react_hiring_ITInterview"];
const processSvg = [
"8035b580-6ae4-4aa8-9ec0-e18e19809e0b",
"8035b580-6ae4-4aa8-9ec0-e18e19809e0blmnop",
"2d962eef-45b8-48a9-ad4e-9cde0ad6af88",
"c54ca5b0-b975-46e2-a9a0-6a86bf7ac21e",
];
module.exports = controller = {
showError: (req, res) => {
console.log("called", req.params.processId, req.params.processInstanceId);
const { process } = restData.management;
const processId = process.filter((data) => {
return data.processId === req.params.processId;
});
const error = processId[0].instances.filter((err) => {
return err.processInstanceId === req.params.processInstanceId;
});
res.send(error[0].error);
},
callRetrigger: (req, res) => {
const { process } = restData.management;
const processId = process.filter((data) => {
return data.processId === req.params.processId;
});
const error = processId[0].instances.filter((err) => {
return err.processInstanceId === req.params.processInstanceId;
});
switch (error[0].retrigger) {
case "success":
res.send(error[0].retrigger);
break;
case "Authentication failed":
res.status(401).send(error[0].retrigger);
break;
case "Authorization failed":
res.status(403).send(error[0].retrigger);
break;
case "Internal server error":
res.status(500).send(error[0].retrigger);
break;
}
},
callSkip: (req, res) => {
const { process } = restData.management;
const processId = process.filter((data) => {
return data.processId === req.params.processId;
});
const error = processId[0].instances.filter((err) => {
return err.processInstanceId === req.params.processInstanceId;
});
switch (error[0].skip) {
case "success":
res.send(error[0].skip);
break;
case "Authentication failed":
res.status(401).send(error[0].skip);
break;
case "Authorization failed":
res.status(403).send(error[0].skip);
break;
case "Internal server error":
res.status(500).send(error[0].skip);
break;
}
},
callAbort: (req, res) => {
const failedAbortInstances = ["8035b580-6ae4-4aa8-9ec0-e18e19809e0b2", "8035b580-6ae4-4aa8-9ec0-e18e19809e0b3"];
const data = graphData.ProcessInstanceData.filter((data) => {
return data.id === req.params.processInstanceId;
});
if (failedAbortInstances.includes(data[0].id)) {
res.status(404).send("process not found");
} else {
data[0].state = "ABORTED";
res.status(200).send("success");
}
},
callNodeRetrigger: (req, res) => {
const data = graphData.ProcessInstanceData.filter((data) => {
return data.id === req.params.processInstanceId;
});
const nodeObject = data[0].nodes.filter((node) => node.id === req.params.nodeInstanceId);
if (nodeObject[0].name.includes("not found")) {
res.status(404).send("node not found");
} else {
nodeObject[0].enter = new Date().toISOString();
res.status(200).send(data[0]);
}
},
callNodeCancel: (req, res) => {
const data = graphData.ProcessInstanceData.filter((data) => {
return data.id === req.params.processInstanceId;
});
const nodeObject = data[0].nodes.filter((node) => node.id === req.params.nodeInstanceId);
if (nodeObject[0].name.includes("not found")) {
res.status(404).send("node not found");
} else {
nodeObject[0].exit = new Date().toIProcessInstanceDataSOString();
res.status(200).send(data[0]);
}
},
handleJobReschedule: (req, res) => {
const data = graphData.JobsData.find((data) => {
return data.id === req.params.id;
});
if (
req.params.id !== "eff4ee-11qw23-6675-pokau97-qwedjut45a0fa_0" &&
req.body.repeatInterval &&
req.body.repeatLimit
) {
data.expirationTime = req.body.expirationTime;
data.repeatInterval = req.body.repeatInterval;
data.repeatLimit = req.body.repeatLimit;
} else {
if (req.params.id !== "eff4ee-11qw23-6675-pokau97-qwedjut45a0fa_0") {
data.expirationTime = req.body.expirationTime;
}
}
if (req.params.id !== "eff4ee-11qw23-6675-pokau97-qwedjut45a0fa_0") {
res.status(200).send(data);
} else {
res.status(400).send("job not rescheduled");
}
},
callNodeTrigger: (req, res) => {
const graphData = require("./graphql");
const processInstance = graphData.ProcessInstanceData.filter((process) => {
return process.id === req.params.processInstanceId;
});
const nodeObject = processInstance[0].nodes.filter((node, index) => {
if (index !== processInstance[0].nodes.length - 1) {
return node.definitionId === req.params.nodeId;
}
});
if (nodeObject.length === 0) {
res.status(404).send("node not found");
} else {
const node = { ...nodeObject[0] };
node.enter = new Date().toISOString();
node.exit = null;
processInstance[0].nodes.unshift(node);
res.status(200).send({});
}
},
getTriggerableNodes: (req, res) => {
if (req.params.processId !== null || req.params.processId !== undefined) {
res.send([
{
nodeDefinitionId: "_BDA56801-1155-4AF2-94D4-7DAADED2E3C0",
name: "Send visa application",
id: 1,
type: "ActionNode",
uniqueId: "1",
},
{
nodeDefinitionId: "_175DC79D-C2F1-4B28-BE2D-B583DFABF70D",
name: "Book",
id: 2,
type: "Split",
uniqueId: "2",
},
{
nodeDefinitionId: "_E611283E-30B0-46B9-8305-768A002C7518",
name: "visasrejected",
id: 3,
type: "EventNode",
uniqueId: "3",
},
]);
} else {
res.send([]);
}
},
callJobCancel: (req, res) => {
const mockFailedJobs = ["dad3aa88-5c1e-4858-a919-6123c675a0fa_0"];
const graphData = require("./graphql");
const jobData = graphData.JobsData.filter((job) => job.id === req.params.jobId);
if (mockFailedJobs.includes(jobData[0].id) || jobData.length === 0) {
res.status(404).send("job not found");
} else {
jobData[0].status = "CANCELED";
jobData[0].lastUpdate = new Date().toISOString();
res.status(200).send(jobData[0]);
}
},
dispatchSVG: (req, res) => {
try {
if (processSvg.includes(req.params.id)) {
if (req.params.processId === "travels") {
res.sendFile(path.resolve(__dirname + "/../static/travels.svg"));
} else if (req.params.processId === "flightBooking") {
res.sendFile(path.resolve(__dirname + "/../static/flightBooking.svg"));
} else if (req.params.processId === "hotelBooking") {
res.sendFile(path.resolve(__dirname + "/../static/hotelBooking.svg"));
}
} else {
res.send(null);
}
} catch (error) {
res.status(404).send(error);
}
},
callCompleteTask: (req, res) => {
console.log(`......Transition task: --taskId:${req.params.taskId}`);
const task = graphData.UserTaskInstances.find((userTask) => {
return userTask.id === req.params.taskId;
});
if (tasksUnableToTransition.includes(task.id)) {
res.status(500).send("Unexpected failure when doing a transition!");
} else {
const phase = req.query.phase;
if (phase === "complete") {
task.state = "Completed";
task.completed = new Date().toISOString();
}
res.send(task.inputs);
}
},
getTaskForm: (req, res) => {
console.log(
`......Get Task Form Schema: --processId:${req.params.processId} --piId:${req.params.processInstanceId} --taskId:${req.params.taskId}`
);
const task = graphData.UserTaskInstances.find((userTask) => {
return userTask.id === req.params.taskId;
});
const clearPhases = task.completed || task.state === "Aborted";
if (taskWithEmptyForm.includes(task.id)) {
const form = _.cloneDeep(emptyForm);
if (clearPhases) {
delete form.phases;
}
res.send(JSON.stringify(form));
return;
}
if (taskWithoutForm.includes(task.id)) {
res.status(500).send("Error: cannot load form");
return;
}
res.send(JSON.stringify(getTaskSchema(task.name, clearPhases)));
},
getTaskDefinitionForm: (req, res) => {
console.log(
`......Get Task Definition Form Schema: --processId:${req.params.processId} --TaskName:${req.params.taskName}`
);
res.send(JSON.stringify(getTaskSchema(req.params.taskName, true)));
},
getCustomDashboards: (req, res) => {
const filterNames = req.query.names.split(";");
if (filterNames[0].length === 0) {
res.send(customDashboardData);
} else {
const filteredCustomDashboards = [];
filterNames.forEach((name) => {
customDashboardData.forEach((customDashboard) => {
if (customDashboard.name === name) {
filteredCustomDashboards.push(customDashboard);
}
});
});
res.send(filteredCustomDashboards);
}
},
getCustomDashboardContent: (req, res) => {
const dashboardName = req.params.name;
let content = "";
if (dashboardName === "age.dash.yaml") {
content = fs.readFileSync(__dirname + "/customDashboard/age.dash.yaml", "utf-8");
}
if (dashboardName === "products.dash.yaml") {
content = fs.readFileSync(__dirname + "/customDashboard/products.dash.yaml", "utf-8");
}
res.send(content);
},
getForms: (req, res) => {
const formFilterNames = req.query.names.split(";");
if (formFilterNames[0].length === 0) {
res.send(formData);
} else {
const filteredForms = [];
formFilterNames.forEach((name) => {
formData.forEach((form) => {
if (form.name === name) {
filteredForms.push(form);
}
});
});
res.send(filteredForms);
}
},
getFormContent: (req, res) => {
console.log(`......Get Custom Form Content: --formName:${req.params.formName}`);
const formName = req.params.formName;
const formInfo = formData.filter((datum) => datum.name === formName);
if (formInfo.length === 0) {
res.status(500).send("Cannot find form");
return;
}
let sourceString;
const configString = fs.readFileSync(path.join(`${__dirname}/forms/examples/${formName}.config`), "utf8");
if (formInfo[0].type.toLowerCase() === "html") {
sourceString = fs.readFileSync(path.join(`${__dirname}/forms/examples/${formName}.html`), "utf8");
} else if (formInfo[0].type.toLowerCase() === "tsx") {
sourceString = fs.readFileSync(path.join(`${__dirname}/forms/examples/${formName}.tsx`), "utf8");
}
const response = {
formInfo: formInfo[0],
source: sourceString,
configuration: JSON.parse(configString),
};
res.send(response);
},
saveFormContent: (req, res) => {
console.log(`......Save Form Content: --formName:${req.params.formName}`);
if (formsUnableToSave.includes(req.params.formName)) {
res.status(500).send("Unexpected failure saving form!");
} else {
res.send("Saved!");
}
},
getProcessFormSchema: (req, res) => {
console.log(`processName: ${req.params.processName}`);
const processName = req.params.processName;
let schema;
if (processName === "hiring") {
schema = _.cloneDeep(hiringSchema);
} else {
res.status(500).send("internal server error");
}
res.send(JSON.stringify(schema));
},
startProcessInstance: (req, res) => {
const businessKey = req.query.businessKey ? req.query.businessKey : null;
const processId = uuidv4();
const processInstance = {
id: processId,
processId: "hiring",
businessKey: businessKey,
parentProcessInstanceId: null,
parentProcessInstance: null,
processName: "Hiring",
rootProcessInstanceId: null,
roles: [],
state: "ACTIVE",
start: "2019-10-22T03:40:44.089Z",
end: "2019-10-22T05:40:44.089Z",
serviceUrl: null,
endpoint: "http://localhost:4000",
error: {
nodeDefinitionId: "a1e139d5-4e77-48c9-84ae-34578e904e6b",
message: "some thing went wrong",
},
addons: [],
variables:
'{"trip":{"begin":"2019-10-22T22:00:00Z[UTC]","city":"Bangalore","country":"India","end":"2019-10-30T22:00:00Z[UTC]","visaRequired":false},"hotel":{"address":{"city":"Bangalore","country":"India","street":"street","zipCode":"12345"},"bookingNumber":"XX-012345","name":"Perfect hotel","phone":"09876543"},"traveller":{"address":{"city":"Bangalore","country":"US","street":"Bangalore","zipCode":"560093"},"email":"ajaganat@redhat.com","firstName":"Ajay","lastName":"Jaganathan","nationality":"US"}}',
nodes: [
{
nodeId: "1",
name: "End Event 1",
definitionId: "EndEvent_1",
id: "27107f38-d888-4edf-9a4f-11b9e6d751b6",
enter: "2019-10-22T03:37:30.798Z",
exit: "2019-10-22T03:37:30.798Z",
type: "EndNode",
},
],
milestones: [],
childProcessInstances: [],
};
if (businessKey && businessKey.toLowerCase() === "error") {
res.status(500).send("internal server error");
}
graphData["ProcessInstanceData"].push(processInstance);
res.send({
id: processId,
});
},
triggerCloudEvent: (req, res) => {
console.log(
`......Trigger Cloud Event:: id: ${req.headers["ce-id"]} type: ${req.headers["ce-type"]} source: ${req.headers["ce-source"]}`
);
if (req.body.type === "error") {
res.status(500).send("internal server error");
}
if (req.body.kogitobusinesskey) {
console.log(`Starting Serverless workflow with business key: ${req.body.kogitobusinesskey}`);
return res.status(200).send(req.body.kogitobusinesskey);
} else if (req.body.kogitoprocrefid) {
console.log(`Serverless Workflow with id ${req.body.kogitoprocrefid} successfully completed`);
return res.status(200).send(req.body.kogitoprocrefid);
}
return res.status(200).send("Cloud Event successfully triggered");
},
};
function getTaskSchema(taskName, clearPhases) {
let schema;
console.log(`Getting Schema for task: ${taskName} --clearPhases: ${clearPhases}`);
switch (taskName) {
case "ConfirmTravel": {
schema = _.cloneDeep(confirmTravelForm);
break;
}
case "VisaApplication": {
schema = _.cloneDeep(applyForVisaForm);
break;
}
case "HRInterview": {
schema = _.cloneDeep(hrInterviewForm);
break;
}
case "ITInterview": {
schema = _.cloneDeep(itInterviewForm);
break;
}
}
if (clearPhases) {
delete schema.phases;
}
return schema;
}