@contrail/cli 1.0.19 → 1.0.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/apps/deploy-app/app-deployer.d.ts +1 -1
- package/lib/apps/deploy-app/app-deployer.js +8 -2
- package/lib/apps/deploy-app/deploy.js +2 -1
- package/lib/apps/deploy-app/interfaces.d.ts +16 -2
- package/lib/apps/deploy-app/workflow-definition-deployer.d.ts +10 -0
- package/lib/apps/deploy-app/workflow-definition-deployer.js +85 -0
- package/lib/apps/deploy-app/workflow-deployer.d.ts +2 -2
- package/lib/apps/deploy-app/workflow-deployer.js +4 -1
- package/package.json +1 -1
- package/src/apps/deploy-app/app-deployer.ts +7 -2
- package/src/apps/deploy-app/deploy.ts +2 -2
- package/src/apps/deploy-app/interfaces.ts +18 -2
- package/src/apps/deploy-app/workflow-definition-deployer.ts +110 -0
- package/src/apps/deploy-app/workflow-deployer.ts +20 -13
- package/templates/javascript/app.yml +13 -14
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { App, AppDeclaration } from './interfaces';
|
|
2
2
|
export declare class AppDeployer {
|
|
3
|
-
deploy(appDeclaration: AppDeclaration): Promise<void>;
|
|
3
|
+
deploy(appDeclaration: AppDeclaration, deployWorkflowTemplateOnly?: boolean): Promise<void>;
|
|
4
4
|
getExistingApp(appDeclaration: AppDeclaration): Promise<App>;
|
|
5
5
|
private createNewApp;
|
|
6
6
|
updateExistingApp(appDeclaration: AppDeclaration, existingApp: any): Promise<any>;
|
|
@@ -3,9 +3,10 @@ import chalk from 'chalk';
|
|
|
3
3
|
import { Auth } from '../../auth/auth';
|
|
4
4
|
import { ActionsDeployer } from './actions-deployer';
|
|
5
5
|
import { TriggerKeyDefinitionParser, ConfigPropertiesParser } from './app-template-parsers';
|
|
6
|
+
import { WorkflowDefinitionDeployer } from './workflow-definition-deployer';
|
|
6
7
|
import { WorkflowDeployer } from './workflow-deployer';
|
|
7
8
|
export class AppDeployer {
|
|
8
|
-
async deploy(appDeclaration) {
|
|
9
|
+
async deploy(appDeclaration, deployWorkflowTemplateOnly = false) {
|
|
9
10
|
let app = await this.getExistingApp(appDeclaration);
|
|
10
11
|
if (!app) {
|
|
11
12
|
console.log(`%s Creating new app.`, chalk.yellow.bold('APP'));
|
|
@@ -16,7 +17,12 @@ export class AppDeployer {
|
|
|
16
17
|
app = await this.updateExistingApp(appDeclaration, app);
|
|
17
18
|
}
|
|
18
19
|
await new ActionsDeployer().deployActions(appDeclaration, app);
|
|
19
|
-
|
|
20
|
+
if (deployWorkflowTemplateOnly) {
|
|
21
|
+
await new WorkflowDeployer().deployWorkflows(appDeclaration, app);
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
await new WorkflowDefinitionDeployer().deployWorkflowDefinitions(appDeclaration, app);
|
|
25
|
+
}
|
|
20
26
|
}
|
|
21
27
|
async getExistingApp(appDeclaration) {
|
|
22
28
|
const orgId = Auth.config.orgId;
|
|
@@ -26,9 +26,10 @@ export async function deployApp(args) {
|
|
|
26
26
|
return;
|
|
27
27
|
}
|
|
28
28
|
console.log(`%s Deploying Application. ${appDeclaration.appIdentifier}`, chalk.blue.bold('START'));
|
|
29
|
+
const templateOnly = args && args.includes('--template-only');
|
|
29
30
|
try {
|
|
30
31
|
await authUser();
|
|
31
|
-
await new AppDeployer().deploy(appDeclaration);
|
|
32
|
+
await new AppDeployer().deploy(appDeclaration, templateOnly);
|
|
32
33
|
}
|
|
33
34
|
catch (e) {
|
|
34
35
|
console.log(`%s Application Deployment Failed. ${e}`, chalk.red.bold('FAIL'));
|
|
@@ -19,7 +19,7 @@ export interface AppDeclaration {
|
|
|
19
19
|
[key: string]: AppTriggerDeclaration;
|
|
20
20
|
};
|
|
21
21
|
workflows?: {
|
|
22
|
-
[key: string]:
|
|
22
|
+
[key: string]: WorkflowDefinitionDeclaration | WorkflowTemplateDeclaration;
|
|
23
23
|
};
|
|
24
24
|
}
|
|
25
25
|
export interface ConfigPropertyElements {
|
|
@@ -42,7 +42,7 @@ export interface AppTriggerDeclaration {
|
|
|
42
42
|
external?: boolean;
|
|
43
43
|
description?: string;
|
|
44
44
|
}
|
|
45
|
-
export interface
|
|
45
|
+
export interface WorkflowDefinitionDeclaration {
|
|
46
46
|
id?: string;
|
|
47
47
|
identifier: string;
|
|
48
48
|
name: string;
|
|
@@ -50,6 +50,20 @@ export interface WorkflowDeclaration {
|
|
|
50
50
|
workflowDefinition: WorkflowDefinition;
|
|
51
51
|
ownerKey: string;
|
|
52
52
|
isActive: boolean;
|
|
53
|
+
public: boolean;
|
|
54
|
+
supportingAppId?: string;
|
|
55
|
+
}
|
|
56
|
+
export interface WorkflowTemplateDeclaration {
|
|
57
|
+
id?: string;
|
|
58
|
+
identifier: string;
|
|
59
|
+
name: string;
|
|
60
|
+
triggerKey: string;
|
|
61
|
+
workflowDefinition: WorkflowDefinition;
|
|
62
|
+
ownerKey: string;
|
|
63
|
+
isActive: boolean;
|
|
64
|
+
supportingAppId?: string;
|
|
65
|
+
messageGroupId?: string;
|
|
66
|
+
parallelWorkerCount?: number;
|
|
53
67
|
}
|
|
54
68
|
export interface WorkflowDefinition {
|
|
55
69
|
paths: WorkflowConditional[];
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { App, AppDeclaration, WorkflowDefinitionDeclaration } from './interfaces';
|
|
2
|
+
export declare class WorkflowDefinitionDeployer {
|
|
3
|
+
deployWorkflowDefinitions(appDeclaration: AppDeclaration, app: App): Promise<void>;
|
|
4
|
+
getWorkflowDefinitionsForApp(app: App): Promise<any>;
|
|
5
|
+
deployWorkflow(workflowKey: string, workflow: WorkflowDefinitionDeclaration, app: App, existingWorkflows: Array<any>, appDeclaration: AppDeclaration): Promise<any>;
|
|
6
|
+
private createNewWorkflowDefinition;
|
|
7
|
+
private populateActionIds;
|
|
8
|
+
private updateWorkflowDefinition;
|
|
9
|
+
getWorkflowDeclarationIdentifier(actionKey: any, app: App): string;
|
|
10
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { Entities } from '@contrail/sdk';
|
|
2
|
+
import chalk from 'chalk';
|
|
3
|
+
import { getActionDeclarationIdentifier, getActionsForApp } from './actions-deployer';
|
|
4
|
+
export class WorkflowDefinitionDeployer {
|
|
5
|
+
async deployWorkflowDefinitions(appDeclaration, app) {
|
|
6
|
+
// FETCH ALL WORKFLOWS FROM THE API.
|
|
7
|
+
const existingWorkflows = await this.getWorkflowDefinitionsForApp(app);
|
|
8
|
+
// UPSERT / DELETE BASED ON WORKFLOW IDENTIFIER
|
|
9
|
+
console.log('%s \tDeploying workflow definitions.', chalk.yellow.bold('WORKFLOW DEFINITION'));
|
|
10
|
+
for (const workflowKey of Object.keys(appDeclaration.workflows)) {
|
|
11
|
+
await this.deployWorkflow(workflowKey, appDeclaration.workflows[workflowKey], app, existingWorkflows, appDeclaration);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
async getWorkflowDefinitionsForApp(app) {
|
|
15
|
+
return await new Entities().get({
|
|
16
|
+
entityName: 'event-workflow-template-definition',
|
|
17
|
+
criteria: { ownerKey: `app:${app.id}` },
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
async deployWorkflow(workflowKey, workflow, app, existingWorkflows, appDeclaration) {
|
|
21
|
+
console.log(`%s \tDeploying workflow definitions: ${workflowKey}`, chalk.yellow.bold('WORKFLOW DEFINITION'));
|
|
22
|
+
const identifier = this.getWorkflowDeclarationIdentifier(workflowKey, app);
|
|
23
|
+
const existingDefinition = existingWorkflows.find(ad => ad.identifier === identifier);
|
|
24
|
+
if (existingDefinition) {
|
|
25
|
+
return await this.updateWorkflowDefinition(existingDefinition, workflow, app, appDeclaration);
|
|
26
|
+
}
|
|
27
|
+
return await this.createNewWorkflowDefinition(workflowKey, workflow, app, appDeclaration);
|
|
28
|
+
}
|
|
29
|
+
async createNewWorkflowDefinition(workflowKey, workflowDeclaration, app, appDeclaration) {
|
|
30
|
+
await this.populateActionIds(workflowDeclaration, appDeclaration, app);
|
|
31
|
+
const newObject = {
|
|
32
|
+
identifier: this.getWorkflowDeclarationIdentifier(workflowKey, app),
|
|
33
|
+
name: workflowDeclaration.name,
|
|
34
|
+
ownerKey: `app:${app.id}`,
|
|
35
|
+
triggerKey: workflowDeclaration.triggerKey,
|
|
36
|
+
workflowDefinition: workflowDeclaration.workflowDefinition,
|
|
37
|
+
public: workflowDeclaration.public,
|
|
38
|
+
isActive: workflowDeclaration.isActive,
|
|
39
|
+
};
|
|
40
|
+
const workflowTemplate = await new Entities().create({
|
|
41
|
+
entityName: 'event-workflow-template-definition',
|
|
42
|
+
object: newObject,
|
|
43
|
+
});
|
|
44
|
+
console.log(`%s Created new workflow definition definitions: ${workflowKey}`, chalk.yellow.bold('WORKFLOW DEFINITION'));
|
|
45
|
+
return workflowTemplate;
|
|
46
|
+
}
|
|
47
|
+
async populateActionIds(workflowDeclaration, appDeclaration, app) {
|
|
48
|
+
var _a;
|
|
49
|
+
let availableAppActions = await getActionsForApp(app);
|
|
50
|
+
if (!((_a = workflowDeclaration.workflowDefinition) === null || _a === void 0 ? void 0 : _a.paths)) {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
for (const path of workflowDeclaration.workflowDefinition.paths) {
|
|
54
|
+
if (!(path === null || path === void 0 ? void 0 : path.actionDefinitionConfigs)) {
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
for (const actionConfiguration of path.actionDefinitionConfigs) {
|
|
58
|
+
const actionKey = actionConfiguration.action;
|
|
59
|
+
const action = availableAppActions.find(action => action.identifier === getActionDeclarationIdentifier(actionKey, app));
|
|
60
|
+
if (!action) {
|
|
61
|
+
throw new Error(`Could not find action ${actionKey} declared in workflow definition ${workflowDeclaration.name}`);
|
|
62
|
+
}
|
|
63
|
+
actionConfiguration.id = action.id;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
async updateWorkflowDefinition(existingWorkflowDefinition, workflowDeclaration, app, appDeclaration) {
|
|
68
|
+
await this.populateActionIds(workflowDeclaration, appDeclaration, app);
|
|
69
|
+
const updates = Object.assign(new Object(), {
|
|
70
|
+
name: workflowDeclaration.name,
|
|
71
|
+
triggerKey: workflowDeclaration.triggerKey,
|
|
72
|
+
workflowDefinition: workflowDeclaration.workflowDefinition
|
|
73
|
+
});
|
|
74
|
+
const updatedWorkflowDefinition = await new Entities().update({
|
|
75
|
+
entityName: 'event-workflow-template-definition',
|
|
76
|
+
id: existingWorkflowDefinition.id,
|
|
77
|
+
object: updates,
|
|
78
|
+
});
|
|
79
|
+
console.log(`%s Updated existing workflow definition: ${updatedWorkflowDefinition.identifier}`, chalk.yellow.bold('WORKFLOW DEFINITION'));
|
|
80
|
+
return updatedWorkflowDefinition;
|
|
81
|
+
}
|
|
82
|
+
getWorkflowDeclarationIdentifier(actionKey, app) {
|
|
83
|
+
return app.identifier + ':' + actionKey;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { App, AppDeclaration,
|
|
1
|
+
import { App, AppDeclaration, WorkflowTemplateDeclaration } from './interfaces';
|
|
2
2
|
export declare class WorkflowDeployer {
|
|
3
3
|
deployWorkflows(appDeclaration: AppDeclaration, app: App): Promise<void>;
|
|
4
4
|
getWorkflowsForApp(app: App): Promise<any>;
|
|
5
|
-
deployWorkflow(workflowKey: string, workflow:
|
|
5
|
+
deployWorkflow(workflowKey: string, workflow: WorkflowTemplateDeclaration, app: App, existingWorkflows: Array<any>, appDeclaration: AppDeclaration): Promise<any>;
|
|
6
6
|
private createNewWorkflowDefinition;
|
|
7
7
|
private populateActionIds;
|
|
8
8
|
private updateWorkflowDefinition;
|
|
@@ -34,7 +34,10 @@ export class WorkflowDeployer {
|
|
|
34
34
|
ownerKey: `app:${app.id}`,
|
|
35
35
|
triggerKey: workflowDeclaration.triggerKey,
|
|
36
36
|
workflowDefinition: workflowDeclaration.workflowDefinition,
|
|
37
|
-
isActive: workflowDeclaration.isActive
|
|
37
|
+
isActive: workflowDeclaration.isActive,
|
|
38
|
+
supportingAppId: workflowDeclaration.supportingAppId,
|
|
39
|
+
messageGroupId: workflowDeclaration.messageGroupId,
|
|
40
|
+
parallelWorkerCount: workflowDeclaration.parallelWorkerCount,
|
|
38
41
|
};
|
|
39
42
|
const workflowTemplate = await new Entities().create({
|
|
40
43
|
entityName: 'event-workflow-template',
|
package/package.json
CHANGED
|
@@ -4,10 +4,11 @@ import { Auth } from '../../auth/auth';
|
|
|
4
4
|
import { ActionsDeployer } from './actions-deployer';
|
|
5
5
|
import { App, AppDeclaration } from './interfaces';
|
|
6
6
|
import { TriggerKeyDefinitionParser, ConfigPropertiesParser } from './app-template-parsers';
|
|
7
|
+
import { WorkflowDefinitionDeployer } from './workflow-definition-deployer';
|
|
7
8
|
import { WorkflowDeployer } from './workflow-deployer';
|
|
8
9
|
|
|
9
10
|
export class AppDeployer {
|
|
10
|
-
public async deploy(appDeclaration: AppDeclaration) {
|
|
11
|
+
public async deploy(appDeclaration: AppDeclaration, deployWorkflowTemplateOnly = false) {
|
|
11
12
|
let app = await this.getExistingApp(appDeclaration);
|
|
12
13
|
if (!app) {
|
|
13
14
|
console.log(`%s Creating new app.`, chalk.yellow.bold('APP'));
|
|
@@ -17,7 +18,11 @@ export class AppDeployer {
|
|
|
17
18
|
app = await this.updateExistingApp(appDeclaration, app);
|
|
18
19
|
}
|
|
19
20
|
await new ActionsDeployer().deployActions(appDeclaration, app);
|
|
20
|
-
|
|
21
|
+
if (deployWorkflowTemplateOnly) {
|
|
22
|
+
await new WorkflowDeployer().deployWorkflows(appDeclaration, app);
|
|
23
|
+
} else {
|
|
24
|
+
await new WorkflowDefinitionDeployer().deployWorkflowDefinitions(appDeclaration, app);
|
|
25
|
+
}
|
|
21
26
|
}
|
|
22
27
|
|
|
23
28
|
public async getExistingApp(appDeclaration: AppDeclaration): Promise<App> {
|
|
@@ -29,10 +29,10 @@ export async function deployApp(args) {
|
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
console.log(`%s Deploying Application. ${appDeclaration.appIdentifier}`, chalk.blue.bold('START'));
|
|
32
|
-
|
|
32
|
+
const templateOnly = args && args.includes('--template-only')
|
|
33
33
|
try {
|
|
34
34
|
await authUser();
|
|
35
|
-
await new AppDeployer().deploy(appDeclaration);
|
|
35
|
+
await new AppDeployer().deploy(appDeclaration, templateOnly);
|
|
36
36
|
}
|
|
37
37
|
catch (e) {
|
|
38
38
|
console.log(`%s Application Deployment Failed. ${e}`, chalk.red.bold('FAIL'));
|
|
@@ -14,7 +14,7 @@ export interface AppDeclaration {
|
|
|
14
14
|
actions?: { [key: string]: AppActionDeclaration };
|
|
15
15
|
appConfiguration: ConfigPropertyElements;
|
|
16
16
|
triggers: { [key: string]: AppTriggerDeclaration };
|
|
17
|
-
workflows?: { [key: string]:
|
|
17
|
+
workflows?: { [key: string]: WorkflowDefinitionDeclaration|WorkflowTemplateDeclaration }
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
export interface ConfigPropertyElements {
|
|
@@ -41,7 +41,20 @@ export interface AppTriggerDeclaration {
|
|
|
41
41
|
description?: string;
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
|
|
44
|
+
|
|
45
|
+
export interface WorkflowDefinitionDeclaration {
|
|
46
|
+
id?: string;
|
|
47
|
+
identifier: string;
|
|
48
|
+
name: string;
|
|
49
|
+
triggerKey: string;
|
|
50
|
+
workflowDefinition: WorkflowDefinition;
|
|
51
|
+
ownerKey: string;
|
|
52
|
+
isActive: boolean;
|
|
53
|
+
public: boolean;
|
|
54
|
+
supportingAppId?: string;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export interface WorkflowTemplateDeclaration {
|
|
45
58
|
id?: string;
|
|
46
59
|
identifier: string;
|
|
47
60
|
name: string;
|
|
@@ -49,6 +62,9 @@ export interface WorkflowDeclaration {
|
|
|
49
62
|
workflowDefinition: WorkflowDefinition;
|
|
50
63
|
ownerKey: string;
|
|
51
64
|
isActive: boolean;
|
|
65
|
+
supportingAppId?: string;
|
|
66
|
+
messageGroupId?: string;
|
|
67
|
+
parallelWorkerCount?: number;
|
|
52
68
|
}
|
|
53
69
|
|
|
54
70
|
export interface WorkflowDefinition {
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { Entities } from '@contrail/sdk';
|
|
2
|
+
import chalk from 'chalk';
|
|
3
|
+
import { App, AppDeclaration, WorkflowDefinitionDeclaration } from './interfaces';
|
|
4
|
+
import { getActionDeclarationIdentifier, getActionsForApp } from './actions-deployer'
|
|
5
|
+
|
|
6
|
+
export class WorkflowDefinitionDeployer {
|
|
7
|
+
async deployWorkflowDefinitions(appDeclaration: AppDeclaration, app: App) {
|
|
8
|
+
|
|
9
|
+
// FETCH ALL WORKFLOWS FROM THE API.
|
|
10
|
+
const existingWorkflows = await this.getWorkflowDefinitionsForApp(app);
|
|
11
|
+
|
|
12
|
+
// UPSERT / DELETE BASED ON WORKFLOW IDENTIFIER
|
|
13
|
+
console.log('%s \tDeploying workflow definitions.', chalk.yellow.bold('WORKFLOW DEFINITION'));
|
|
14
|
+
|
|
15
|
+
for (const workflowKey of Object.keys(appDeclaration.workflows)) {
|
|
16
|
+
await this.deployWorkflow(
|
|
17
|
+
workflowKey, appDeclaration.workflows[workflowKey] as WorkflowDefinitionDeclaration,
|
|
18
|
+
app,
|
|
19
|
+
existingWorkflows,
|
|
20
|
+
appDeclaration
|
|
21
|
+
);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
async getWorkflowDefinitionsForApp(app: App) {
|
|
26
|
+
return await new Entities().get({
|
|
27
|
+
entityName: 'event-workflow-template-definition',
|
|
28
|
+
criteria: { ownerKey: `app:${app.id}` },
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
async deployWorkflow(workflowKey: string, workflow: WorkflowDefinitionDeclaration, app: App, existingWorkflows: Array<any>, appDeclaration: AppDeclaration) {
|
|
33
|
+
console.log(`%s \tDeploying workflow definitions: ${workflowKey}`, chalk.yellow.bold('WORKFLOW DEFINITION'));
|
|
34
|
+
|
|
35
|
+
const identifier = this.getWorkflowDeclarationIdentifier(workflowKey, app);
|
|
36
|
+
const existingDefinition = existingWorkflows.find(ad => ad.identifier === identifier);
|
|
37
|
+
|
|
38
|
+
if (existingDefinition) {
|
|
39
|
+
return await this.updateWorkflowDefinition(existingDefinition, workflow, app, appDeclaration);
|
|
40
|
+
}
|
|
41
|
+
return await this.createNewWorkflowDefinition(workflowKey, workflow, app, appDeclaration);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
private async createNewWorkflowDefinition(workflowKey: string, workflowDeclaration: WorkflowDefinitionDeclaration, app: App, appDeclaration: AppDeclaration) {
|
|
45
|
+
await this.populateActionIds(workflowDeclaration, appDeclaration, app);
|
|
46
|
+
const newObject: WorkflowDefinitionDeclaration = {
|
|
47
|
+
identifier: this.getWorkflowDeclarationIdentifier(workflowKey, app),
|
|
48
|
+
name: workflowDeclaration.name,
|
|
49
|
+
ownerKey: `app:${app.id}`,
|
|
50
|
+
triggerKey: workflowDeclaration.triggerKey,
|
|
51
|
+
workflowDefinition: workflowDeclaration.workflowDefinition,
|
|
52
|
+
public: workflowDeclaration.public,
|
|
53
|
+
isActive: workflowDeclaration.isActive,
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
const workflowTemplate = await new Entities().create({
|
|
57
|
+
entityName: 'event-workflow-template-definition',
|
|
58
|
+
object: newObject,
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
console.log(`%s Created new workflow definition definitions: ${workflowKey}`, chalk.yellow.bold('WORKFLOW DEFINITION'));
|
|
62
|
+
|
|
63
|
+
return workflowTemplate;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
private async populateActionIds(workflowDeclaration: WorkflowDefinitionDeclaration, appDeclaration: AppDeclaration, app: App) {
|
|
67
|
+
let availableAppActions = await getActionsForApp(app);
|
|
68
|
+
if (!workflowDeclaration.workflowDefinition?.paths) {
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
for (const path of workflowDeclaration.workflowDefinition.paths) {
|
|
72
|
+
if (!path?.actionDefinitionConfigs) {
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
for (const actionConfiguration of path.actionDefinitionConfigs) {
|
|
76
|
+
const actionKey = actionConfiguration.action;
|
|
77
|
+
const action = availableAppActions.find(
|
|
78
|
+
action => action.identifier === getActionDeclarationIdentifier(actionKey, app)
|
|
79
|
+
)
|
|
80
|
+
if (!action) {
|
|
81
|
+
throw new Error(`Could not find action ${actionKey} declared in workflow definition ${workflowDeclaration.name}`);
|
|
82
|
+
}
|
|
83
|
+
actionConfiguration.id = action.id;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
private async updateWorkflowDefinition(existingWorkflowDefinition: WorkflowDefinitionDeclaration, workflowDeclaration: WorkflowDefinitionDeclaration, app: App, appDeclaration: AppDeclaration) {
|
|
89
|
+
await this.populateActionIds(workflowDeclaration, appDeclaration, app);
|
|
90
|
+
const updates = Object.assign(new Object(), {
|
|
91
|
+
name: workflowDeclaration.name,
|
|
92
|
+
triggerKey: workflowDeclaration.triggerKey,
|
|
93
|
+
workflowDefinition: workflowDeclaration.workflowDefinition
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
const updatedWorkflowDefinition = await new Entities().update({
|
|
97
|
+
entityName: 'event-workflow-template-definition',
|
|
98
|
+
id: existingWorkflowDefinition.id,
|
|
99
|
+
object: updates,
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
console.log(`%s Updated existing workflow definition: ${updatedWorkflowDefinition.identifier}`, chalk.yellow.bold('WORKFLOW DEFINITION'));
|
|
103
|
+
|
|
104
|
+
return updatedWorkflowDefinition;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
getWorkflowDeclarationIdentifier(actionKey, app: App) {
|
|
108
|
+
return app.identifier + ':' + actionKey;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Entities } from '@contrail/sdk';
|
|
2
2
|
import chalk from 'chalk';
|
|
3
|
-
import { App, AppDeclaration,
|
|
4
|
-
import {getActionDeclarationIdentifier, getActionsForApp} from './actions-deployer'
|
|
3
|
+
import { App, AppDeclaration, WorkflowTemplateDeclaration } from './interfaces';
|
|
4
|
+
import { getActionDeclarationIdentifier, getActionsForApp } from './actions-deployer'
|
|
5
5
|
|
|
6
6
|
export class WorkflowDeployer {
|
|
7
7
|
async deployWorkflows(appDeclaration: AppDeclaration, app: App) {
|
|
@@ -13,7 +13,11 @@ export class WorkflowDeployer {
|
|
|
13
13
|
console.log('%s \tDeploying workflows.', chalk.yellow.bold('WORKFLOW'));
|
|
14
14
|
|
|
15
15
|
for (const workflowKey of Object.keys(appDeclaration.workflows)) {
|
|
16
|
-
await this.deployWorkflow(workflowKey,
|
|
16
|
+
await this.deployWorkflow(workflowKey,
|
|
17
|
+
appDeclaration.workflows[workflowKey] as WorkflowTemplateDeclaration,
|
|
18
|
+
app,
|
|
19
|
+
existingWorkflows,
|
|
20
|
+
appDeclaration);
|
|
17
21
|
}
|
|
18
22
|
}
|
|
19
23
|
|
|
@@ -24,7 +28,7 @@ export class WorkflowDeployer {
|
|
|
24
28
|
});
|
|
25
29
|
}
|
|
26
30
|
|
|
27
|
-
async deployWorkflow(workflowKey: string, workflow:
|
|
31
|
+
async deployWorkflow(workflowKey: string, workflow: WorkflowTemplateDeclaration, app: App, existingWorkflows: Array<any>, appDeclaration: AppDeclaration) {
|
|
28
32
|
console.log(`%s \tDeploying workflow: ${workflowKey}`, chalk.yellow.bold('WORKFLOW'));
|
|
29
33
|
|
|
30
34
|
const identifier = this.getWorkflowDeclarationIdentifier(workflowKey, app);
|
|
@@ -36,15 +40,18 @@ export class WorkflowDeployer {
|
|
|
36
40
|
return await this.createNewWorkflowDefinition(workflowKey, workflow, app, appDeclaration);
|
|
37
41
|
}
|
|
38
42
|
|
|
39
|
-
private async createNewWorkflowDefinition(workflowKey: string, workflowDeclaration:
|
|
43
|
+
private async createNewWorkflowDefinition(workflowKey: string, workflowDeclaration: WorkflowTemplateDeclaration, app: App, appDeclaration: AppDeclaration) {
|
|
40
44
|
await this.populateActionIds(workflowDeclaration, appDeclaration, app);
|
|
41
|
-
const newObject:
|
|
45
|
+
const newObject: WorkflowTemplateDeclaration = {
|
|
42
46
|
identifier: this.getWorkflowDeclarationIdentifier(workflowKey, app),
|
|
43
47
|
name: workflowDeclaration.name,
|
|
44
48
|
ownerKey: `app:${app.id}`,
|
|
45
49
|
triggerKey: workflowDeclaration.triggerKey,
|
|
46
50
|
workflowDefinition: workflowDeclaration.workflowDefinition,
|
|
47
|
-
isActive: workflowDeclaration.isActive
|
|
51
|
+
isActive: workflowDeclaration.isActive,
|
|
52
|
+
supportingAppId: workflowDeclaration.supportingAppId,
|
|
53
|
+
messageGroupId: workflowDeclaration.messageGroupId,
|
|
54
|
+
parallelWorkerCount: workflowDeclaration.parallelWorkerCount,
|
|
48
55
|
};
|
|
49
56
|
|
|
50
57
|
const workflowTemplate = await new Entities().create({
|
|
@@ -57,16 +64,16 @@ export class WorkflowDeployer {
|
|
|
57
64
|
return workflowTemplate;
|
|
58
65
|
}
|
|
59
66
|
|
|
60
|
-
private async populateActionIds(workflowDeclaration:
|
|
67
|
+
private async populateActionIds(workflowDeclaration: WorkflowTemplateDeclaration, appDeclaration: AppDeclaration, app: App) {
|
|
61
68
|
let availableAppActions = await getActionsForApp(app);
|
|
62
|
-
if(!workflowDeclaration.workflowDefinition?.paths) {
|
|
69
|
+
if (!workflowDeclaration.workflowDefinition?.paths) {
|
|
63
70
|
return;
|
|
64
71
|
}
|
|
65
|
-
for(const path of workflowDeclaration.workflowDefinition.paths){
|
|
66
|
-
if(!path?.actionDefinitionConfigs) {
|
|
72
|
+
for (const path of workflowDeclaration.workflowDefinition.paths) {
|
|
73
|
+
if (!path?.actionDefinitionConfigs) {
|
|
67
74
|
continue;
|
|
68
75
|
}
|
|
69
|
-
for(const actionConfiguration of path.actionDefinitionConfigs) {
|
|
76
|
+
for (const actionConfiguration of path.actionDefinitionConfigs) {
|
|
70
77
|
const actionKey = actionConfiguration.action;
|
|
71
78
|
const action = availableAppActions.find(
|
|
72
79
|
action => action.identifier === getActionDeclarationIdentifier(actionKey, app)
|
|
@@ -79,7 +86,7 @@ export class WorkflowDeployer {
|
|
|
79
86
|
}
|
|
80
87
|
}
|
|
81
88
|
|
|
82
|
-
private async updateWorkflowDefinition(existingWorkflowDefinition:
|
|
89
|
+
private async updateWorkflowDefinition(existingWorkflowDefinition: WorkflowTemplateDeclaration, workflowDeclaration: WorkflowTemplateDeclaration, app: App, appDeclaration: AppDeclaration) {
|
|
83
90
|
await this.populateActionIds(workflowDeclaration, appDeclaration, app);
|
|
84
91
|
const updates = Object.assign(new Object(), {
|
|
85
92
|
name: workflowDeclaration.name,
|
|
@@ -38,17 +38,16 @@ triggers:
|
|
|
38
38
|
external: true
|
|
39
39
|
description: "Triggers on externally created products"
|
|
40
40
|
|
|
41
|
-
#
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
41
|
+
# workflows:
|
|
42
|
+
# workflow1:
|
|
43
|
+
# triggerKey: item|update
|
|
44
|
+
# isActive: true
|
|
45
|
+
# name: test wf from cli
|
|
46
|
+
# workflowDefinition:
|
|
47
|
+
# paths:
|
|
48
|
+
# - conditional: "true"
|
|
49
|
+
# actionDefinitionConfigs:
|
|
50
|
+
# - action: updateProduct
|
|
51
|
+
# name: handle product update
|
|
52
|
+
# config:
|
|
53
|
+
# message: "hello world"
|