add workflow components.

This commit is contained in:
Simon Larsen 2023-02-16 13:07:40 +00:00
parent c475cbc2df
commit 80ca4ea76e
No known key found for this signature in database
GPG Key ID: AB45983AA9C81CDE
8 changed files with 191 additions and 28 deletions

View File

@ -0,0 +1,9 @@
enum ComponentID {
Webhook = "webhook",
Log = "log",
Schedule="schedule"
}
export default ComponentID;

View File

@ -1,4 +1,5 @@
import IconProp from '../../Icon/IconProp';
import ComponentID from '../ComponentID';
import ComponentMetadata, {
ComponentInputType,
ComponentType,
@ -6,7 +7,7 @@ import ComponentMetadata, {
const components: Array<ComponentMetadata> = [
{
id: 'log',
id: ComponentID.Log,
title: 'Log',
category: 'Utils',
description: 'Log to console what ever is passed to this component',

View File

@ -3,10 +3,11 @@ import ComponentMetadata, {
ComponentInputType,
ComponentType,
} from './../Component';
import ComponentID from "../ComponentID";
const components: Array<ComponentMetadata> = [
{
id: 'webhook',
id: ComponentID.Webhook,
title: 'Webhook',
category: 'Webhook',
description:

View File

@ -2,61 +2,58 @@
//
import BadDataException from "Common/Types/Exception/BadDataException";
import NotImplementedException from "Common/Types/Exception/NotImplementedException";
import { JSONObject } from "Common/Types/JSON";
import ObjectID from "Common/Types/ObjectID";
import ComponentMetadata, { Port } from "Common/Types/Workflow/Component";
import { ExpressRouter } from "../../Utils/Express";
export interface RunProps {
global: {
variables: JSONObject
},
local: {
variables: JSONObject,
components: {
// component id.
[x: string]: {
returnValues: JSONObject
}
}
},
workflowId: ObjectID,
workflowRunId: ObjectID
arguments: JSONObject;
workflowId: ObjectID;
workflowRunId: ObjectID;
}
export interface RunReturnType {
returnValues: JSONObject,
executePort: Port
executePort?: Port | undefined
}
export interface InitProps{
export interface ExecuteWorkflowType {
workflowId: ObjectID,
returnValues: JSONObject,
}
export interface InitProps {
router: ExpressRouter;
runWorkflow: (workflowId: ObjectID, returnValues: JSONObject) => void;
executeWorkflow: (executeWorkflow: ExecuteWorkflowType) => Promise<void>;
scheduleWorkflow: (executeWorkflow: ExecuteWorkflowType, scheduleAt: string) => Promise<void>;
}
export default class ComponentCode {
export default class ComponentCode {
private metadata: ComponentMetadata | null = null;
public constructor(metadata: ComponentMetadata){
public constructor(metadata: ComponentMetadata) {
this.metadata = metadata;
}
public getMetadata(): ComponentMetadata {
if(!this.metadata){
public getMetadata(): ComponentMetadata {
if (!this.metadata) {
throw new BadDataException("ComponentMetadata not found")
}
return this.metadata;
}
public async init(_props: InitProps ): Promise<void>{
throw new NotImplementedException();
public async init(_props: InitProps): Promise<void> {
return await Promise.resolve()
}
public async run(_props: RunProps): Promise<RunReturnType>{
throw new NotImplementedException();
public async run(_props: RunProps): Promise<RunReturnType> {
return await Promise.resolve({
returnValues: {},
port: undefined
})
}
}

View File

@ -0,0 +1,10 @@
import ComponentID from "Common/Types/Workflow/ComponentID";
import WebhookTrigger from "./Webhook";
import Log from "./Log";
import Schedule from "./Schedule";
export default {
[ComponentID.Webhook]: WebhookTrigger,
[ComponentID.Log]: Log,
[ComponentID.Schedule]: Schedule
}

View File

@ -0,0 +1,35 @@
import OneUptimeDate from "Common/Types/Date";
import BadDataException from "Common/Types/Exception/BadDataException";
import ComponentMetadata, { Port } from "Common/Types/Workflow/Component";
import ComponentID from "Common/Types/Workflow/ComponentID";
import WebhookComponents from "Common/Types/Workflow/Components/Webhook";
import ComponentCode, { RunProps, RunReturnType } from "../ComponentCode";
export default class Log extends ComponentCode {
public constructor() {
const LogComponent: ComponentMetadata | undefined = WebhookComponents.find((i: ComponentMetadata) => i.id === ComponentID.Log);
if (!LogComponent) {
throw new BadDataException("Component not found.")
}
super(LogComponent);
}
public override run(props: RunProps): Promise<RunReturnType> {
const outPort: Port | undefined = this.getMetadata().outPorts.find((p)=> p.id === "out");
if(!outPort){
throw new BadDataException("Out port not found");
}
console.log(OneUptimeDate.getCurrentDateAsFormattedString()+":");
console.log(props.arguments["value"]);
return Promise.resolve({
returnValues: {},
executePort: outPort
});
}
}

View File

@ -0,0 +1,56 @@
import LIMIT_MAX from "Common/Types/Database/LimitMax";
import BadDataException from "Common/Types/Exception/BadDataException";
import ObjectID from "Common/Types/ObjectID";
import ComponentMetadata from "Common/Types/Workflow/Component";
import ComponentID from "Common/Types/Workflow/ComponentID";
import WebhookComponents from "Common/Types/Workflow/Components/Webhook";
import Workflow from "Model/Models/Workflow";
import WorkflowService from "../../../Services/WorkflowService";
import QueryHelper from "../../Database/QueryHelper";
import ComponentCode, { ExecuteWorkflowType, InitProps } from "../ComponentCode";
export default class WebhookTrigger extends ComponentCode {
public constructor() {
const component: ComponentMetadata | undefined = WebhookComponents.find((i: ComponentMetadata) => i.id === ComponentID.Schedule);
if (!component) {
throw new BadDataException("Trigger not found.")
}
super(component);
}
public override async init(props: InitProps): Promise<void> {
const workflows: Array<Workflow> = await WorkflowService.findBy({
query: {
triggerId: ComponentID.Schedule,
triggerArguments: QueryHelper.notNull()
},
select:{
_id: true,
triggerArguments: true,
},
props: {
isRoot: true,
},
limit: LIMIT_MAX,
skip: 0
});
// query all workflows.
for(const workflow of workflows){
const executeWorkflow: ExecuteWorkflowType = {
workflowId: new ObjectID(workflow._id!),
returnValues: {}
};
if(workflow.triggerArguments && workflow.triggerArguments["schedule"]){
await props.scheduleWorkflow(executeWorkflow, workflow.triggerArguments["schedule"] as string)
}
}
}
}

View File

@ -0,0 +1,54 @@
import BadDataException from "Common/Types/Exception/BadDataException";
import ObjectID from "Common/Types/ObjectID";
import ComponentMetadata from "Common/Types/Workflow/Component";
import ComponentID from "Common/Types/Workflow/ComponentID";
import WebhookComponents from "Common/Types/Workflow/Components/Webhook";
import { ExpressRequest, ExpressResponse } from "../../../Utils/Express";
import Response from "../../../Utils/Response";
import ComponentCode, { ExecuteWorkflowType, InitProps } from "../ComponentCode";
export default class WebhookTrigger extends ComponentCode {
public constructor() {
const WebhookComponent: ComponentMetadata | undefined = WebhookComponents.find((i: ComponentMetadata) => i.id === ComponentID.Webhook);
if (!WebhookComponent) {
throw new BadDataException("Webhook trigger not found.")
}
super(WebhookComponent);
}
public override async init(props: InitProps): Promise<void> {
props.router.get(
`/trigger/:workflowId`,
async (req: ExpressRequest, res: ExpressResponse) => {
await this.initTrigger(req, res, props);
}
);
props.router.post(
`/trigger/:workflowId`,
async (req: ExpressRequest, res: ExpressResponse) => {
await this.initTrigger(req, res, props);
}
);
}
public async initTrigger(req: ExpressRequest, res: ExpressResponse, props: InitProps) {
/// Run Graph.
const executeWorkflow: ExecuteWorkflowType = {
workflowId: new ObjectID(req.params['workflowId'] as string),
returnValues: {
'request-headers': req.headers,
'request-params': req.query,
'request-body': req.body
}
};
await props.executeWorkflow(executeWorkflow);
Response.sendJsonObjectResponse(req, res, { status: "Scheduled" });
}
}