├── .eslintignore ├── .eslintrc ├── .gitignore ├── CHANGELOG.md ├── CONTRIBUTION.md ├── CORPORATE_CLA.md ├── Coding_Guidelines.md ├── Dockerfile ├── Gruntfile.js ├── INDIVIDUAL_CLA.md ├── ISSUES.md ├── LICENSE ├── README.md ├── common ├── activiti-models │ ├── activiti-account.js │ ├── activiti-account.json │ ├── activiti-base-entity.json │ ├── activiti-manager.js │ ├── activiti-manager.json │ ├── activiti-workflow-request.js │ ├── activiti-workflow-request.json │ ├── datasources │ │ ├── ds-activiti-deployment.json │ │ ├── ds-activiti-engine.json │ │ ├── ds-activiti-execution.json │ │ ├── ds-activiti-form.json │ │ ├── ds-activiti-group.json │ │ ├── ds-activiti-history.json │ │ ├── ds-activiti-job.json │ │ ├── ds-activiti-model.json │ │ ├── ds-activiti-process-definition.json │ │ ├── ds-activiti-process-instance.json │ │ ├── ds-activiti-runtime.json │ │ ├── ds-activiti-table.json │ │ ├── ds-activiti-task.json │ │ └── ds-activiti-user.json │ ├── dynamic-models │ │ ├── activiti-deployment.js │ │ ├── activiti-deployment.json │ │ ├── activiti-engine.js │ │ ├── activiti-engine.json │ │ ├── activiti-execution.js │ │ ├── activiti-execution.json │ │ ├── activiti-form.js │ │ ├── activiti-form.json │ │ ├── activiti-group.js │ │ ├── activiti-group.json │ │ ├── activiti-history.js │ │ ├── activiti-history.json │ │ ├── activiti-job.js │ │ ├── activiti-job.json │ │ ├── activiti-model.js │ │ ├── activiti-model.json │ │ ├── activiti-process-definition.js │ │ ├── activiti-process-definition.json │ │ ├── activiti-process-instance.js │ │ ├── activiti-process-instance.json │ │ ├── activiti-runtime.js │ │ ├── activiti-runtime.json │ │ ├── activiti-table.js │ │ ├── activiti-table.json │ │ ├── activiti-task.js │ │ ├── activiti-task.json │ │ ├── activiti-user.js │ │ └── activiti-user.json │ └── lib │ │ ├── helper.js │ │ ├── register.js │ │ └── util.js ├── mixins │ ├── maker-checker-mixin-v1.js │ ├── maker-checker-mixin-v2.js │ └── workflow-mixin.js └── models │ ├── bpmndata.js │ ├── bpmndata.json │ ├── change-workflow-request.json │ ├── durableTimeout.json │ ├── process-definition.js │ ├── process-definition.json │ ├── process-instance.js │ ├── process-instance.json │ ├── task.js │ ├── task.json │ ├── workflow-base-entity.js │ ├── workflow-base-entity.json │ ├── workflow-definition.js │ ├── workflow-definition.json │ ├── workflow-instance.js │ ├── workflow-instance.json │ ├── workflow-manager.js │ ├── workflow-manager.json │ ├── workflow-mapping.js │ ├── workflow-mapping.json │ ├── workflow-request.js │ ├── workflow-request.json │ ├── workflow-signal.js │ └── workflow-signal.json ├── docker-compose.yml ├── index.js ├── lib ├── parsing │ ├── activity.js │ ├── boundaryevents.js │ ├── buildFlowObjects.js │ ├── callactivity.js │ ├── collaborationdefinition.js │ ├── definitions.js │ ├── endevents.js │ ├── errors.js │ ├── events.js │ ├── evtags.js │ ├── flowobject.js │ ├── gateways.js │ ├── intermediateevents.js │ ├── lanes.js │ ├── messageflows.js │ ├── parse-utils │ │ ├── in-out-mappings.js │ │ └── input-output-parameters.js │ ├── parser.js │ ├── participant.js │ ├── processdefinition.js │ ├── sequenceflows.js │ ├── startevents.js │ ├── subprocess.js │ ├── taskmarkers.js │ └── tasks.js ├── utils │ ├── maker-checker-helper-v2.js │ ├── maker-checker-helper.js │ ├── oe-date-utils.js │ ├── process-state-delta.js │ ├── process-tokens.js │ ├── throwobject.js │ ├── timeout-calculator.js │ ├── timeouts.js │ ├── tokenemission.js │ └── workflow-utils.js ├── workflow-eventHandlers │ ├── catcheventhandler.js │ ├── processterminatehandlers.js │ ├── subprocesshandlers.js │ ├── taskeventhandler.js │ └── tokeneventhandler.js ├── workflow-nodes │ ├── businessruletask-node.js │ ├── evaluate-flow-object.js │ ├── evaluate-sequence-flow.js │ ├── sandbox.js │ └── service-node.js └── wrapper.js ├── package.json ├── server ├── boot │ ├── 01-load-addon.js │ ├── 03-attach-workflow.js │ └── 05-workflow-recovery.js ├── middleware.json ├── model-config.json └── server.js ├── test ├── app-list.json ├── boot │ └── populate-data.js ├── bootstrap.js ├── bpmn-files │ ├── Adjustments.xlsx │ ├── DecisionTableData.json │ ├── DecisionTreeData.json │ ├── Service.xlsx │ ├── business-rule-decision-service.bpmn │ ├── business-rule-decision-table.bpmn │ ├── business-rule-decision-tree.bpmn │ ├── call-activity-child.bpmn │ ├── call-activity-main.bpmn │ ├── collaboration-collapsed.bpmn │ ├── collaboration.bpmn │ ├── conditional-boundary-interrupting.bpmn │ ├── conditional-boundary-non-interrupting.bpmn │ ├── conditional-intermediate-catch.bpmn │ ├── correlationid-maker-checker.bpmn │ ├── correlationid.bpmn │ ├── dynamic-timer-boundary.bpmn │ ├── dynamic-timer-intermediate-parallel.bpmn │ ├── dynamic-timer-intermediate.bpmn │ ├── dynamic-timer-start.bpmn │ ├── error-event-child.bpmn │ ├── error-event-main.bpmn │ ├── escalate-event-child.bpmn │ ├── escalate-event-main.bpmn │ ├── eventbased-gateway.bpmn │ ├── exclusive-gateway.bpmn │ ├── inclusive-gateway-complex.bpmn │ ├── inclusive-gateway-simple.bpmn │ ├── internal-messaging.bpmn │ ├── lanes-pools.bpmn │ ├── link-event.bpmn │ ├── maker-checker-v1.bpmn │ ├── maker-checker-v2-custom-remote.bpmn │ ├── maker-checker-v2-multi.bpmn │ ├── maker-checker-v2.bpmn │ ├── message-boundary-interrupting.bpmn │ ├── message-boundary-non-interrupting.bpmn │ ├── message-end.bpmn │ ├── message-start-send.bpmn │ ├── message-start-throw.bpmn │ ├── multi-instance-parallel-child.bpmn │ ├── multi-instance-parallel.bpmn │ ├── multi-instance-sequential.bpmn │ ├── nested-subprocess-interrupting.bpmn │ ├── parallel-gateway.bpmn │ ├── script-task.bpmn │ ├── service-task-oe-connector.bpmn │ ├── service-task-rest.bpmn │ ├── signal-boundary-interrupting.bpmn │ ├── signal-boundary-non-interrupting.bpmn │ ├── signal-inter-process-catch.bpmn │ ├── signal-inter-process-throw.bpmn │ ├── signal-intra-process-boundary.bpmn │ ├── signal-intra-process-start.bpmn │ ├── signal-intra-process.bpmn │ ├── step-variables.bpmn │ ├── sub-process.bpmn │ ├── subprocess-boundary-interrupting.bpmn │ ├── terminate-end-event.bpmn │ ├── timer-boundary-p.bpmn │ ├── timer-boundary.bpmn │ ├── timer-intermediate-p.bpmn │ ├── timer-intermediate-parallel.bpmn │ ├── timer-intermediate.bpmn │ ├── timer-start.bpmn │ ├── update-via-workflow.bpmn │ ├── user-task-hook.bpmn │ ├── user-task-ui.bpmn │ ├── user-task.bpmn │ ├── workflow-manager.bpmn │ ├── workflow-mixin-v0.bpmn │ ├── workflow-recovery-child.bpmn │ ├── workflow-recovery-parent.bpmn │ ├── workflow-versioning-1.bpmn │ └── workflow-versioning-2.bpmn ├── common │ └── models │ │ ├── Address.json │ │ ├── AddressV1.json │ │ ├── AddressV2.json │ │ ├── LuckyDraw.json │ │ ├── OrderV0.js │ │ ├── OrderV0.json │ │ ├── OrderV1.json │ │ ├── OrderV2.json │ │ ├── Person.json │ │ ├── Stock.json │ │ ├── StoreV0.json │ │ ├── StoreV1.json │ │ └── StoreV2.json ├── component-config.json ├── config.json ├── datasources.json ├── datasources.mongo.js ├── datasources.oracle.js ├── datasources.postgres.js ├── failTest.sh ├── middleware.json ├── model-config.json ├── oracle-utility.js ├── performance │ ├── oe-workflow-performance-test.bpmn │ └── oe-workflow.jmx ├── scripts │ ├── activiti-integration-tests.js │ ├── business-rule-task-tests.js │ ├── call-activity-tests.js │ ├── collaboration-tests.js │ ├── conditional-boundary-interrupting-tests.js │ ├── conditional-boundary-non-interrupting-tests.js │ ├── conditional-intermediate-catch-tests.js │ ├── correlationid-maker-checker-tests.js │ ├── correlationid-tests.js │ ├── date-util-test.js │ ├── dynamic-timer-boundary-tests.js │ ├── dynamic-timer-intermediate-parallel-tests.js │ ├── dynamic-timer-intermediate-tests.js │ ├── dynamic-timer-start-tests.js │ ├── error-event-tests.js │ ├── escalate-event-tests.js │ ├── eventbased-gateway-tests.js │ ├── exclusive-gateway-tests.js │ ├── inclusive-gateway-complex-tests.js │ ├── inclusive-gateway-simple-tests.js │ ├── internal-messaging-tests.js │ ├── lanes-pools-tests.js │ ├── link-event-tests.js │ ├── maker-checker-v1-tests.js │ ├── maker-checker-v2-basic-tests.js │ ├── maker-checker-v2-custom-tests.js │ ├── maker-checker-v2-multi-tests.js │ ├── message-boundary-interrupting-tests.js │ ├── message-boundary-non-interrupting-tests.js │ ├── message-end-tests.js │ ├── message-start-send-tests.js │ ├── message-start-throw-tests.js │ ├── multi-instance-parallel-tests.js │ ├── multi-instance-sequential-tests.js │ ├── nested-subprocess-interrupting-tests.js │ ├── parallel-gateway-tests.js │ ├── script-task-tests.js │ ├── service-task-oe-connector.js │ ├── service-task-rest.js │ ├── signal-boundary-interrupting-tests.js │ ├── signal-boundary-non-interrupting-tests.js │ ├── signal-inter-process-tests.js │ ├── signal-intra-process-boundary-tests.js │ ├── signal-intra-process-start-tests.js │ ├── signal-intra-process-tests.js │ ├── step-variables-tests.js │ ├── sub-process-tests.js │ ├── subprocess-boundary-interrupting-tests.js │ ├── terminate-end-event-tests.js │ ├── timeout-calculator-tests.js │ ├── timer-boundary-p-tests.js │ ├── timer-boundary-tests.js │ ├── timer-intermediate-p-tests.js │ ├── timer-intermediate-parallel-tests.js │ ├── timer-intermediate-tests.js │ ├── timer-start-tests.js │ ├── update-via-workflow-tests.js │ ├── user-task-hook-tests.js │ ├── user-task-tests.js │ ├── user-task-ui-tests.js │ ├── workflow-manager-tests.js │ ├── workflow-mixin-v0-basic-tests.js │ ├── workflow-recovery-tests.js │ └── workflow-versioning-tests.js ├── server.js └── utils │ ├── addon-functions.js │ └── state-verifier.js └── utils └── addon-functions.js /.eslintignore: -------------------------------------------------------------------------------- 1 | build/ 2 | client/ 3 | coverage/ 4 | node_modules/ 5 | test/ 6 | drop.js 7 | Gruntfile.js 8 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | package-lock.json 2 | *.csv 3 | *.dat 4 | *.iml 5 | *.log 6 | *.un 7 | *.un~ 8 | *.out 9 | *.pid 10 | *.seed 11 | *.sublime-* 12 | *.swo 13 | *.swp 14 | *.tgz 15 | *.xml 16 | .DS_Store 17 | .idea 18 | .project 19 | .strong-pm 20 | .vscode/ 21 | tags 22 | coverage 23 | node_modules 24 | npm-debug.log 25 | client 26 | nodered 27 | builds 28 | dev 29 | *.suo 30 | *.sln 31 | *.dll 32 | /obj/Debug 33 | /.vs/config/applicationhost.config 34 | /oe.njsperf 35 | .vimrc 36 | test/bpmn-files-todo 37 | test/todo 38 | *.js1 39 | oracle-user.sh 40 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | 2018-07-30, Version 2.x 2 | ========================= 3 | * oe-connector, model name evaluation expression, replace msg('prop') as msg.prop 4 | * User task expressions, replace $variable as ${pv.variable} 5 | * /api/Tasks will NOT filter the records. Use separate API GET /api/Tasks/filtered/ 6 | * For task filtering, user group is now taken from options.ctx.group (as opposed to older options.ctx.department) 7 | * Pools and Lanes, now you can use expressions in names to specify dynamic user, group, role. 8 | e.g. "User:${...}", "Group:${...}", "Role:${...}" 9 | 10 | * Sequential Multi-Instance now populates _iteration and elementVariable in inVariables. It can be used in pv(...) expressions. 11 | 12 | * Message passed to next node msg.msg should be replaced as msg 13 | 2018-01-03, Version 1.2.0 14 | ========================= 15 | 16 | * Implementation of Maker Checker Version 2 17 | * Rework functionality for Maker Checker 18 | * Additional attributes Due Date, Followup Date and Priority for User Task 19 | * Input-Output variable mapping for Call Activity and Subprocess 20 | 21 | 2017-11-17, Version 1.1.1 22 | ========================= 23 | 24 | * Process definition relation fix 25 | * Uninitailzed variables bug fix maker-checker 26 | 27 | 2017-10-31, Version 1.1.0 28 | ========================= 29 | 30 | * Workflow versioning enabled 31 | * form support on user task 32 | * duplicate bpmn template fix 33 | * recovery fix for user task creation 34 | * /workflow & /task api stability fix 35 | 36 | 2017-10-11, Version 1.0.0 37 | ========================= 38 | 39 | * Initial Commit 40 | -------------------------------------------------------------------------------- /CONTRIBUTION.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | Thank you for your interest in oe-workflow, an open source project administered by EdgeVerve. 4 | 5 | 6 | ## Raising issues 7 | 8 | Please raise any bug reports on the relevant project's issue tracker. Be sure to 9 | search the list to see if your issue has already been raised. 10 | 11 | A good bug report is one that make it easy for us to understand what you were 12 | trying to do and what went wrong. 13 | 14 | 15 | ### Contributor License Agreement 16 | 17 | You must sign a Contributor License Agreement (CLA) before submitting your pull request. To complete the CLA, please email a signed .pdf file of this Agreement to IPC@EdgeVerve.com. You need to complete the CLA only once to cover all EdgeVerve projects. 18 | 19 | You can download the CLAs here: 20 | - [Individual Contributer License Agreement](./INDIVIDUAL_CLA.md) 21 | - [Corporate Contributer License Agreement](./CORPORATE_CLA.md) 22 | 23 | If you are an Infosys employee, please contact us directly as the contribution process is 24 | slightly different. 25 | 26 | ### Coding standards 27 | 28 | Please ensure you follow the coding standards used through-out the existing code base. -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ${REGISTRY}/alpine-node:12-alpine 2 | 3 | RUN mkdir -p /home/src 4 | 5 | EXPOSE 3000 6 | 7 | ENV NODE_ENV docker 8 | ENV MONGO_HOST mongo 9 | ENV POSTGRES_HOST postgres 10 | 11 | WORKDIR /home/src 12 | 13 | COPY . /home/src 14 | 15 | CMD node bin/app.js 16 | -------------------------------------------------------------------------------- /Gruntfile.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * ©2018-2019 EdgeVerve Systems Limited (a fully owned Infosys subsidiary), 4 | * Bangalore, India. All Rights Reserved. 5 | * 6 | */ 7 | 8 | module.exports = function GruntConfig(grunt) { 9 | // Project configuration. 10 | grunt.initConfig({ 11 | pkg: grunt.file.readJSON('package.json'), 12 | 13 | lint: { 14 | target: [ 15 | 'common/**/*.js', 16 | 'server/**/*.js', 17 | 'test/**/*.js' 18 | ] 19 | }, 20 | 21 | clean: { 22 | coverage: { 23 | src: ['coverage/'] 24 | }, 25 | dist: { 26 | src: ['dist/'] 27 | } 28 | }, 29 | 30 | mocha_istanbul: { 31 | options: { 32 | mochaOptions: ['--exit'] 33 | }, 34 | coverage: { 35 | src: ['test/bootstrap.js', 'test/scripts/*.js'], 36 | options: { 37 | timeout: 5000, 38 | check: { 39 | lines: 80, 40 | statements: 80, 41 | branches: 70, 42 | functions: 80 43 | }, 44 | reportFormats: ['lcov'] 45 | } 46 | } 47 | } 48 | }); 49 | 50 | // Add the grunt-mocha-test tasks. 51 | grunt.loadNpmTasks('grunt-contrib-clean'); 52 | grunt.loadNpmTasks('grunt-mocha-istanbul'); 53 | 54 | grunt.loadNpmTasks('grunt-eslint'); 55 | 56 | grunt.registerTask('all', ['lint', 'clean:coverage', 'mocha_istanbul']); 57 | grunt.registerTask('test-with-coverage', ['clean:coverage', 'mocha_istanbul']); 58 | }; 59 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | Copyright (c) 2015-2016 EdgeVerve 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 5 | 6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 7 | 8 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # OE Workflow Engine 2 | 3 | _oe-workflow_ is a **BPMN 2.0** compliant workflow engine built on [oe-cloud](https://github.com/edgeverve/oe-cloud). 4 | _oe-workflow_ is a production grade workflow engine written in _Node.js_. The number of implemented bpmn-elements are comparable to popular industry standard workflow engines like _jBPM, camunda, activiti_. The exhaustive list 5 | can be found in the wiki. Minimal coding is required from _workflow design creation_ to _deployment_. We provide various built-in connectors like _REST_, _oe-connector_ etc. 6 | 7 | ## What is BPMN 2.0 ? 8 | _Business Process Model and Notation_ (BPMN) is a graphical representation for specifying business processes in a business process model. It is the standard in business process modeling used widely by enterprises. 9 | 10 | ## Workflow Models and Elements 11 | _oe-workflow_ can be interacted and managed through either function level API's or Rest Endpoints exposed by the following models. 12 | 13 | |ModelName|Description| 14 | |---------|-----------| 15 | |WorkflowDefinition| This model maintains details about all the workflows that have been published. Each Workflow definition can have multiple Process Definitions| 16 | |WorkflowInstance | This model maintains details of instances of the workflows that are executed. Each WorkflowInstance can have multiple Process Instances| 17 | |ProcessDefinition|This model maintains details about all the process definitions deployed and generated through WorkflowDefinition.| 18 | |ProcessInstance|This model maintain details of a created Process Instances by WorkflowInstance. This model maintains process states, process variables, messages, etc. | 19 | |Task|This model is used to manage user tasks for a process instance executing a Workflow.| 20 | |Workflow Manager|This model maintains details pertaining to which workflows are attached to which models. | 21 | 22 | ## Prerequisites 23 | * Nodejs (LTS) 24 | * MongoDB 25 | 26 | ## Getting Started 27 | * Clone the git repository for refapp ```git clone https://github.com/EdgeVerve/oe-workflow.git``` 28 | * Install Node modules ``` npm install ``` 29 | * Start the Application ```npm run app``` 30 | 31 | ## Coding Guidelines 32 | Please refer to [Coding Guidlines](./Coding_Guidelines.md) document. 33 | > Run `grunt eslint-test-coverage` to verify code quality. 34 | 35 | ## Development Pre-requisites 36 | * [loopback](https://loopback.io/) 37 | * [oe-cloud](http://oecloud.io/) 38 | * [BPMN 2.0 spec](http://www.omg.org/spec/BPMN/2.0/) 39 | 40 | ## More information 41 | Please refer wiki documentation for more information on installation and usage. 42 | 43 | ## License 44 | The project is licensed under MIT License, See [LICENSE](./LICENSE) for more details. 45 | 46 | ## Contributing 47 | We welcome contributions. Some of the best ways to contribute are to try things out, file bugs, and join in design conversations. 48 | 49 | ### [How to contribute](./CONTRIBUTION.md) -------------------------------------------------------------------------------- /common/activiti-models/activiti-account.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * ©2016-2017 EdgeVerve Systems Limited (a fully owned Infosys subsidiary), 4 | * Bangalore, India. All Rights Reserved. 5 | * 6 | */ 7 | 8 | var logger = require('oe-logger'); 9 | var log = logger('ActivitiAccount'); 10 | 11 | module.exports = function ActivitiAccount(ActivitiAccount) { 12 | ActivitiAccount.disableRemoteMethodByName('create', false); 13 | ActivitiAccount.disableRemoteMethodByName('upsert', false); 14 | ActivitiAccount.disableRemoteMethodByName('updateAll', true); 15 | // ActivitiAccount.disableRemoteMethod('updateAttributes', false); 16 | ActivitiAccount.disableRemoteMethodByName('find', false); 17 | ActivitiAccount.disableRemoteMethodByName('findById', true); 18 | ActivitiAccount.disableRemoteMethodByName('findOne', true); 19 | ActivitiAccount.disableRemoteMethodByName('deleteById', true); 20 | ActivitiAccount.disableRemoteMethodByName('count', true); 21 | ActivitiAccount.disableRemoteMethodByName('createChangeStream', true); 22 | ActivitiAccount.disableRemoteMethodByName('exists', true); 23 | ActivitiAccount.disableRemoteMethodByName('history', true); 24 | ActivitiAccount.disableRemoteMethodByName('updateById', true); 25 | ActivitiAccount.disableRemoteMethodByName('deleteWithVersion', false); 26 | 27 | ActivitiAccount.observe('before save', function beforeSaveAA(ctx, next) { 28 | if (ctx.instance && ctx.isNewInstance) { 29 | ActivitiAccount.find({}, ctx.options, function fetchExistingActivitAccount(err, instance) { 30 | /* istanbul ignore if*/ 31 | if (err) { 32 | log.error(ctx.options, err); 33 | return next(err); 34 | } 35 | if (instance.length === 0) { 36 | // no existing account so create 37 | return next(); 38 | } 39 | err = new Error('Activiti account already exists'); 40 | log.error(ctx.options, err.message); 41 | return next(err); 42 | }); 43 | } else { 44 | next(); 45 | } 46 | }); 47 | 48 | ActivitiAccount.observe('access', function limitToUser(ctx, next) { 49 | let userName; 50 | if (ctx && ctx.options && ctx.options.ctx) { 51 | userName = ctx.options.ctx.username; 52 | } 53 | if (!userName) { 54 | var err = new Error('Unauthorized'); 55 | err.status = 401; 56 | return next(err); 57 | } 58 | ctx.query.where = ctx.query.where || {}; 59 | ctx.query.where._createdBy = userName; 60 | next(); 61 | }); 62 | }; 63 | -------------------------------------------------------------------------------- /common/activiti-models/activiti-account.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Activiti_Account", 3 | "base": "BaseEntity", 4 | "description" : "Stores Activiti Account Info", 5 | "options": { 6 | "validateUpsert": true 7 | }, 8 | "properties": { 9 | "username": { 10 | "type": "string", 11 | "required": true 12 | }, 13 | "password": { 14 | "type": "string", 15 | "encrypt": true, 16 | "required": true 17 | } 18 | }, 19 | "mixins" : { 20 | "HistoryMixin" : false, 21 | "AuditFieldsMixin": true 22 | }, 23 | "acls": [{ 24 | "accessType": "*", 25 | "permission": "DENY", 26 | "principalType": "ROLE", 27 | "principalId": "$everyone" 28 | },{ 29 | "accessType": "*", 30 | "permission": "ALLOW", 31 | "principalType": "ROLE", 32 | "principalId": "$authenticated" 33 | }] 34 | } 35 | -------------------------------------------------------------------------------- /common/activiti-models/activiti-base-entity.json: -------------------------------------------------------------------------------- 1 | 2 | { 3 | "name": "Activiti_BaseEntity", 4 | "base": "Model", 5 | "idInjection": true, 6 | "mixins": { 7 | "VersionMixin": false, 8 | "HistoryMixin": false, 9 | "AuditFieldsMixin": true 10 | }, 11 | "options": { 12 | "validateUpsert": true 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /common/activiti-models/activiti-manager.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Activiti_Manager", 3 | "base": "Model", 4 | "description" : "Manages interaction with Activiti Workflow engine", 5 | "idInjection": true, 6 | "options": { 7 | "validateUpsert": true 8 | }, 9 | "properties": { 10 | "status": { 11 | "type": "string", 12 | "required": true 13 | } 14 | }, 15 | "validations": [] 16 | } 17 | -------------------------------------------------------------------------------- /common/activiti-models/activiti-workflow-request.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * 4 | * ©2016-2017 EdgeVerve Systems Limited (a fully owned Infosys subsidiary), 5 | * Bangalore, India. All Rights Reserved. 6 | * 7 | */ 8 | 9 | module.exports = function ActivitiWR(Model) { 10 | 11 | }; 12 | -------------------------------------------------------------------------------- /common/activiti-models/activiti-workflow-request.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Activiti_WorkflowRequest", 3 | "base": "BaseEntity", 4 | "description": "Stores triggered workflow information for Model Instances(Activiti Workflow Engine)", 5 | "strictObjectIDCoercion": true, 6 | "options": { 7 | "validateUpsert": true 8 | }, 9 | "mixins": { 10 | "SoftDeleteMixin": false 11 | }, 12 | "properties": { 13 | "modelName": { 14 | "type": "string", 15 | "required": true 16 | }, 17 | "modelInstanceId": { 18 | "type": "string", 19 | "required": true 20 | }, 21 | "processId": { 22 | "type": "string", 23 | "required": true, 24 | "id": true 25 | }, 26 | "operation": { 27 | "type": "string", 28 | "required": true 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /common/activiti-models/datasources/ds-activiti-engine.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "_meta": { 4 | "id": "15.11.2.", 5 | "description": "Get engine info" 6 | }, 7 | "template": { 8 | "method": "GET", 9 | "url": "management/engine", 10 | "headers": { 11 | "accept": "application/json", 12 | "content-type": "application/json" 13 | } 14 | }, 15 | "functions": { 16 | "getInfo": [] 17 | }, 18 | "description": "Get engine info (15.11.2.)" 19 | }, 20 | { 21 | "_meta": { 22 | "id": "15.11.1.", 23 | "description": "Get engine properties" 24 | }, 25 | "template": { 26 | "method": "GET", 27 | "url": "management/properties", 28 | "headers": { 29 | "accept": "application/json", 30 | "content-type": "application/json" 31 | } 32 | }, 33 | "functions": { 34 | "getProperties": [] 35 | }, 36 | "description": "Get engine properties (15.11.1.)" 37 | } 38 | ] -------------------------------------------------------------------------------- /common/activiti-models/datasources/ds-activiti-form.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "_meta": { 4 | "id": "15.9.2.", 5 | "description": "Submit task form data" 6 | }, 7 | "template": { 8 | "method": "POST", 9 | "url": "form/form-data", 10 | "headers": { 11 | "accept": "application/json", 12 | "content-type": "application/json" 13 | }, 14 | "body": "{!variables:object}" 15 | }, 16 | "functions": { 17 | "CreateFormData": [ 18 | "variables" 19 | ] 20 | }, 21 | "description": "Submit task form data (15.9.2.)" 22 | }, 23 | { 24 | "_meta": { 25 | "id": "15.9.1.", 26 | "description": "Get form data" 27 | }, 28 | "template": { 29 | "method": "GET", 30 | "url": "form/form-data", 31 | "headers": { 32 | "accept": "application/json", 33 | "content-type": "application/json" 34 | }, 35 | "query": { 36 | "taskId": "{!taskId:object}", 37 | "processDefinitionId": "{!processDefinitionId :string}" 38 | } 39 | }, 40 | "functions": { 41 | "getFormData": [ 42 | "taskId", 43 | "processDefinitionId" 44 | ] 45 | }, 46 | "description": "Get form data (15.9.1.)" 47 | } 48 | ] 49 | -------------------------------------------------------------------------------- /common/activiti-models/datasources/ds-activiti-job.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "_meta": { 4 | "id": "15.13.5.", 5 | "description": "Get a list of jobs" 6 | }, 7 | "template": { 8 | "method": "GET", 9 | "url": "management/jobs", 10 | "headers": { 11 | "accept": "application/json", 12 | "content-type": "application/json" 13 | }, 14 | "query": "{query:object}" 15 | }, 16 | "functions": { 17 | "getJobs": [ 18 | "query" 19 | ] 20 | }, 21 | "description": "Get a list of jobs (15.13.5.)" 22 | }, 23 | { 24 | "_meta": { 25 | "id": "15.13.4.", 26 | "description": "Get the exception stacktrace for a job" 27 | }, 28 | "template": { 29 | "method": "GET", 30 | "url": "management/jobs/{!jobId}/exception-stacktrace", 31 | "headers": { 32 | "accept": "application/json", 33 | "content-type": "application/json" 34 | } 35 | }, 36 | "functions": { 37 | "getStackTraceById": [ 38 | "jobId" 39 | ] 40 | }, 41 | "description": "Get the exception stacktrace for a job (15.13.4.)" 42 | }, 43 | { 44 | "_meta": { 45 | "id": "15.13.3.", 46 | "description": "Execute a single job" 47 | }, 48 | "template": { 49 | "method": "POST", 50 | "url": "management/jobs/{!jobId}", 51 | "headers": { 52 | "accept": "application/json", 53 | "content-type": "application/json" 54 | }, 55 | "body": { 56 | "action": "execute" 57 | } 58 | }, 59 | "functions": { 60 | "complete": [ 61 | "jobId" 62 | ] 63 | }, 64 | "description": "Execute a single job (15.13.3.)" 65 | }, 66 | { 67 | "_meta": { 68 | "id": "15.13.2.", 69 | "description": "Delete a job" 70 | }, 71 | "template": { 72 | "method": "DELETE", 73 | "url": "management/jobs/{!jobId}", 74 | "headers": { 75 | "accept": "application/json", 76 | "content-type": "application/json" 77 | } 78 | }, 79 | "functions": { 80 | "deleteById": [ 81 | "jobId" 82 | ] 83 | }, 84 | "description": "Delete a job (15.13.2.)" 85 | }, 86 | { 87 | "_meta": { 88 | "id": "15.13.1.", 89 | "description": "Get a single job" 90 | }, 91 | "template": { 92 | "method": "GET", 93 | "url": "management/jobs/{!jobId}", 94 | "headers": { 95 | "accept": "application/json", 96 | "content-type": "application/json" 97 | } 98 | }, 99 | "functions": { 100 | "getById": [ 101 | "jobId" 102 | ] 103 | }, 104 | "description": "Get a single job (15.13.1.)" 105 | } 106 | ] -------------------------------------------------------------------------------- /common/activiti-models/datasources/ds-activiti-runtime.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "_meta": { 4 | "id": "15.12.1.", 5 | "description": "Signal event received" 6 | }, 7 | "template": { 8 | "method": "POST", 9 | "url": "runtime/signals", 10 | "headers": { 11 | "accept": "application/json", 12 | "content-type": "application/json" 13 | }, 14 | "body": "{variables:object}" 15 | }, 16 | "functions": { 17 | "query": [ 18 | "variables" 19 | ] 20 | }, 21 | "description": "Signal event received (15.12.1.)" 22 | } 23 | ] -------------------------------------------------------------------------------- /common/activiti-models/datasources/ds-activiti-table.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "_meta": { 4 | "id": "15.10.4.", 5 | "description": "Get row data for a single table" 6 | }, 7 | "template": { 8 | "method": "GET", 9 | "url": "management/tables/{!tableName}/data", 10 | "headers": { 11 | "accept": "application/json", 12 | "content-type": "application/json" 13 | }, 14 | "query": "{query:object}" 15 | }, 16 | "functions": { 17 | "getRowData": [ 18 | "query", 19 | "tableName" 20 | ] 21 | }, 22 | "description": "Get row data for a single table (15.10.4.)" 23 | }, 24 | { 25 | "_meta": { 26 | "id": "15.10.3.", 27 | "description": "Get column info for a single table" 28 | }, 29 | "template": { 30 | "method": "GET", 31 | "url": "management/tables/{!tableName}/columns", 32 | "headers": { 33 | "accept": "application/json", 34 | "content-type": "application/json" 35 | } 36 | }, 37 | "functions": { 38 | "getColumnsById": [ 39 | "tableName" 40 | ] 41 | }, 42 | "description": "Get column info for a single table (15.10.3.)" 43 | }, 44 | { 45 | "_meta": { 46 | "id": "15.10.2.", 47 | "description": "Get a single table" 48 | }, 49 | "template": { 50 | "method": "GET", 51 | "url": "management/tables/{!tableName}", 52 | "headers": { 53 | "accept": "application/json", 54 | "content-type": "application/json" 55 | } 56 | }, 57 | "functions": { 58 | "getById": [ 59 | "tableName" 60 | ] 61 | }, 62 | "description": "Get a single table (15.10.2.)" 63 | }, 64 | { 65 | "_meta": { 66 | "id": "15.10.1.", 67 | "description": "List of tables" 68 | }, 69 | "template": { 70 | "method": "GET", 71 | "url": "management/tables", 72 | "headers": { 73 | "accept": "application/json", 74 | "content-type": "application/json" 75 | } 76 | }, 77 | "functions": { 78 | "get": [] 79 | }, 80 | "description": "List of tables (15.10.1.)" 81 | } 82 | ] -------------------------------------------------------------------------------- /common/activiti-models/dynamic-models/activiti-deployment.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * ©2016-2017 EdgeVerve Systems Limited (a fully owned Infosys subsidiary), 4 | * Bangalore, India. All Rights Reserved. 5 | * 6 | */ 7 | 8 | /* jshint ignore:start */ 9 | module.exports = function Model(Model) { 10 | 11 | }; 12 | /* jshint ignore:end */ 13 | -------------------------------------------------------------------------------- /common/activiti-models/dynamic-models/activiti-deployment.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Activiti_Deployment", 3 | "base": "Activiti_BaseEntity", 4 | "idInjection": false, 5 | "strict": true, 6 | "options": { 7 | "validateUpsert": true 8 | }, 9 | "properties": { 10 | } 11 | } -------------------------------------------------------------------------------- /common/activiti-models/dynamic-models/activiti-engine.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * 4 | * ©2016-2017 EdgeVerve Systems Limited (a fully owned Infosys subsidiary), 5 | * Bangalore, India. All Rights Reserved. 6 | * 7 | */ 8 | 9 | /* jshint ignore:start */ 10 | module.exports = function Model(Model) { 11 | 12 | }; 13 | /* jshint ignore:end */ 14 | -------------------------------------------------------------------------------- /common/activiti-models/dynamic-models/activiti-engine.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Activiti_Engine", 3 | "base": "Activiti_BaseEntity", 4 | "idInjection": false, 5 | "strict": true, 6 | "options": { 7 | "validateUpsert": true 8 | }, 9 | "properties": { 10 | } 11 | } -------------------------------------------------------------------------------- /common/activiti-models/dynamic-models/activiti-execution.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * ©2016-2017 EdgeVerve Systems Limited (a fully owned Infosys subsidiary), 4 | * Bangalore, India. All Rights Reserved. 5 | * 6 | */ 7 | 8 | /* jshint ignore:start */ 9 | module.exports = function Model(Model) { 10 | 11 | }; 12 | /* jshint ignore:end */ 13 | -------------------------------------------------------------------------------- /common/activiti-models/dynamic-models/activiti-execution.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Activiti_Execution", 3 | "base": "Activiti_BaseEntity", 4 | "idInjection": false, 5 | "strict": true, 6 | "options": { 7 | "validateUpsert": true 8 | }, 9 | "properties": { 10 | } 11 | } -------------------------------------------------------------------------------- /common/activiti-models/dynamic-models/activiti-form.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * 4 | * ©2016-2017 EdgeVerve Systems Limited (a fully owned Infosys subsidiary), 5 | * Bangalore, India. All Rights Reserved. 6 | * 7 | */ 8 | 9 | /* jshint ignore:start */ 10 | module.exports = function Model(Model) { 11 | 12 | }; 13 | /* jshint ignore:end */ 14 | -------------------------------------------------------------------------------- /common/activiti-models/dynamic-models/activiti-form.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Activiti_Form", 3 | "base": "Activiti_BaseEntity", 4 | "idInjection": false, 5 | "strict": true, 6 | "options": { 7 | "validateUpsert": true 8 | }, 9 | "properties": { 10 | } 11 | } -------------------------------------------------------------------------------- /common/activiti-models/dynamic-models/activiti-group.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * 4 | * ©2016-2017 EdgeVerve Systems Limited (a fully owned Infosys subsidiary), 5 | * Bangalore, India. All Rights Reserved. 6 | * 7 | */ 8 | 9 | /* jshint ignore:start */ 10 | module.exports = function Model(Model) { 11 | 12 | }; 13 | /* jshint ignore:end */ 14 | -------------------------------------------------------------------------------- /common/activiti-models/dynamic-models/activiti-group.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Activiti_Group", 3 | "base": "Activiti_BaseEntity", 4 | "idInjection": false, 5 | "strict": true, 6 | "options": { 7 | "validateUpsert": true 8 | }, 9 | "properties": { 10 | } 11 | } -------------------------------------------------------------------------------- /common/activiti-models/dynamic-models/activiti-history.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * 4 | * ©2016-2017 EdgeVerve Systems Limited (a fully owned Infosys subsidiary), 5 | * Bangalore, India. All Rights Reserved. 6 | * 7 | */ 8 | 9 | /* jshint ignore:start */ 10 | module.exports = function Model(Model) { 11 | 12 | }; 13 | /* jshint ignore:end */ 14 | -------------------------------------------------------------------------------- /common/activiti-models/dynamic-models/activiti-history.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Activiti_History", 3 | "base": "Activiti_BaseEntity", 4 | "idInjection": false, 5 | "strict": true, 6 | "options": { 7 | "validateUpsert": true 8 | }, 9 | "properties": { 10 | } 11 | } -------------------------------------------------------------------------------- /common/activiti-models/dynamic-models/activiti-job.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * 4 | * ©2016-2017 EdgeVerve Systems Limited (a fully owned Infosys subsidiary), 5 | * Bangalore, India. All Rights Reserved. 6 | * 7 | */ 8 | 9 | /* jshint ignore:start */ 10 | module.exports = function Model(Model) { 11 | 12 | }; 13 | /* jshint ignore:end */ 14 | -------------------------------------------------------------------------------- /common/activiti-models/dynamic-models/activiti-job.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Activiti_Job", 3 | "base": "Activiti_BaseEntity", 4 | "idInjection": false, 5 | "strict": true, 6 | "options": { 7 | "validateUpsert": true 8 | }, 9 | "properties": { 10 | } 11 | } -------------------------------------------------------------------------------- /common/activiti-models/dynamic-models/activiti-model.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * 4 | * ©2016-2017 EdgeVerve Systems Limited (a fully owned Infosys subsidiary), 5 | * Bangalore, India. All Rights Reserved. 6 | * 7 | */ 8 | 9 | /* jshint ignore:start */ 10 | module.exports = function Model(Model) { 11 | 12 | }; 13 | /* jshint ignore:end */ 14 | -------------------------------------------------------------------------------- /common/activiti-models/dynamic-models/activiti-model.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Activiti_Model", 3 | "base": "Activiti_BaseEntity", 4 | "idInjection": false, 5 | "strict": true, 6 | "options": { 7 | "validateUpsert": true 8 | }, 9 | "properties": { 10 | } 11 | } -------------------------------------------------------------------------------- /common/activiti-models/dynamic-models/activiti-process-definition.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * 4 | * ©2016-2017 EdgeVerve Systems Limited (a fully owned Infosys subsidiary), 5 | * Bangalore, India. All Rights Reserved. 6 | * 7 | */ 8 | 9 | /* jshint ignore:start */ 10 | module.exports = function Model(Model) { 11 | 12 | }; 13 | /* jshint ignore:end */ 14 | -------------------------------------------------------------------------------- /common/activiti-models/dynamic-models/activiti-process-definition.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Activiti_ProcessDefinition", 3 | "base": "Activiti_BaseEntity", 4 | "idInjection": false, 5 | "strict": true, 6 | "options": { 7 | "validateUpsert": true 8 | }, 9 | "properties": { 10 | } 11 | } -------------------------------------------------------------------------------- /common/activiti-models/dynamic-models/activiti-process-instance.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * 4 | * ©2016-2017 EdgeVerve Systems Limited (a fully owned Infosys subsidiary), 5 | * Bangalore, India. All Rights Reserved. 6 | * 7 | */ 8 | 9 | /* jshint ignore:start */ 10 | module.exports = function Model(Model) { 11 | 12 | }; 13 | /* jshint ignore:end */ 14 | -------------------------------------------------------------------------------- /common/activiti-models/dynamic-models/activiti-process-instance.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Activiti_ProcessInstance", 3 | "base": "Activiti_BaseEntity", 4 | "idInjection": false, 5 | "strict": true, 6 | "options": { 7 | "validateUpsert": true 8 | }, 9 | "properties": { 10 | } 11 | } -------------------------------------------------------------------------------- /common/activiti-models/dynamic-models/activiti-runtime.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * 4 | * ©2016-2017 EdgeVerve Systems Limited (a fully owned Infosys subsidiary), 5 | * Bangalore, India. All Rights Reserved. 6 | * 7 | */ 8 | 9 | /* jshint ignore:start */ 10 | module.exports = function Model(Model) { 11 | 12 | }; 13 | /* jshint ignore:end */ 14 | -------------------------------------------------------------------------------- /common/activiti-models/dynamic-models/activiti-runtime.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Activiti_Runtime", 3 | "base": "Activiti_BaseEntity", 4 | "idInjection": false, 5 | "strict": true, 6 | "options": { 7 | "validateUpsert": true 8 | }, 9 | "properties": { 10 | } 11 | } -------------------------------------------------------------------------------- /common/activiti-models/dynamic-models/activiti-table.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * 4 | * ©2016-2017 EdgeVerve Systems Limited (a fully owned Infosys subsidiary), 5 | * Bangalore, India. All Rights Reserved. 6 | * 7 | */ 8 | 9 | /* jshint ignore:start */ 10 | module.exports = function Model(Model) { 11 | 12 | }; 13 | /* jshint ignore:end */ 14 | -------------------------------------------------------------------------------- /common/activiti-models/dynamic-models/activiti-table.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Activiti_Table", 3 | "base": "Activiti_BaseEntity", 4 | "idInjection": false, 5 | "strict": true, 6 | "options": { 7 | "validateUpsert": true 8 | }, 9 | "properties": { 10 | } 11 | } -------------------------------------------------------------------------------- /common/activiti-models/dynamic-models/activiti-task.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * 4 | * ©2016-2017 EdgeVerve Systems Limited (a fully owned Infosys subsidiary), 5 | * Bangalore, India. All Rights Reserved. 6 | * 7 | */ 8 | 9 | /* jshint ignore:start */ 10 | module.exports = function Model(Model) { 11 | 12 | }; 13 | /* jshint ignore:end */ 14 | -------------------------------------------------------------------------------- /common/activiti-models/dynamic-models/activiti-task.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Activiti_Task", 3 | "base": "Activiti_BaseEntity", 4 | "idInjection": false, 5 | "strict": true, 6 | "options": { 7 | "validateUpsert": true 8 | }, 9 | "properties": { 10 | } 11 | } -------------------------------------------------------------------------------- /common/activiti-models/dynamic-models/activiti-user.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * 4 | * ©2016-2017 EdgeVerve Systems Limited (a fully owned Infosys subsidiary), 5 | * Bangalore, India. All Rights Reserved. 6 | * 7 | */ 8 | 9 | /* jshint ignore:start */ 10 | module.exports = function Model(Model) { 11 | 12 | }; 13 | /* jshint ignore:end */ 14 | -------------------------------------------------------------------------------- /common/activiti-models/dynamic-models/activiti-user.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Activiti_User", 3 | "base": "Activiti_BaseEntity", 4 | "idInjection": false, 5 | "strict": true, 6 | "options": { 7 | "validateUpsert": true 8 | }, 9 | "properties": { 10 | } 11 | } -------------------------------------------------------------------------------- /common/activiti-models/lib/helper.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * ©2016-2017 EdgeVerve Systems Limited (a fully owned Infosys subsidiary), 4 | * Bangalore, India. All Rights Reserved. 5 | * 6 | */ 7 | var path = require('path'); 8 | var register = require(path.join(__dirname, 'register.js')); 9 | 10 | var logger = require('oe-logger'); 11 | var log = logger('activiti-manager-helper'); 12 | 13 | var exports = module.exports = {}; 14 | 15 | exports._enableActiviti = function _enableActiviti(baseUrl, app, ctx, done) { 16 | /* istanbul ignore if*/ 17 | if (typeof ctx === 'function') { 18 | done = ctx; 19 | ctx = {}; 20 | } 21 | 22 | if (!baseUrl) { 23 | let err = new Error('Activiti endpoint must be specified'); 24 | err.statusCode = err.status = 422; 25 | err.code = 'INVALID_DATA'; 26 | return done(err); 27 | } 28 | 29 | var modelNames = [ 30 | 'activiti-deployment', 31 | 'activiti-engine', 32 | 'activiti-execution', 33 | 'activiti-form', 34 | 'activiti-group', 35 | 'activiti-history', 36 | 'activiti-job', 37 | 'activiti-model', 38 | 'activiti-process-definition', 39 | 'activiti-process-instance', 40 | 'activiti-runtime', 41 | 'activiti-table', 42 | 'activiti-task', 43 | 'activiti-user' 44 | ]; 45 | 46 | for (var i = 0; i < modelNames.length; i++) { 47 | var modelName = modelNames[i]; 48 | var dataSourceName = 'ds-' + modelName; 49 | register.unPersistedConfiguration(modelName, dataSourceName, app, baseUrl); 50 | } 51 | log.debug(log.defaultContext(), 'activiti endpoints successfully enabled'); 52 | done(null, 'activiti endpoints successfully enabled'); 53 | }; 54 | -------------------------------------------------------------------------------- /common/activiti-models/lib/register.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * ©2016-2017 EdgeVerve Systems Limited (a fully owned Infosys subsidiary), 4 | * Bangalore, India. All Rights Reserved. 5 | * 6 | */ 7 | var path = require('path'); 8 | var util = require(path.join(__dirname, 'util.js')); 9 | 10 | var logger = require('oe-logger'); 11 | var log = logger('activiti-register'); 12 | 13 | var exports = module.exports = {}; 14 | 15 | // TODO : Boolean doesnt work while specifing template param in Datasource Definition, check why 16 | function updateURL(operations, baseUrl) { 17 | for (var i = 0; i < operations.length; i++) { 18 | // updating url with base url 19 | operations[i].template.url = baseUrl + operations[i].template.url; 20 | } 21 | } 22 | 23 | function addOptions(operations) { 24 | operations.forEach(op => { 25 | op.template.headers = op.template.headers || {}; 26 | op.template.headers['x-options'] = '{options:object}'; 27 | Object.keys(op.functions).forEach(fName => { 28 | op.functions[fName] = op.functions[fName] || []; 29 | op.functions[fName].push('options'); 30 | }); 31 | }); 32 | } 33 | 34 | exports.unPersistedConfiguration = function unPersistedConfiguration(modelName, dataSourceName, app, baseUrl) { 35 | var modelDefinition = require('../dynamic-models/' + modelName + '.json'); 36 | var modelJs = require('../dynamic-models/' + modelName + '.js'); 37 | 38 | // var operations = require(path.join(__dirname, '..', 'datasources', dataSourceName + '.json')); 39 | var operations = require('../datasources/' + dataSourceName + '.json'); 40 | updateURL(operations, baseUrl); 41 | addOptions(operations); 42 | var dsDefinition = { 43 | 'name': modelName, 44 | 'connector': require('loopback-connector-rest'), 45 | 'debug': 'false', 46 | 'options': { 47 | 'strictSSL': false 48 | }, 49 | 'operations': operations 50 | }; 51 | 52 | log.debug(log.defaultContext(), 'creating unPersistedConfiguration'); 53 | var ds = util.createDatasource(dsDefinition); 54 | var model = util.createModel(modelDefinition, modelJs); 55 | util.mapModelDS(app, model, ds); 56 | util.addBeforeExecuteConnectorHooks(app, ds); 57 | }; 58 | -------------------------------------------------------------------------------- /common/activiti-models/lib/util.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * ©2016-2017 EdgeVerve Systems Limited (a fully owned Infosys subsidiary), 4 | * Bangalore, India. All Rights Reserved. 5 | * 6 | */ 7 | var exports = module.exports = {}; 8 | var loopback = require('loopback'); 9 | var logger = require('oe-logger'); 10 | var log = logger('activiti-util'); 11 | 12 | exports.createModel = function createModel(modelDefn, customizeFn, options) { 13 | var Model = loopback.createModel(modelDefn); 14 | if (customizeFn) { 15 | customizeFn(Model, options); 16 | } 17 | Model.clientModelName = Model.modelName; 18 | Model.clientPlural = Model.pluralModelName; 19 | log.debug(log.defaultContext(), 'ModelDefinition successfully created : ' + modelDefn.name); 20 | return Model; 21 | }; 22 | 23 | exports.createDatasource = function createDatasource(datasourceDefn) { 24 | var datasource = loopback.createDataSource(datasourceDefn); 25 | return datasource; 26 | }; 27 | 28 | exports.mapModelDS = function mapModelDS(app, model, ds) { 29 | app.model(model, {dataSource: ds }); 30 | log.debug(log.defaultContext(), 'datasource mapping successfully created : ' + model.name + ' , ' + ds.name); 31 | return; 32 | }; 33 | 34 | exports.addBeforeExecuteConnectorHooks = function addBeforeExecuteConnectorHooks(app, ds) { 35 | var connector = ds.connector; 36 | connector.observe('before execute', function beforeExecuteConnectorHookCb(ctx, next) { 37 | /* 38 | * ctx.options is available now 39 | */ 40 | let options = ctx.options || ctx.req.headers['x-options']; 41 | delete ctx.req.headers['x-options']; 42 | app.models.Activiti_Account.find({}, options, function fetchAccountDetails(err, account) { 43 | /* istanbul ignore if*/ 44 | if (err) { 45 | log.error(options, err); 46 | return next(err); 47 | } 48 | if (account.length === 0) { 49 | err = new Error('Please setup Activiti Account by posting details to Activiti_Account.'); 50 | log.error(options, err); 51 | return next(err); 52 | } 53 | 54 | // if the context is passed correctly there will always be one account returned for a single user 55 | var user = account[0].username; 56 | var password = account[0].password; 57 | 58 | ctx.req.auth = { 59 | user: user, 60 | password: password 61 | }; 62 | 63 | next(); 64 | }); 65 | }); 66 | }; 67 | 68 | -------------------------------------------------------------------------------- /common/models/bpmndata.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * 4 | * ©2016-2017 EdgeVerve Systems Limited (a fully owned Infosys subsidiary), 5 | * Bangalore, India. All Rights Reserved. 6 | * 7 | */ 8 | 9 | module.exports = function Bpmndata(Bpmndata) { 10 | }; 11 | -------------------------------------------------------------------------------- /common/models/bpmndata.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bpmndata", 3 | "base": "BaseEntity", 4 | "description": "Contains XML data of BPMN workflows", 5 | "idInjection": true, 6 | "options": { 7 | "validateUpsert": true 8 | }, 9 | "mixins":{ 10 | "VersionMixin": true, 11 | "HistoryMixin": true 12 | }, 13 | "properties": { 14 | "versionmessage": { 15 | "type": "string" 16 | }, 17 | "bpmnname": { 18 | "type": "string", 19 | "required": true 20 | }, 21 | "xmldata": { 22 | "type": "string", 23 | "required": true, 24 | "oracle": { 25 | "dataType": "CLOB" 26 | } 27 | } 28 | }, 29 | "validations": [], 30 | "relations": {}, 31 | "acls": [], 32 | "methods": { 33 | "processDefinitions": { 34 | "type": "hasMany", 35 | "model": "ProcessDefinition" 36 | }, 37 | "workflowDefinition": { 38 | "type": "hasOne", 39 | "model": "WorkflowDefinition" 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /common/models/change-workflow-request.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ChangeWorkflowRequest", 3 | "base": "BaseEntity", 4 | "description" : "Manages change request created during maker-checker", 5 | "idInjection": true, 6 | "strictObjectIDCoercion": true, 7 | "mixins":{ 8 | "VersionMixin": true, 9 | "HistoryMixin": true 10 | }, 11 | "properties": { 12 | "data": { 13 | "type": "object", 14 | "required": true 15 | }, 16 | "operation" : { 17 | "type": "string", 18 | "required": true 19 | }, 20 | "modelName" : { 21 | "type": "string", 22 | "required": true, 23 | "index": true 24 | }, 25 | "modelId": { 26 | "type": "string", 27 | "required": true, 28 | "index": true 29 | }, 30 | "status": { 31 | "type": "string", 32 | "required": true, 33 | "default": "pending" 34 | }, 35 | "verificationStatus": { 36 | "type": "string" 37 | }, 38 | "remarks": { 39 | "type": "string" 40 | }, 41 | "_verifiedBy": { 42 | "type": "string" , 43 | "required": false 44 | }, 45 | "_modifiers": { 46 | "type": ["string"] , 47 | "required": false 48 | }, 49 | "correlationId": { 50 | "type": "string", 51 | "index": true 52 | } 53 | }, 54 | "validations": [], 55 | "relations": { 56 | "workflowInstance": { 57 | "type": "belongsTo", 58 | "model": "WorkflowInstance", 59 | "foreignKey": "workflowInstanceId" 60 | } 61 | }, 62 | "acls": [] 63 | } 64 | -------------------------------------------------------------------------------- /common/models/durableTimeout.json: -------------------------------------------------------------------------------- 1 | 2 | { 3 | "name": "DurableTimeout", 4 | "base": "WorkflowBaseEntity", 5 | "description" : "Manages timer event execution in oe-workflow engine", 6 | "idInjection": true, 7 | "properties": { 8 | "definition": { 9 | "type": "string", 10 | "required": true 11 | }, 12 | "nextExecution": { 13 | "type": "date", 14 | "index": true, 15 | "required": true 16 | }, 17 | "schedule": { 18 | "type": ["date"] 19 | }, 20 | "counter": { 21 | "type": "number", 22 | "default": 0 23 | }, 24 | "perpetual": { 25 | "type": "boolean", 26 | "default": false 27 | }, 28 | "status": { 29 | "type": "string", 30 | "index": true, 31 | "required": true, 32 | "default": "pending" 33 | }, 34 | "tokenId": { 35 | "type" : "string", 36 | "required" : true 37 | } 38 | }, 39 | "validations": [], 40 | "relations": { 41 | "processInstance": { 42 | "type": "belongsTo", 43 | "model": "ProcessInstance", 44 | "foreignKey": "processInstanceId" 45 | } 46 | }, 47 | "acls": [] 48 | } 49 | -------------------------------------------------------------------------------- /common/models/process-definition.json: -------------------------------------------------------------------------------- 1 | 2 | { 3 | "name": "ProcessDefinition", 4 | "base": "WorkflowBaseEntity", 5 | "description" : "Stores Process level definiton of workflows in oe-workflow engine", 6 | "idInjection": true, 7 | "options": { 8 | "validateUpsert": true 9 | }, 10 | "properties": { 11 | "name": { 12 | "type": "string", 13 | "required": true, 14 | "index": true 15 | }, 16 | "parsedDef": { 17 | "type": "object", 18 | "required": false 19 | }, 20 | "processDefinition" : { 21 | "type": "object", 22 | "required": false 23 | }, 24 | "messageFlowsBySrcProcess" : { 25 | "type": "object", 26 | "required": false 27 | }, 28 | "parentProcessDefinitionId" : { 29 | "type" : "string", 30 | "required" : false 31 | } 32 | }, 33 | "validations": [], 34 | "relations": { 35 | "parentProcessDefinition": { 36 | "type": "belongsTo", 37 | "model": "ProcessDefinition", 38 | "foreignKey" : "parentProcessDefinitionId" 39 | }, 40 | "bpmndata": { 41 | "type": "belongsTo", 42 | "model": "bpmndata", 43 | "foreignKey" : "bpmndataId" 44 | }, 45 | "workflowDefinition": { 46 | "type": "belongsTo", 47 | "model": "WorkflowDefinition", 48 | "foreignKey" : "workflowDefinitionId" 49 | }, 50 | "processInstances" : { 51 | "type" : "hasMany", 52 | "model" : "ProcessInstance" 53 | } 54 | }, 55 | "acls": [], 56 | "methods": {} 57 | } 58 | -------------------------------------------------------------------------------- /common/models/task.json: -------------------------------------------------------------------------------- 1 | 2 | { 3 | "name": "Task", 4 | "base": "WorkflowBaseEntity", 5 | "description": "Manages User interaction with workflows in oe-workflow engine", 6 | "plural" : "Tasks", 7 | "idInjection": true, 8 | "options": { 9 | "validateUpsert": true 10 | }, 11 | "mixins" :{ 12 | }, 13 | "properties": { 14 | "name": { 15 | "type": "string", 16 | "required": true 17 | }, 18 | "status": { 19 | "type": "string", 20 | "default": "pending" 21 | }, 22 | "processTokenId": { 23 | "type": "string", 24 | "required": true 25 | }, 26 | "candidateUsers": { 27 | "type": ["string"], 28 | "required" : false 29 | }, 30 | "excludedUsers": { 31 | "type": ["string"], 32 | "required" : false 33 | }, 34 | "candidateRoles": { 35 | "type": ["string"], 36 | "required" : false 37 | }, 38 | "excludedRoles": { 39 | "type": ["string"], 40 | "required" : false 41 | }, 42 | "candidateGroups" : { 43 | "type": ["string"], 44 | "required" : false 45 | }, 46 | "excludedGroups" : { 47 | "type": ["string"], 48 | "required" : false 49 | }, 50 | "dueDate" : { 51 | "type" : "date", 52 | "required" : false 53 | }, 54 | "followUpDate" : { 55 | "type" : "date", 56 | "required" : false 57 | }, 58 | "priority" : { 59 | "type" : "string", 60 | "required" : false 61 | }, 62 | "formKey" : { 63 | "type" : "string", 64 | "required" : false 65 | }, 66 | "formType" : { 67 | "type" : "string", 68 | "required" : false 69 | }, 70 | "formVariables" : { 71 | "type" : "object", 72 | "required" : false 73 | }, 74 | "stepVariables" : { 75 | "type" : "object", 76 | "required" : false 77 | }, 78 | "message" : { 79 | "type" : "object", 80 | "required" : false 81 | }, 82 | "comments" : { 83 | "type" : "string", 84 | "required" : false 85 | }, 86 | "correlationId": { 87 | "type": "string", 88 | "index": true 89 | } 90 | }, 91 | "validations": [], 92 | "relations": { 93 | "processInstance": { 94 | "type": "belongsTo", 95 | "model": "ProcessInstance", 96 | "foreignKey": "processInstanceId" 97 | }, 98 | "workflowInstance" : { 99 | "type" : "belongsTo", 100 | "model" : "WorkflowInstance", 101 | "foreignKey" : "workflowInstanceId" 102 | } 103 | }, 104 | "methods": {}, 105 | "acls" : [ 106 | { 107 | "accessType": "*", 108 | "principalType": "ROLE", 109 | "principalId": "$authenticated", 110 | "permission": "ALLOW", 111 | "property": "completeTask" 112 | } 113 | ] 114 | } 115 | -------------------------------------------------------------------------------- /common/models/workflow-base-entity.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * ©2016-2017 EdgeVerve Systems Limited (a fully owned Infosys subsidiary), 4 | * Bangalore, India. All Rights Reserved. 5 | * 6 | */ 7 | 8 | module.exports = function WorkflowBaseEntity() { 9 | }; 10 | -------------------------------------------------------------------------------- /common/models/workflow-base-entity.json: -------------------------------------------------------------------------------- 1 | 2 | { 3 | "name": "WorkflowBaseEntity", 4 | "base": "BaseEntity", 5 | "strict" : true, 6 | "idInjection": false, 7 | "cacheable" : false, 8 | "mixins": { 9 | "VersionMixin": false, 10 | "HistoryMixin": false, 11 | "AuditFieldsMixin": false 12 | }, 13 | "properties": {}, 14 | "validations": [], 15 | "relations": {}, 16 | "acls": [], 17 | "methods": {} 18 | } 19 | -------------------------------------------------------------------------------- /common/models/workflow-definition.json: -------------------------------------------------------------------------------- 1 | 2 | { 3 | "name": "WorkflowDefinition", 4 | "base": "WorkflowBaseEntity", 5 | "description" : "Manages deployment of workflows in oe-workflow engine", 6 | "idInjection": true, 7 | "options": { 8 | "validateUpsert": true 9 | }, 10 | "mixins":{ 11 | "VersionMixin": true, 12 | "HistoryMixin": true 13 | }, 14 | "properties": { 15 | "name": { 16 | "type": "string", 17 | "required": true 18 | }, 19 | "xmldata": { 20 | "type": "string", 21 | "required": false 22 | }, 23 | "isCollaborationDefinition": { 24 | "type": "boolean", 25 | "required": false 26 | }, 27 | "participants": { 28 | "type": ["object"], 29 | "required": false 30 | }, 31 | "latest": { 32 | "type": "boolean" 33 | } 34 | }, 35 | "validations": [], 36 | "relations": { 37 | "workflowInstances": { 38 | "type": "hasMany", 39 | "model": "WorkflowInstance" 40 | }, 41 | "processDefinitions" : { 42 | "type": "hasMany", 43 | "model": "ProcessDefinition" 44 | }, 45 | "bpmnData": { 46 | "type": "belongsTo", 47 | "model": "bpmndata", 48 | "foreignKey" : "bpmndataId" 49 | } 50 | }, 51 | "acls": [], 52 | "methods": {} 53 | } 54 | -------------------------------------------------------------------------------- /common/models/workflow-instance.json: -------------------------------------------------------------------------------- 1 | 2 | { 3 | "name": "WorkflowInstance", 4 | "base": "WorkflowBaseEntity", 5 | "description" : "Manages workflow instances in oe-workflow engine", 6 | "idInjection": true, 7 | "options": { 8 | "validateUpsert": true 9 | }, 10 | "properties": { 11 | "workflowDefinitionName": { 12 | "type": "string", 13 | "required": true 14 | }, 15 | "workflowDefinitionId": { 16 | "type": "string", 17 | "required": true 18 | }, 19 | "processVariables": { 20 | "type": "object", 21 | "required": false 22 | }, 23 | "message": { 24 | "type": "object", 25 | "required": false 26 | }, 27 | "status": { 28 | "type": "string" 29 | }, 30 | "correlationId":{ 31 | "type":"string", 32 | "index":true 33 | } 34 | }, 35 | "validations": [], 36 | "relations": { 37 | "workflowDefinition": { 38 | "type": "belongsTo", 39 | "model": "WorkflowDefinition", 40 | "foreignKey": "workflowDefinitionId" 41 | }, 42 | "processes": { 43 | "type": "hasMany", 44 | "model": "ProcessInstance" 45 | }, 46 | "tasks": { 47 | "type": "hasMany", 48 | "model": "Task" 49 | }, 50 | "signals": { 51 | "type": "hasMany", 52 | "model": "WorkflowSignal" 53 | } 54 | }, 55 | "acls": [] 56 | } 57 | -------------------------------------------------------------------------------- /common/models/workflow-manager.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "WorkflowManager", 3 | "base": "Model", 4 | "description" : "Manages oe-framework model interactions with oe-workflow engine", 5 | "idInjection": true, 6 | "options": { 7 | "validateUpsert": true 8 | }, 9 | "properties": { 10 | "status": { 11 | "type": "string", 12 | "required": true 13 | } 14 | }, 15 | "validations": [] 16 | } 17 | -------------------------------------------------------------------------------- /common/models/workflow-mapping.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * ©2016-2017 EdgeVerve Systems Limited (a fully owned Infosys subsidiary), 4 | * Bangalore, India. All Rights Reserved. 5 | * 6 | */ 7 | 8 | module.exports = function WorkflowMapping(Model) { 9 | }; 10 | -------------------------------------------------------------------------------- /common/models/workflow-mapping.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "WorkflowMapping", 3 | "base": "WorkflowBaseEntity", 4 | "idInjection": true, 5 | "options": { 6 | "validateUpsert": true 7 | }, 8 | "mixins":{ 9 | "VersionMixin": true 10 | }, 11 | "properties": { 12 | "engineType": { 13 | "type": "string", 14 | "required": true 15 | }, 16 | "workflowBody": { 17 | "type": "object", 18 | "required": true 19 | }, 20 | "modelName" :{ 21 | "type": "string", 22 | "required": true 23 | }, 24 | "actualModelName" :{ 25 | "type": "string", 26 | "required": false, 27 | "hidden" : true 28 | }, 29 | "operation" : { 30 | "type": "string", 31 | "required": true 32 | }, 33 | "version" : { 34 | "type": "string", 35 | "required": true, 36 | "default": "v1" 37 | }, 38 | "wfDependent" : { 39 | "type": "boolean", 40 | "required": true 41 | }, 42 | "makersRecall" : { 43 | "type": "boolean", 44 | "default": false 45 | }, 46 | "privilegedUsers" : { 47 | "type": ["string"], 48 | "required": false 49 | }, 50 | "privilegedRoles": { 51 | "type": ["string"], 52 | "required": false 53 | }, 54 | "remote":{ 55 | "type":"object", 56 | "required": false 57 | }, 58 | "mappingName":{ 59 | "type":"string" 60 | } 61 | }, 62 | "relations": { 63 | }, 64 | "validations": [] 65 | } 66 | -------------------------------------------------------------------------------- /common/models/workflow-request.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * ©2016-2017 EdgeVerve Systems Limited (a fully owned Infosys subsidiary), 4 | * Bangalore, India. All Rights Reserved. 5 | * 6 | */ 7 | 8 | module.exports = function WorkflowRequest(Model) { 9 | }; 10 | -------------------------------------------------------------------------------- /common/models/workflow-request.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "WorkflowRequest", 3 | "base": "WorkflowBaseEntity", 4 | "description": "Stores triggered workflow information for Model Instances(oe-workflow engine)", 5 | "strictObjectIDCoercion": true, 6 | "idInjection" : true, 7 | "options": { 8 | "validateUpsert": true 9 | }, 10 | "mixins": { 11 | "SoftDeleteMixin": false 12 | }, 13 | "properties": { 14 | "modelName": { 15 | "type": "string", 16 | "required": true 17 | }, 18 | "modelInstanceId": { 19 | "type": "string", 20 | "required": true 21 | }, 22 | "processId": { 23 | "type": "string", 24 | "required": true 25 | }, 26 | "operation": { 27 | "type": "string", 28 | "required": true 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /common/models/workflow-signal.json: -------------------------------------------------------------------------------- 1 | 2 | { 3 | "name": "WorkflowSignal", 4 | "base": "WorkflowBaseEntity", 5 | "description" : "Manages workflow signal execution in oe-workflow engine", 6 | "idInjection": true, 7 | "properties": { 8 | "signalRef": { 9 | "type": "string", 10 | "index": true, 11 | "required": true 12 | }, 13 | "tokenId": { 14 | "type" : "string", 15 | "required" : true 16 | } 17 | }, 18 | "validations": [], 19 | "relations": { 20 | "workflowInstance": { 21 | "type": "belongsTo", 22 | "model": "WorkflowInstance", 23 | "foreignKey": "workflowInstanceId" 24 | }, 25 | "processInstance": { 26 | "type": "belongsTo", 27 | "model": "ProcessInstance", 28 | "foreignKey": "processInstanceId" 29 | } 30 | }, 31 | "acls": [] 32 | } 33 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "3" 2 | services: 3 | web: 4 | entrypoint: node bin/app.js 5 | image: ${REGISTRY}/${APP_IMAGE_NAME}:${APP_TAG} 6 | deploy: 7 | mode: replicated 8 | replicas: 1 9 | update_config: 10 | delay: 60s 11 | # resources: 12 | # limits: 13 | # cpus: '0.25' 14 | # memory: 512M 15 | restart_policy: 16 | condition: on-failure 17 | delay: 5s 18 | max_attempts: 3 19 | window: 180s 20 | environment: 21 | #NODE_TLS_REJECT_UNAUTHORIZED: "0" 22 | NODE_ENV: "docker" 23 | MONGO_HOST: ${MONGO_HOST} 24 | VIRTUAL_HOST: ${VIRTUAL_HOST} 25 | SERVICE_PORTS: "3000" 26 | LICENSE_KEY: "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJvZWNsb3VkLmlvIiwiYXVkIjoib2VjbG91ZC5pbyIsImVuZGwiOjE1MTQ3NjQ4MDAwMDAsImlhdCI6MTUxOTAzODMxMX0.X2p2NWle9Fa0OQcqWmuGE8aaLr9coUxTI1AMRxaICPW2n2aVGsfE1ZFJ3DRoCBrZ4L1rIOqGuoceARzHXD3FBZjFET7ZfKnLd3yBvCOhPNEaPu-7dU1cRwS1Rdb-tgQrj_-1dzLWLTqOn7AxLOU1TH5uw2XQ4lg9UyeGzylvM2U" 27 | LICENSE_PUBLICKEY: "-----BEGIN PUBLIC KEY-----MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCAqigyzSV+Yo59aA0IOgnG3Ad9VD5iiLJG7xwezarFsApsBZbOFzd++yqG1Tc7bbZO3rTCymjdFmVVB8Kdq8PE5MIb4Tsz97W8IElyX9lwIU7AmPfh/8LV9YLLxTJPVwQMWIrEWNZs4CzMGkMKKcSUcURxG3nXyIc3IKh0HxrHJwIDAQAB-----END PUBLIC KEY-----" 28 | LOGGER_CONFIG: '{"name":"oe-workflow","logStreams":[{"type":"pretty"}],"levels":{"default":"info","req-logging-filter":"debug","response-logger":"debug"}}' 29 | networks: 30 | - ${NETWORK_NAME} 31 | - router_network 32 | # logging: 33 | # driver: gelf 34 | # options: 35 | # gelf-address: "udp://0.0.0.0:12201" 36 | 37 | mongo: 38 | image: ${REGISTRY}/alpine-mongo:latest 39 | networks: 40 | - ${NETWORK_NAME} 41 | 42 | networks: 43 | ${NETWORK_NAME}: 44 | external: true 45 | router_network: 46 | external: true 47 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | var wrapper = require('./lib/wrapper.js'); 2 | const commonMixins = require('oe-common-mixins'); 3 | 4 | 5 | commonMixins(); 6 | module.exports = function main(app) { 7 | wrapper(app); 8 | }; 9 | -------------------------------------------------------------------------------- /lib/parsing/activity.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * ©2016-2017 EdgeVerve Systems Limited (a fully owned Infosys subsidiary), 4 | * Bangalore, India. All Rights Reserved. 5 | * 6 | */ 7 | 8 | 'use strict'; 9 | var logger = require('oe-logger'); 10 | var log = logger('Activity-Parser'); 11 | 12 | var util = require('util'); 13 | var BPMNFlowObject = require('./flowobject.js').BPMNFlowObject; 14 | 15 | exports.activityEndHandlerPostfix = 'Done'; 16 | 17 | /** 18 | * Subsumes all kind of tasks 19 | * @param {String} bpmnId BpmnId 20 | * @param {String} name Name 21 | * @param {String} type Type 22 | * @constructor 23 | */ 24 | var BPMNActivity = function BPMNActivity(bpmnId, name, type) { 25 | BPMNFlowObject.call(this, bpmnId, name, type); 26 | this.isActivity = true; 27 | log.debug(log.defaultContext(), 'BPMNActivity constructor called'); 28 | }; 29 | util.inherits(BPMNActivity, BPMNFlowObject); 30 | 31 | exports.BPMNActivity = BPMNActivity; 32 | -------------------------------------------------------------------------------- /lib/parsing/boundaryevents.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * ©2016-2017 EdgeVerve Systems Limited (a fully owned Infosys subsidiary), 4 | * Bangalore, India. All Rights Reserved. 5 | * 6 | */ 7 | 8 | 'use strict'; 9 | 10 | var logger = require('oe-logger'); 11 | var log = logger('BoundaryEvent-Parser'); 12 | 13 | var util = require('util'); 14 | var BPMNFlowObject = require('./flowobject.js').BPMNFlowObject; 15 | 16 | /** 17 | * Subsumes all kind of start events 18 | * @param {String} bpmnId BpmnId 19 | * @param {String} name Name 20 | * @param {String} type Type 21 | * @param {String} attachedToRef AttachedToRef 22 | * @param {Object} cancelActivity CancelActivity 23 | * @constructor 24 | */ 25 | exports.createBPMNBoundaryEvent = function createBPMNBoundaryEvent(bpmnId, name, type, attachedToRef, cancelActivity) { 26 | log.debug(log.defaultContext(), 'BPMN boundary constructor called'); 27 | return (new BPMNBoundaryEvent(bpmnId, name, type, attachedToRef, cancelActivity)); 28 | }; 29 | 30 | 31 | /** 32 | * Subsumes all kind of start events 33 | * @param {String} bpmnId BpmnId 34 | * @param {String} name Name 35 | * @param {String} type Type 36 | * @param {String} attachedToRef AttachedToRef 37 | * @param {Object} cancelActivity CancelActivity 38 | * @constructor 39 | */ 40 | var BPMNBoundaryEvent = exports.BPMNBoundaryEvent = function BpmnBoundaryEvent(bpmnId, name, type, attachedToRef, cancelActivity) { 41 | BPMNFlowObject.call(this, bpmnId, name, type); 42 | this.isBoundaryEvent = true; 43 | this.attachedToRef = attachedToRef; 44 | this.cancelActivity = cancelActivity; 45 | }; 46 | util.inherits(BPMNBoundaryEvent, BPMNFlowObject); 47 | 48 | /** 49 | * Validate assertions for name and sequence flows 50 | * @param {BPMNProcessDefinition} processDefinition Process-Definition 51 | * @param {BPMNParseErrorQueue} errorQueue ErrorQueue 52 | */ 53 | // BPMNBoundaryEvent.prototype.validate = function validate(processDefinition, errorQueue) { 54 | // this.assertName(errorQueue); 55 | // this.assertNoIncomingSequenceFlows(processDefinition, errorQueue); 56 | // this.assertOneOutgoingSequenceFlow(processDefinition, errorQueue); 57 | // }; 58 | -------------------------------------------------------------------------------- /lib/parsing/callactivity.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * ©2016-2017 EdgeVerve Systems Limited (a fully owned Infosys subsidiary), 4 | * Bangalore, India. All Rights Reserved. 5 | * 6 | */ 7 | 8 | 'use strict'; 9 | 10 | var logger = require('oe-logger'); 11 | var log = logger('CallActivity-Parser'); 12 | 13 | var BPMNActivity = require('./activity.js').BPMNActivity; 14 | var util = require('util'); 15 | var BPMNCallActivity; 16 | var checkAndAddMultiInstanceCharacteristics = require('./taskmarkers.js').checkAndAddMultiInstanceCharacteristics; 17 | var extractInputOutputParameters = require('./parse-utils/input-output-parameters.js').extractInputOutputParameters; 18 | var extractInOutMappings = require('./parse-utils/in-out-mappings.js').extractInOutMappings; 19 | 20 | /** 21 | * create a bpmn call activity 22 | * @param {Object} flowObject flowObject 23 | * @returns {Object} BPMNCallActivity 24 | */ 25 | exports.createBPMNCallActivity = function createBPMNCallActivity(flowObject) { 26 | log.debug(log.defaultContext(), 'BPMN Call Activity constructor called'); 27 | var bpmnId = flowObject.attributes_.id.value; 28 | var name = ''; 29 | if (typeof flowObject.attributes_.name !== 'undefined') { 30 | name = flowObject.attributes_.name.value; 31 | } 32 | var type = flowObject.attributes_ns.local; 33 | var calledElement = flowObject.attributes_.calledElement.value; 34 | 35 | var callActivityObject = new BPMNCallActivity(bpmnId, name, type, calledElement); 36 | checkAndAddMultiInstanceCharacteristics(flowObject, callActivityObject); 37 | if (flowObject['bpmn2:extensionElements'] && flowObject['bpmn2:extensionElements']['camunda:inputOutput']) { 38 | callActivityObject.inputOutputParameters = extractInputOutputParameters(flowObject['bpmn2:extensionElements']['camunda:inputOutput']); 39 | } 40 | if (flowObject['bpmn2:extensionElements'] ) { 41 | callActivityObject.inOutMappings = extractInOutMappings(flowObject['bpmn2:extensionElements']); 42 | } 43 | return callActivityObject; 44 | }; 45 | 46 | /** 47 | * Subsumes all kind of tasks 48 | * @param {String} bpmnId BpmnId 49 | * @param {String} name Name 50 | * @param {String} type Type 51 | * @param {String} calledElement Element 52 | * @constructor 53 | */ 54 | BPMNCallActivity = exports.BPMNCallActivity = function BPMNCallActivity(bpmnId, name, type, calledElement) { 55 | BPMNActivity.call(this, bpmnId, name, type); 56 | this.isCallActivity = true; 57 | this.subProcessId = calledElement; 58 | this.isMultiInstanceLoop = false; 59 | this.isSequential = false; 60 | }; 61 | util.inherits(BPMNCallActivity, BPMNActivity); 62 | 63 | /** 64 | * Validate assertions for name and sequence flows 65 | * @param {BPMNProcessDefinition} processDefinition Process-Definition 66 | * @param {BPMNParseErrorQueue} errorQueue ErrorQueue 67 | */ 68 | // BPMNCallActivity.prototype.validate = function validate(processDefinition, errorQueue) { 69 | // this.assertName(errorQueue); 70 | // this.assertIncomingSequenceFlows(processDefinition, errorQueue); 71 | // this.assertOutgoingSequenceFlows(processDefinition, errorQueue); 72 | // if (typeof this.subProcessId === 'undefined') { 73 | // errorQueue.addError('SubprocessId must be defined'); 74 | // } 75 | // }; 76 | -------------------------------------------------------------------------------- /lib/parsing/collaborationdefinition.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * ©2016-2017 EdgeVerve Systems Limited (a fully owned Infosys subsidiary), 4 | * Bangalore, India. All Rights Reserved. 5 | * 6 | */ 7 | 8 | 'use strict'; 9 | 10 | var BPMNParticipant = require('./participant.js'); 11 | var BPMNMessageFlows = require('./messageflows.js'); 12 | var logger = require('oe-logger'); 13 | var log = logger('Collaboration-Parser'); 14 | 15 | /** 16 | * Instantiate a bpmn collaboration definition 17 | * @param {String} bpmnId BpmnId 18 | * @param {Array} participants All the participants of the Collaboration 19 | * @param {Array} messageFlows All the message flows between the collaborating processes 20 | * @constructor 21 | */ 22 | function BPMNCollaborationDefinition(bpmnId, participants, messageFlows) { 23 | this.bpmnId = bpmnId; 24 | this.participants = participants; 25 | this.messageFlows = messageFlows; 26 | this.isCollaborationDefinition = true; 27 | } 28 | 29 | /** 30 | * get a participant by process id 31 | * @param {String} processBpmnId ProcessBpmnId 32 | * @return {BPMNParticipant} BPMNParticipant 33 | */ 34 | BPMNCollaborationDefinition.prototype.getParticipantByProcessId = function getParticipantByProcessId(processBpmnId) { 35 | var participants = this.participants.filter(function filterParticipants(participant) { 36 | return (participant.processRef === processBpmnId); 37 | }); 38 | if (participants.length > 1) { 39 | log.error(log.defaultContext(), "Cannot uniquely assign a pool to the process whith the BPMN ID '" + processBpmnId + "'"); 40 | } 41 | return participants[0]; 42 | }; 43 | 44 | /** 45 | * Get all participants the process is collaborating with 46 | * @param {String} processBpmnId ProcessBpmnId 47 | * @return {[BPMNParticipant]} BPMNParticipants 48 | */ 49 | BPMNCollaborationDefinition.prototype.getCollaboratingParticipants = function getCollaboratingParticipants(processBpmnId) { 50 | return this.participants.filter(function filterParticipants(participant) { 51 | return (participant.processRef !== processBpmnId); 52 | }); 53 | }; 54 | 55 | /** 56 | * Get all participants the process is collaborating with 57 | * @param {String} processBpmnId ProcessBpmnId 58 | * @return {[BPMNParticipant]} BPMNParticipants 59 | */ 60 | BPMNCollaborationDefinition.prototype.getMessageFlows = function getMessageFlows() { 61 | return this.messageFlows; 62 | }; 63 | 64 | 65 | /** 66 | * create a bpmn collaboration definition 67 | * @param {Object} defObject Raw parsed definition of collaboration process 68 | * @return {BPMNCollaborationDefinition} BPMNCollaborationDefinition 69 | */ 70 | exports.createBPMNCollaborationDefinition = function createBPMNCollaborationDefinition(defObject) { 71 | if (typeof defObject !== 'undefined') { 72 | if (defObject.hasOwnProperty('attributes_') && defObject.attributes_.hasOwnProperty('id')) { 73 | var bpmnId = defObject.attributes_.id.value; 74 | } 75 | } 76 | 77 | var participants = BPMNParticipant.createBPMNParticipant(defObject['bpmn2:participant'] || defObject['bpmn:participant']); 78 | var messageFlows = BPMNMessageFlows.createBPMNMessageFlow(defObject['bpmn2:messageFlow'] || defObject['bpmn:messageFlow']); 79 | return (new BPMNCollaborationDefinition(bpmnId, participants, messageFlows)); 80 | }; 81 | 82 | 83 | -------------------------------------------------------------------------------- /lib/parsing/endevents.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * ©2016-2017 EdgeVerve Systems Limited (a fully owned Infosys subsidiary), 4 | * Bangalore, India. All Rights Reserved. 5 | * 6 | */ 7 | 8 | 'use strict'; 9 | 10 | var logger = require('oe-logger'); 11 | var log = logger('EndEvent-Parser'); 12 | 13 | var util = require('util'); 14 | var BPMNFlowObject = require('./flowobject.js').BPMNFlowObject; 15 | var BPMNEndEvent; 16 | 17 | /** 18 | * create bpmn end event 19 | * @param {String} bpmnId BpmnId 20 | * @param {String} name Name 21 | * @param {String} type Type 22 | * @return {BPMNEndEvent} BPMNEndEvent 23 | */ 24 | exports.createBPMNEndEvent = function createBPMNEndEvent(bpmnId, name, type) { 25 | log.debug(log.defaultContext(), 'Bpmn End Event constructor called.'); 26 | return (new BPMNEndEvent(bpmnId, name, type)); 27 | }; 28 | 29 | /** 30 | * Subsumes all kind of end events 31 | * @param {String} bpmnId BpmnId 32 | * @param {String} name Name 33 | * @param {String} type Type 34 | * @constructor 35 | */ 36 | BPMNEndEvent = exports.BPMNEndEvent = function BPMNEndEvent(bpmnId, name, type) { 37 | BPMNFlowObject.call(this, bpmnId, name, type); 38 | this.isEndEvent = true; 39 | }; 40 | util.inherits(BPMNEndEvent, BPMNFlowObject); 41 | 42 | /** 43 | * Validate assertions for name and sequence flows 44 | * @param {BPMNProcessDefinition} processDefinition processDefinition 45 | * @param {BPMNParseErrorQueue} errorQueue ErrorQueue 46 | */ 47 | BPMNEndEvent.prototype.validate = function validate(processDefinition, errorQueue) { 48 | this.assertName(errorQueue); 49 | this.assertIncomingSequenceFlows(processDefinition, errorQueue); 50 | this.assertNoOutgoingSequenceFlows(processDefinition, errorQueue); 51 | }; 52 | -------------------------------------------------------------------------------- /lib/parsing/evtags.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * ©2016-2017 EdgeVerve Systems Limited (a fully owned Infosys subsidiary), 4 | * Bangalore, India. All Rights Reserved. 5 | * 6 | */ 7 | 8 | 'use strict'; 9 | var parserUtils = require('./parserutils'); 10 | var logger = require('oe-logger'); 11 | var log = logger('EVTags-Parser'); 12 | 13 | var QueryString = exports.queryString = function queryString(type, key, value) { 14 | this.type = type; 15 | this.key = key; 16 | this.value = value; 17 | }; 18 | 19 | exports.createQueryString = function createQueryString(node) { 20 | var getValue = parserUtils.getAttributesValue; 21 | log.debug(log.defaultContext(), 'query string constructor called.'); 22 | return (new QueryString( 23 | node.local, 24 | getValue(node, 'key'), 25 | getValue(node, 'value') 26 | )); 27 | }; 28 | 29 | exports.hasSpecifiedAttribute = function hasSpecifiedAttribute(name, attribute) { 30 | return (name.toLowerCase().indexOf(attribute) > -1); 31 | }; 32 | -------------------------------------------------------------------------------- /lib/parsing/messageflows.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * ©2016-2017 EdgeVerve Systems Limited (a fully owned Infosys subsidiary), 4 | * Bangalore, India. All Rights Reserved. 5 | * 6 | */ 7 | 8 | 'use strict'; 9 | 10 | var logger = require('oe-logger'); 11 | var log = logger('MessageFlows-Parser'); 12 | 13 | /** 14 | * create a bpmn message flow 15 | * @param {String} bpmnId BpmnId 16 | * @param {String} name Name 17 | * @param {String} type Tyoe 18 | * @param {String} sourceRef SourceRef 19 | * @param {String} targetRef TargetRef 20 | * @constructor 21 | */ 22 | function BPMNMessageFlow(bpmnId, name, type, sourceRef, targetRef) { 23 | this.bpmnId = bpmnId; 24 | this.name = name; 25 | this.type = type; 26 | this.sourceRef = sourceRef; 27 | this.targetRef = targetRef; 28 | this.targetProcessDefinitionId = null; 29 | this.sourceProcessDefinitionId = null; 30 | } 31 | /** 32 | * create an array of message flows in a collaboration process 33 | * @param {Array} defObject Array of Message Flows for a collaboration process 34 | * @constructor 35 | */ 36 | exports.createBPMNMessageFlow = function createBPMNMessageFlow(defObject) { 37 | log.debug(log.defaultContext(), 'BPMN Message Flow constructor called.'); 38 | var messageflows = []; 39 | if (typeof defObject === 'undefined') { 40 | return messageflows; 41 | } 42 | if (typeof defObject === 'object' && defObject.constructor.name === 'Array') { 43 | for (var messageflow of defObject) { 44 | messageflows.push(createMessageFlows(messageflow)); 45 | } 46 | } 47 | if (typeof defObject === 'object' && defObject.constructor.name === 'Object') { 48 | messageflows.push(createMessageFlows(defObject)); 49 | } 50 | return messageflows; 51 | }; 52 | 53 | function createMessageFlows(messageflow) { 54 | var bpmnId = messageflow.attributes_.id.value; 55 | var name = ''; 56 | if (typeof messageflow.attributes_.name !== 'undefined') { 57 | name = messageflow.attributes_.name.value; 58 | } 59 | var type = messageflow.attributes_ns.local; 60 | var sourceRef = messageflow.attributes_.sourceRef.value; 61 | var targetRef = messageflow.attributes_.targetRef.value; 62 | var finalMessageFlow = new BPMNMessageFlow(bpmnId, name, type, sourceRef, targetRef); 63 | return finalMessageFlow; 64 | } 65 | -------------------------------------------------------------------------------- /lib/parsing/parse-utils/in-out-mappings.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * 4 | * ©2016-2017 EdgeVerve Systems Limited (a fully owned Infosys subsidiary), 5 | * Bangalore, India. All Rights Reserved. 6 | * 7 | */ 8 | 9 | /** 10 | * Add Extension Elements to the task object 11 | * @param {BPMNProcessDefinition} defObject ProcessDefinition 12 | * @returns {Object} inoutmappings 13 | 14 | */ 15 | module.exports.extractInOutMappings = function extractInOutMappings(defObject) { 16 | var inputParametersObj = defObject['camunda:in']; 17 | var outputParametersObj = defObject['camunda:out']; 18 | var inputOutputMappings = {'inputMappings': createInputOutputMappings(inputParametersObj), 19 | 'outputMappings': createInputOutputMappings(outputParametersObj) }; 20 | return inputOutputMappings; 21 | }; 22 | 23 | /** 24 | * Return the input/output parameters 25 | * @param {Object} inputOutputParameter inputOutputParameter 26 | * @returns {boolean} isServiceTask 27 | */ 28 | function createInputOutputMappings(inputOutputParameter) { 29 | var source; 30 | var target; 31 | var inputMappings = {}; 32 | var input; 33 | if (typeof inputOutputParameter !== 'undefined' && inputOutputParameter.constructor.name === 'Array') { 34 | for (input of inputOutputParameter) { 35 | source = ''; 36 | if (input.attributes_ && input.attributes_.source) { 37 | source = input.attributes_.source.value; 38 | } else if (input.attributes_ && input.attributes_.sourceExpression) { 39 | source = input.attributes_.sourceExpression.value; 40 | } else if (input.attributes_ && input.attributes_.variables) { 41 | source = input.attributes_.variables.value; 42 | } 43 | if (source === 'variables') { 44 | target = 'all'; 45 | } else if (source && source !== '') { 46 | source = source.replace(/\W/g, ''); 47 | if (input.attributes_ && input.attributes_.target) { 48 | target = input.attributes_.target.value; 49 | } else { 50 | target = ''; 51 | } 52 | } else { 53 | target = ''; 54 | } 55 | inputMappings[source] = target; 56 | } 57 | } else if (typeof inputOutputParameter !== 'undefined' && inputOutputParameter.constructor.name === 'Object') { 58 | input = inputOutputParameter; 59 | source = ''; 60 | if (input.attributes_ && input.attributes_.source) { 61 | source = input.attributes_.source.value; 62 | } else if (input.attributes_ && input.attributes_.sourceExpression) { 63 | source = input.attributes_.sourceExpression.value; 64 | } else if (input.attributes_ && input.attributes_.variables) { 65 | source = input.attributes_.variables.value; 66 | } 67 | if (source === 'variables') { 68 | target = 'all'; 69 | } else if (source && source !== '') { 70 | if (input.attributes_ && input.attributes_.target) { 71 | target = input.attributes_.target.value; 72 | } else { 73 | target = ''; 74 | } 75 | } else { 76 | target = ''; 77 | } 78 | inputMappings[source] = target; 79 | } 80 | 81 | return inputMappings; 82 | } 83 | 84 | 85 | -------------------------------------------------------------------------------- /lib/parsing/participant.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * ©2016-2017 EdgeVerve Systems Limited (a fully owned Infosys subsidiary), 4 | * Bangalore, India. All Rights Reserved. 5 | * 6 | */ 7 | 8 | 9 | 'use strict'; 10 | 11 | var logger = require('oe-logger'); 12 | var log = logger('Participant-Parser'); 13 | 14 | /** 15 | * Create a bpmn participant 16 | * @param {String} bpmnId BpmnId 17 | * @param {String} name Name 18 | * @param {String} type Type 19 | * @param {String} processRef ProcessRef 20 | * @constructor 21 | */ 22 | function BPMNParticipant(bpmnId, name, type, processRef) { 23 | log.debug(log.defaultContext(), 'BPMNParticipant called'); 24 | this.bpmnId = bpmnId; 25 | this.name = name; 26 | this.type = type; 27 | this.processRef = processRef; 28 | } 29 | 30 | 31 | /** 32 | * create an array of all participants in a collaboration definition 33 | * @param {Object} defObject An array of participants in a collaboration entity 34 | * @constructor 35 | */ 36 | exports.createBPMNParticipant = function createBPMNParticipant(defObject) { 37 | var participants = []; 38 | var bpmnId; 39 | var name; 40 | var processRef; 41 | var type; 42 | var finalParticipant; 43 | var participant; 44 | if (typeof defObject !== 'undefined' && defObject.constructor.name === 'Array') { 45 | for (participant of defObject) { 46 | name = ''; 47 | bpmnId = ''; 48 | processRef = null; 49 | if (participant.hasOwnProperty('attributes_')) { 50 | if (participant.attributes_.hasOwnProperty('id')) { 51 | bpmnId = participant.attributes_.id.value; 52 | } 53 | if (participant.attributes_.hasOwnProperty('name')) { 54 | name = participant.attributes_.name.value; 55 | } 56 | if (participant.attributes_.hasOwnProperty('processRef')) { 57 | processRef = participant.attributes_.processRef.value; 58 | } 59 | } 60 | if (participant.hasOwnProperty('attributes_ns')) { 61 | type = participant.attributes_ns.local; 62 | } 63 | finalParticipant = new BPMNParticipant(bpmnId, name, type, processRef); 64 | participants.push(finalParticipant); 65 | } 66 | } 67 | if (defObject.constructor.name === 'Object') { 68 | participant = defObject; 69 | if (participant.hasOwnProperty('attributes_')) { 70 | if (participant.attributes_.hasOwnProperty('id')) { 71 | bpmnId = participant.attributes_.id.value; 72 | } 73 | if (participant.attributes_.hasOwnProperty('name')) { 74 | name = participant.attributes_.name.value; 75 | } 76 | if (participant.attributes_.hasOwnProperty('processRef')) { 77 | processRef = participant.attributes_.processRef.value; 78 | } 79 | } 80 | if (participant.hasOwnProperty('attributes_ns')) { 81 | type = participant.attributes_ns.local; 82 | } 83 | finalParticipant = new BPMNParticipant(bpmnId, name, type, processRef); 84 | participants.push(finalParticipant); 85 | } 86 | return participants; 87 | }; 88 | 89 | 90 | -------------------------------------------------------------------------------- /lib/parsing/sequenceflows.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * ©2016-2017 EdgeVerve Systems Limited (a fully owned Infosys subsidiary), 4 | * Bangalore, India. All Rights Reserved. 5 | * 6 | */ 7 | 8 | 'use strict'; 9 | 10 | var BPMNSequenceFlow; 11 | var logger = require('oe-logger'); 12 | var log = logger('SequenceFlow-Parser'); 13 | 14 | /** 15 | * Check if the name is of sequence flow 16 | * @param {String} localName name without namespace prefix 17 | * @return {Boolean} isSequenceFlowName 18 | */ 19 | exports.isSequenceFlowName = function isSequenceFlowName(localName) { 20 | return (localName.toLowerCase().indexOf('sequenceflow') > -1); 21 | }; 22 | 23 | /** 24 | * create a bpmn sequence flow 25 | * @param {String} bpmnId BpmnId 26 | * @param {String} name Name 27 | * @param {String} type Type 28 | * @param {String} sourceRef SourceRef 29 | * @param {String} targetRef TargetRef 30 | * @constructor 31 | */ 32 | BPMNSequenceFlow = exports.BPMNSequenceFlow = function BPMNSequenceFlow(bpmnId, name, type, sourceRef, targetRef) { 33 | log.debug(log.defaultContext(), 'BPMNSequenceFlow called'); 34 | this.bpmnId = bpmnId; 35 | this.name = name; 36 | this.type = type; 37 | this.sourceRef = sourceRef; 38 | this.targetRef = targetRef; 39 | this.isSequenceFlow = true; 40 | }; 41 | 42 | /** 43 | * Given a sequence flow node, create a sequence flow 44 | * @param {Object} flowObject flowObject 45 | * @constructor 46 | */ 47 | exports.createBPMNSequenceFlow = function createBPMNSequenceFlow(flowObject) { 48 | var bpmnId = flowObject.attributes_.id.value; 49 | var name = ''; 50 | if (typeof flowObject.attributes_.name !== 'undefined') { 51 | name = flowObject.attributes_.name.value; 52 | } 53 | var type = flowObject.attributes_ns.local; 54 | var sourceRef = flowObject.attributes_.sourceRef.value; 55 | var targetRef = flowObject.attributes_.targetRef.value; 56 | var sequenceFlowObject = new BPMNSequenceFlow(bpmnId, name, type, sourceRef, targetRef); 57 | if (flowObject.hasOwnProperty('bpmn2:conditionExpression')) { 58 | sequenceFlowObject.isConditionalFlow = true; 59 | sequenceFlowObject.script = flowObject['bpmn2:conditionExpression'].text; 60 | } else if (flowObject.hasOwnProperty('bpmn:conditionExpression')) { 61 | sequenceFlowObject.isConditionalFlow = true; 62 | sequenceFlowObject.script = flowObject['bpmn:conditionExpression'].text; 63 | } 64 | return sequenceFlowObject; 65 | }; 66 | -------------------------------------------------------------------------------- /lib/parsing/startevents.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * ©2016-2017 EdgeVerve Systems Limited (a fully owned Infosys subsidiary), 4 | * Bangalore, India. All Rights Reserved. 5 | * 6 | */ 7 | 8 | 'use strict'; 9 | 10 | var util = require('util'); 11 | var BPMNFlowObject = require('./flowobject.js').BPMNFlowObject; 12 | var BPMNStartEvent; 13 | var logger = require('oe-logger'); 14 | var log = logger('StartEvent-Parser'); 15 | 16 | /** 17 | * create a bpmn start event 18 | * @param {String} bpmnId BpmnId 19 | * @param {String} name Name 20 | * @param {String} type Type 21 | * @return {BPMNStartEvent} createBPMNStartEvent 22 | */ 23 | exports.createBPMNStartEvent = function createBPMNStartEvent(bpmnId, name, type) { 24 | return (new BPMNStartEvent(bpmnId, name, type)); 25 | }; 26 | 27 | /** 28 | * Subsumes all kind of start events 29 | * @param {String} bpmnId BpmnId 30 | * @param {String} name Name 31 | * @param {String} type Type 32 | * @param {Boolean} isInterrupting IsInterrupting 33 | * @constructor 34 | */ 35 | BPMNStartEvent = function BPMNStartEvent(bpmnId, name, type, isInterrupting) { 36 | log.debug(log.defaultContext(), 'BPMNStartEvent called'); 37 | 38 | BPMNFlowObject.call(this, bpmnId, name, type); 39 | this.isStartEvent = true; 40 | }; 41 | util.inherits(BPMNStartEvent, BPMNFlowObject); 42 | 43 | exports.BPMNStartEvent = BPMNStartEvent; 44 | 45 | /** 46 | * validatee assertions for name and sequence flows 47 | * @param {BPMNProcessDefinition} processDefinition ProcessDefinition 48 | * @param {BPMNParseErrorQueue} errorQueue ErrorQueue 49 | */ 50 | BPMNStartEvent.prototype.validate = function validate(processDefinition, errorQueue) { 51 | this.assertName(errorQueue); 52 | this.assertNoIncomingSequenceFlows(processDefinition, errorQueue); 53 | this.assertOneOutgoingSequenceFlow(processDefinition, errorQueue); 54 | }; 55 | -------------------------------------------------------------------------------- /lib/utils/process-tokens.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * ©2016-2017 EdgeVerve Systems Limited (a fully owned Infosys subsidiary), 4 | * Bangalore, India. All Rights Reserved. 5 | * 6 | */ 7 | /** 8 | * Implementation of Process-Token 9 | * @author Kangan Verma(kangan06), Mandeep Gill(mandeep6ill), Prem Sai(premsai-ch), Vivek Mittal(vivekmittal07) 10 | */ 11 | 12 | const uuidv4 = require('uuid/v4'); 13 | 14 | module.exports.createToken = function createToken(name, bpmnId, message, meta) { 15 | name = name || bpmnId; 16 | return new ProcessToken(name, bpmnId, message, meta); 17 | }; 18 | 19 | /* Unused Functions */ 20 | // module.exports.findToken = function findToken(tokens, id) { 21 | // if (typeof tokens[id] !== 'undefined') { 22 | // return tokens[id]; 23 | // } 24 | // }; 25 | // module.exports.remove = function remove(token) { 26 | // token.status = 'done'; 27 | // token.endTime = new Date(); 28 | // }; 29 | /* End: Unused Functions */ 30 | 31 | var ProcessToken = function ProcessToken(name, bpmnId, message, meta) { 32 | this.name = name; 33 | this.startTime = new Date(); 34 | this.bpmnId = bpmnId; 35 | this.id = uuidv4(); 36 | this.status = 'pending'; 37 | if ( message instanceof Error ) { 38 | this.message = {}; 39 | var props = Object.getOwnPropertyNames(message); 40 | for (let i = 0; i < props.length; i++) { 41 | this.message[props[i]] = message[props[i]]; 42 | } 43 | } else if (typeof message !== 'undefined') { 44 | this.message = message; 45 | } 46 | if (typeof meta !== 'undefined') { 47 | this.meta = meta; 48 | } 49 | }; 50 | 51 | // ProcessToken.prototype.validate = function validate() { 52 | // if (typeof this.name === 'undefined') { 53 | // // Should never happen, validation of bpmn done already 54 | // log.error('Invalid token name'); 55 | // return false; 56 | // } 57 | // return true; 58 | // }; 59 | -------------------------------------------------------------------------------- /lib/utils/throwobject.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * ©2016-2017 EdgeVerve Systems Limited (a fully owned Infosys subsidiary), 4 | * Bangalore, India. All Rights Reserved. 5 | * 6 | */ 7 | /** 8 | * @description Throw Object 9 | * @author Kangan Verma(kangan06), Mandeep Gill(mandeep6ill), Prem Sai(premsai-ch), Vivek Mittal(vivekmittal07) 10 | */ 11 | 12 | 'use strict'; 13 | 14 | /** 15 | * @param {String} type Type 16 | * @param {String} id Id 17 | * @param {String} msg message 18 | * @returns {void} 19 | */ 20 | exports.throwObject = function throwObj(type, id, msg) { 21 | var throwObj = {}; 22 | throwObj.type = type; 23 | throwObj.id = id || null; 24 | if (type === 'message') { 25 | if (msg) { 26 | if (msg.messageRef) { 27 | throwObj.id = msg.messageRef; 28 | } 29 | if (msg.payload) { 30 | throwObj.message = msg.payload; 31 | } 32 | if (msg.businessKey) { 33 | throwObj.businessKey = msg.businessKey; 34 | } 35 | } 36 | } 37 | if (type === 'escalation' || type === 'error') { 38 | throwObj.code = msg; 39 | } 40 | if (type === 'signal') { 41 | throwObj.attachedTokenId = ( msg && msg.tokenId ? msg.tokenId : null); 42 | } 43 | return throwObj; 44 | }; 45 | -------------------------------------------------------------------------------- /lib/utils/timeout-calculator.js: -------------------------------------------------------------------------------- 1 | var isoDuration = require('iso8601-duration'); 2 | 3 | function getDate(definition, base) { 4 | let retVal; 5 | if (!isNaN(Date.parse(definition))) { 6 | retVal = new Date(definition); 7 | } else { 8 | definition = isoDuration.parse(definition); 9 | retVal = isoDuration.end(definition, base); 10 | } 11 | return retVal; 12 | } 13 | 14 | function getSeconds(definition) { 15 | definition = isoDuration.parse(definition); 16 | return isoDuration.toSeconds(definition); 17 | } 18 | 19 | function getSchedule(definition, base) { 20 | base = base || new Date(); 21 | 22 | let retVal = { 23 | perpetual: false, 24 | definition: definition 25 | }; 26 | if (definition instanceof Date) { 27 | retVal.items = [definition]; 28 | } else if (!isNaN(Number(definition))) { 29 | retVal.items = [new Date(base.getTime() + Number(definition))]; 30 | } else if (!isNaN(Date.parse(definition))) { 31 | retVal.items = [new Date(definition)]; 32 | } else if (definition[0] === 'P') { 33 | /* Simple period or Array of periods */ 34 | retVal.items = definition.split('#').map(item => { 35 | let parsed = isoDuration.parse(item.trim()); 36 | return isoDuration.end(parsed, base); 37 | }); 38 | } else if (definition[0] === 'R') { 39 | let parts = definition.split('/'); 40 | let recurrence = Number(parts[0].substr(1)); 41 | if (recurrence < 0 || isNaN(recurrence)) { 42 | recurrence = 1; 43 | } else if (recurrence === 0) { 44 | retVal.perpetual = true; 45 | } 46 | let periodDef = parts[1]; 47 | retVal.items = []; 48 | if (parts.length === 3) { 49 | /* Recurring periods with specified start/period */ 50 | base = getDate(parts[1].trim(), base); 51 | periodDef = parts[2]; 52 | retVal.definition = periodDef; 53 | retVal.items.push(base); 54 | recurrence -= 1; 55 | } 56 | 57 | let parsed = isoDuration.parse(periodDef); 58 | let newDate = base; 59 | for (let i = 0; i < recurrence; i++) { 60 | newDate = isoDuration.end(parsed, newDate); 61 | retVal.items.push(newDate); 62 | } 63 | } 64 | return retVal; 65 | } 66 | 67 | module.exports = { 68 | getSeconds, 69 | getDate, 70 | getSchedule 71 | }; 72 | -------------------------------------------------------------------------------- /lib/workflow-eventHandlers/processterminatehandlers.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * ©2016-2017 EdgeVerve Systems Limited (a fully owned Infosys subsidiary), 4 | * Bangalore, India. All Rights Reserved. 5 | * 6 | */ 7 | /** 8 | * @description Catch Event Handlers 9 | * @author Kangan Verma(kangan06), Mandeep Gill(mandeep6ill), Prem Sai(premsai-ch), Vivek Mittal(vivekmittal07) 10 | */ 11 | 12 | var logger = require('oe-logger'); 13 | var log = logger('ProcessInstance'); 14 | var StateDelta = require('../../process-state-delta.js'); 15 | 16 | var SUBPROCESS_INTERRUPT_EVENT = 'PROCESS_TERMINATE'; 17 | 18 | var exports = module.exports = {}; 19 | exports._processTerminateHandler = function _processTerminateHandler(options, processInstance, currentProcess, done) { 20 | var delta = new StateDelta(); 21 | delta.setProcessStatus('terminated'); 22 | currentProcess.commit(options, delta, function commitCb(err) { 23 | if (err) { 24 | log.error(options, err); 25 | return; 26 | } 27 | }); 28 | currentProcess.subProcesses({}, options, function fetchPI(err, subProcesses) { 29 | if (err) { 30 | log.error(options, err); 31 | return; 32 | } 33 | for (var i in subProcesses) { 34 | if (Object.prototype.hasOwnProperty.call(subProcesses, i)) { 35 | processInstance.emit(SUBPROCESS_INTERRUPT_EVENT, options, processInstance, subProcesses[i]); 36 | } 37 | } 38 | }); 39 | }; 40 | -------------------------------------------------------------------------------- /lib/workflow-eventHandlers/taskeventhandler.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * ©2016-2017 EdgeVerve Systems Limited (a fully owned Infosys subsidiary), 4 | * Bangalore, India. All Rights Reserved. 5 | * 6 | */ 7 | /** 8 | * @description Task Event Handlers 9 | * @author Mandeep Gill(mandeep6ill), Prem Sai(premsai-ch) 10 | */ 11 | 12 | var logger = require('oe-logger'); 13 | var log = logger('Task'); 14 | 15 | var exports = module.exports = {}; 16 | 17 | exports._taskInterruptHandler = function _taskInterruptHandler(options, Task, currentTask) { 18 | var version = currentTask._version; 19 | currentTask.updateAttributes({ 20 | 'status': 'interrupted', 21 | '_version': version 22 | }, options, function fetchTask(err, utask) { 23 | /* istanbul ignore if*/ 24 | if (err) { 25 | return log.error(err); 26 | } 27 | }); 28 | }; 29 | -------------------------------------------------------------------------------- /lib/workflow-nodes/evaluate-sequence-flow.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * ©2016-2017 EdgeVerve Systems Limited (a fully owned Infosys subsidiary), 4 | * Bangalore, India. All Rights Reserved. 5 | * 6 | */ 7 | /** 8 | * @description Sequence Flow Condition Evaluator 9 | * @author Kangan Verma(kangan06), Mandeep Gill(mandeep6ill), Prem Sai(premsai-ch), Vivek Mittal(vivekmittal07) 10 | */ 11 | 12 | var sandbox = require('./sandbox.js'); 13 | 14 | /* 15 | * Evaluates the expression on the outgoing flow 16 | * @return result of expression 17 | */ 18 | module.exports.evaluate = function evaluateSF(options, flow, message, process) { 19 | var conditionTrue = false; 20 | 21 | if (flow.script) { 22 | conditionTrue = sandbox.evaluateExpression(options, flow.script, message, process); 23 | } else { 24 | conditionTrue = message && (message.path === flow.name); 25 | } 26 | return conditionTrue; 27 | }; 28 | -------------------------------------------------------------------------------- /lib/wrapper.js: -------------------------------------------------------------------------------- 1 | const log = require('oe-logger')('oe-workflow'); 2 | module.exports = function wrapper(app) { 3 | log.info('oe-workflow is loaded : '); 4 | }; 5 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "oe-workflow", 3 | "description": "oe-workflow engine written using oecloud.io framework", 4 | "version": "2.3.0", 5 | "engines": { 6 | "node": ">=6" 7 | }, 8 | "main": "index.js", 9 | "scripts": { 10 | "clean": "if-env NODE_ENV=oracle && npm run clean:oracle || npm run clean2", 11 | "clean2": "if-env NODE_ENV=postgres && npm run clean:postgres || npm run clean:mongo", 12 | "clean:mongo": "mongo oe-workflow-test --eval \"db.dropDatabase();\"", 13 | "clean:oracle": "node test/oracle-utility.js", 14 | "clean:postgres": "echo \"Not implemented\" && exit 1", 15 | "pretest": "npm install --no-optional", 16 | "test": "grunt mochaTest", 17 | "lint": "eslint .", 18 | "fix-lint": "eslint --fix .", 19 | "grunt-cover": "grunt test-with-coverage", 20 | "checks": "eslint . && npm run clean && grunt test-with-coverage", 21 | "app": "node bin/app.js" 22 | }, 23 | "dependencies": { 24 | "async": "2.6.1", 25 | "iso8601-duration": "1.2.0", 26 | "loopback-connector-rest": "3.7.0", 27 | "oe-cloud": "^2.0.0", 28 | "oe-common-mixins": "^2.0.0", 29 | "oe-master-job-executor": "^2.0.0", 30 | "uuid": "3.3.2", 31 | "xml2js": "0.4.17" 32 | }, 33 | "devDependencies": { 34 | "babel-eslint": "7.2.3", 35 | "chai": "3.4.1", 36 | "chai-datetime": "1.4.0", 37 | "chai-things": "0.2.0", 38 | "chalk": "1.1.1", 39 | "eslint": "4.10.0", 40 | "grunt": "1.0.4", 41 | "grunt-cli": "1.3.2", 42 | "grunt-contrib-clean": "2.0.0", 43 | "grunt-mocha-istanbul": "5.0.2", 44 | "if-env": "1.0.4", 45 | "istanbul": "0.4.5", 46 | "mocha": "5.2.0", 47 | "oe-business-rule": "^2.0.0", 48 | "oe-connector-mongodb": "^2.0.0", 49 | "oe-connector-oracle": "^2.0.0", 50 | "oe-connector-postgresql": "^2.0.0", 51 | "superagent-defaults": "0.1.14", 52 | "supertest": "3.4.2" 53 | }, 54 | "license": "MIT", 55 | "repository": { 56 | "type": "git", 57 | "url": "https://github.com/EdgeVerve/oe-workflow.git" 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /server/boot/01-load-addon.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * ©2016-2017 EdgeVerve Systems Limited (a fully owned Infosys subsidiary), 4 | * Bangalore, India. All Rights Reserved. 5 | * 6 | */ 7 | /** 8 | * Boot Script for attaching workflow on boot 9 | * @author Rohit Khode(kvsrohit) 10 | */ 11 | var logger = require('oe-logger'); 12 | var log = logger('load-addon.boot'); 13 | var path = require('path'); 14 | 15 | module.exports = function recoverWorkflows(app) { 16 | let workflowAddons = {}; 17 | var wfConfig = app.get('workflow') || {}; 18 | if (wfConfig.addonModule) { 19 | let modulePath = path.resolve(wfConfig.addonModule); 20 | log.debug('Trying to load addon module at ' + modulePath); 21 | workflowAddons = require(modulePath); 22 | /* No try-catch. let it throw error during startup if specified addon-module is not found */ 23 | } 24 | app.workflowAddons = workflowAddons; 25 | }; 26 | -------------------------------------------------------------------------------- /server/boot/03-attach-workflow.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * ©2016-2017 EdgeVerve Systems Limited (a fully owned Infosys subsidiary), 4 | * Bangalore, India. All Rights Reserved. 5 | * 6 | */ 7 | /** 8 | * Boot Script for attaching workflow on boot for version 1&2 9 | * @author Mandeep Gill(mandeep6ill), Prem Sai(premsai-ch) 10 | */ 11 | var logger = require('oe-logger'); 12 | var log = logger('attach-workflow.boot'); 13 | var applyMakerCheckerMixin1 = require('../../common/mixins/maker-checker-mixin-v1.js'); 14 | var applyMakerCheckerMixin2 = require('../../common/mixins/maker-checker-mixin-v2.js'); 15 | var workflowMixin = require('../../common/mixins/workflow-mixin.js'); 16 | 17 | module.exports = function attachWorkFlows(app) { 18 | var WorkflowMapping = app.models.WorkflowMapping; 19 | var options = { 20 | ctx: {}, 21 | ignoreAutoScope: true, 22 | fetchAllScopes: true 23 | }; 24 | 25 | WorkflowMapping.find({ 26 | where: { 27 | and: [{ 28 | engineType: 'oe-workflow' 29 | }, { 30 | version: {inq: ['v0', 'v1', 'v2']} 31 | }] 32 | } 33 | }, options, function fetchWM(err, result) { 34 | /* istanbul ignore if*/ 35 | if (err) { 36 | log.error(options, err); 37 | } else { 38 | var WorkflowMaps = result; 39 | WorkflowMaps.forEach(mapping => { 40 | var Model = app.models[mapping.actualModelName]; 41 | if (mapping.version === 'v1') { 42 | applyMakerCheckerMixin1(Model); 43 | } else if (mapping.version === 'v2') { 44 | applyMakerCheckerMixin2(Model); 45 | } else { 46 | workflowMixin(Model); 47 | } 48 | }); 49 | } 50 | }); 51 | }; 52 | -------------------------------------------------------------------------------- /server/middleware.json: -------------------------------------------------------------------------------- 1 | { 2 | "initial:before": {}, 3 | "initial": { 4 | "compression": {}, 5 | "cors": { 6 | "params": { 7 | "origin": true, 8 | "credentials": true, 9 | "maxAge": 86400 10 | } 11 | } 12 | }, 13 | "session:before": {}, 14 | "session": {}, 15 | "session:after": {}, 16 | "auth": {}, 17 | "auth:after": {}, 18 | "parse": {}, 19 | "routes:before": {}, 20 | "routes": {}, 21 | "files": {}, 22 | "final": {}, 23 | "final:after": {} 24 | } -------------------------------------------------------------------------------- /server/model-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "_meta": { 3 | "sources": [ 4 | "loopback/common/models", 5 | "loopback/server/models", 6 | "../common/models", 7 | "../common/activiti-models" 8 | ], 9 | "mixins": [] 10 | }, 11 | "ProcessDefinition": { 12 | "dataSource": "db", 13 | "public": true 14 | }, 15 | "ProcessInstance": { 16 | "dataSource": "db", 17 | "public": true 18 | }, 19 | "Task": { 20 | "dataSource": "db", 21 | "public": true 22 | }, 23 | "WorkflowBaseEntity": { 24 | "dataSource": "db", 25 | "public": false 26 | }, 27 | "bpmndata": { 28 | "dataSource": "db", 29 | "public": true 30 | }, 31 | "WorkflowDefinition": { 32 | "dataSource": "db", 33 | "public": true 34 | }, 35 | "WorkflowInstance": { 36 | "dataSource": "db", 37 | "public": true 38 | }, 39 | "WorkflowRequest": { 40 | "dataSource": "db", 41 | "public": true 42 | }, 43 | "WorkflowManager": { 44 | "dataSource": "db", 45 | "public": true 46 | }, 47 | "Activiti_Manager": { 48 | "dataSource": "db", 49 | "public": true 50 | }, 51 | "Activiti_BaseEntity": { 52 | "dataSource": "db", 53 | "public": false 54 | }, 55 | "Activiti_Account": { 56 | "dataSource": "db", 57 | "public": true 58 | }, 59 | "Activiti_WorkflowRequest": { 60 | "dataSource": "db", 61 | "public": true 62 | }, 63 | "WorkflowMapping" :{ 64 | "dataSource": "db", 65 | "public": false 66 | }, 67 | "WorkflowSignal" :{ 68 | "dataSource": "db", 69 | "public": false 70 | }, 71 | "ChangeWorkflowRequest" :{ 72 | "dataSource": "db", 73 | "public":true 74 | }, 75 | "DurableTimeout": { 76 | "dataSource": "db", 77 | "public": true 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /server/server.js: -------------------------------------------------------------------------------- 1 | var oecloud = require('oe-cloud'); 2 | 3 | oecloud.observe('loaded', function loadedCb(ctx, next) { 4 | return next(); 5 | }); 6 | 7 | oecloud.boot(__dirname, function bootCb(err) { 8 | if (err) { 9 | throw err; 10 | } 11 | oecloud.start(); 12 | oecloud.emit('oe-workflow-start'); 13 | }); 14 | -------------------------------------------------------------------------------- /test/app-list.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "path": "oe-cloud", 4 | "enabled": true 5 | }, 6 | { 7 | "path": "oe-master-job-executor", 8 | "enabled": true 9 | }, 10 | { 11 | "path": "oe-business-rule", 12 | "enabled": true 13 | }, 14 | { 15 | "path": "./", 16 | "forceLoad": "index.js", 17 | "enabled": true 18 | }, 19 | { 20 | "path": "./", 21 | "enabled": true, 22 | "serverDir": "test" 23 | } 24 | ] 25 | -------------------------------------------------------------------------------- /test/boot/populate-data.js: -------------------------------------------------------------------------------- 1 | module.exports = function populateData(app, done) { 2 | done(); 3 | // var Customer = loopback.findModel('Customer'); 4 | // Customer.destroyAll({}, { ignoreAutoScope : true }, function (err) { 5 | // console.log(err); 6 | // var item1 = { 7 | // 'name': 'Customer A', 8 | // 'age': 10 9 | // }; 10 | // var item2 = { 11 | // 'name': 'Infosys Customer', 12 | // 'age': 20 13 | // }; 14 | // var item3 = { 15 | // 'name': 'EV Customer', 16 | // 'age': 30 17 | // }; 18 | // var item4 = { 19 | // 'name': 'BPO Customer', 20 | // 'age': 30 21 | // }; 22 | // var item5 = { 23 | // 'name': 'BPO Customer A', 24 | // 'age': 30 25 | // }; 26 | // Customer.create(item1, { ctx: { tenantId: "/default" } }, function (err, r) { 27 | // Customer.create(item2, { ctx: { tenantId: "/default/infosys" } }, function (err, r) { 28 | // Customer.create(item3, { ctx: { tenantId: "/default/infosys/ev" } }, function (err, r) { 29 | // Customer.create([item4, item5], { ctx: { tenantId: "/default/infosys/bpo" } }, function (err, r) { 30 | // return done(); 31 | // }); 32 | // }); 33 | // }); 34 | // }); 35 | // }); 36 | }; 37 | 38 | -------------------------------------------------------------------------------- /test/bpmn-files/Adjustments.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EdgeVerve/oe-workflow/a8811c43d2b5b4b4dbbb97e920c2c2723ce2a013/test/bpmn-files/Adjustments.xlsx -------------------------------------------------------------------------------- /test/bpmn-files/DecisionTreeData.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "sampleTree", 3 | "nodes": [ 4 | { 5 | "id": "n-rkljn4byr", 6 | "name": "UserLocation", 7 | "nodeType": "DECISION_TABLE", 8 | "x": 574, 9 | "y": 8, 10 | "data": {}, 11 | "skipFeel": true 12 | }, 13 | { 14 | "id": "n-fub5yhz6f", 15 | "name": "Decision Gate 2", 16 | "nodeType": "DECISION_GATE", 17 | "x": 574, 18 | "y": 168, 19 | "data": {}, 20 | "skipFeel": true 21 | }, 22 | { 23 | "id": "n-rze21y6nh", 24 | "name": "eligibility_USA", 25 | "nodeType": "DECISION_TABLE", 26 | "x": 327, 27 | "y": 425, 28 | "data": {}, 29 | "skipFeel": true 30 | }, 31 | { 32 | "id": "n-rbnxnuxst", 33 | "name": "eligibility_FR", 34 | "nodeType": "DECISION_TABLE", 35 | "x": 856, 36 | "y": 432, 37 | "data": {}, 38 | "skipFeel": true 39 | } 40 | ], 41 | "connections": [ 42 | { 43 | "from": "n-rkljn4byr", 44 | "to": "n-fub5yhz6f", 45 | "id": "c-1ghbvmu02", 46 | "condition": "" 47 | }, 48 | { 49 | "from": "n-fub5yhz6f", 50 | "to": "n-rze21y6nh", 51 | "id": "c-ebty0cye", 52 | "condition": "location === \"US\"" 53 | }, 54 | { 55 | "from": "n-fub5yhz6f", 56 | "to": "n-rbnxnuxst", 57 | "id": "c-appxa5hi2u", 58 | "condition": "location == \"FR\"" 59 | } 60 | ] 61 | } -------------------------------------------------------------------------------- /test/bpmn-files/Service.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EdgeVerve/oe-workflow/a8811c43d2b5b4b4dbbb97e920c2c2723ce2a013/test/bpmn-files/Service.xlsx -------------------------------------------------------------------------------- /test/bpmn-files/collaboration-collapsed.bpmn: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SequenceFlow_1f38rjw 6 | 7 | 8 | 9 | SequenceFlow_0g4yn0e 10 | 11 | 12 | 13 | SequenceFlow_1f38rjw 14 | SequenceFlow_0g4yn0e 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /test/bpmn-files/correlationid-maker-checker.bpmn: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SequenceFlow_0mgca8w 6 | 7 | 8 | 9 | SequenceFlow_13ljoqk 10 | 11 | 12 | 13 | SequenceFlow_0mgca8w 14 | SequenceFlow_13ljoqk 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /test/bpmn-files/correlationid.bpmn: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SequenceFlow_0ltmpmb 6 | 7 | 8 | 9 | SequenceFlow_0ltmpmb 10 | SequenceFlow_1h9wvhv 11 | 12 | 13 | SequenceFlow_1h9wvhv 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /test/bpmn-files/dynamic-timer-start.bpmn: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | SequenceFlow_1i32fd8 7 | 8 | 9 | 10 | SequenceFlow_0xsgu7s 11 | SequenceFlow_1i32fd8 12 | var a = 10; 13 | 14 | 15 | SequenceFlow_0xsgu7s 16 | 17 | ${pv.tduration} 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /test/bpmn-files/maker-checker-v2-custom-remote.bpmn: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SequenceFlow_0o4zxcv 6 | 7 | 8 | 9 | SequenceFlow_08i273x 10 | 11 | 12 | 13 | SequenceFlow_0o4zxcv 14 | SequenceFlow_08i273x 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /test/bpmn-files/maker-checker-v2.bpmn: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SequenceFlow_0mgca8w 6 | 7 | 8 | 9 | SequenceFlow_13ljoqk 10 | 11 | 12 | 13 | SequenceFlow_0mgca8w 14 | SequenceFlow_13ljoqk 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /test/bpmn-files/multi-instance-parallel-child.bpmn: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SequenceFlow_0g51oz9 6 | 7 | 8 | SequenceFlow_1nxg4jb 9 | 10 | 11 | SequenceFlow_0g51oz9 12 | SequenceFlow_1nxg4jb 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /test/bpmn-files/timer-start.bpmn: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | SequenceFlow_1i32fd8 7 | 8 | 9 | 10 | SequenceFlow_0xsgu7s 11 | SequenceFlow_1i32fd8 12 | var a = 10; 13 | 14 | 15 | SequenceFlow_0xsgu7s 16 | 17 | 500 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /test/bpmn-files/user-task.bpmn: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SequenceFlow_0ltmpmb 6 | 7 | 8 | 9 | SequenceFlow_0ltmpmb 10 | SequenceFlow_1h9wvhv 11 | 12 | 13 | SequenceFlow_1h9wvhv 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /test/bpmn-files/workflow-manager.bpmn: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SequenceFlow_1gif5p2 6 | 7 | 8 | 9 | SequenceFlow_0owfhgj 10 | 11 | 12 | 13 | SequenceFlow_1gif5p2 14 | SequenceFlow_0owfhgj 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /test/bpmn-files/workflow-mixin-v0.bpmn: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SequenceFlow_13itfgw 6 | 7 | 8 | 9 | SequenceFlow_0zqmds4 10 | 11 | 12 | 13 | SequenceFlow_13itfgw 14 | SequenceFlow_0zqmds4 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /test/bpmn-files/workflow-versioning-1.bpmn: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SequenceFlow_1fuw7xm 6 | 7 | 8 | 9 | SequenceFlow_0z13jnh 10 | 11 | 12 | 13 | SequenceFlow_1fuw7xm 14 | SequenceFlow_0z13jnh 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /test/common/models/Address.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Address", 3 | "base": "BaseEntity", 4 | "properties": { 5 | "line1": { "type": "string" }, 6 | "line2": { "type": "string" } 7 | } 8 | } -------------------------------------------------------------------------------- /test/common/models/AddressV1.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "AddressV1", 3 | "base": "BaseEntity", 4 | "properties": { 5 | "line1": { "type": "string", "required": true }, 6 | "line2": { "type": "string" } 7 | } 8 | } -------------------------------------------------------------------------------- /test/common/models/AddressV2.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "AddressV2", 3 | "base": "BaseEntity", 4 | "mixins": { 5 | "VersionMixin": true, 6 | "AuditFieldsMixin": true 7 | }, 8 | "properties": { 9 | "line1": { "type": "string", "required": true }, 10 | "line2": { "type": "string" } 11 | } 12 | } -------------------------------------------------------------------------------- /test/common/models/LuckyDraw.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "LuckyDraw", 3 | "base": "BaseEntity", 4 | "mixins": { 5 | "VersionMixin": true, 6 | "AuditFieldsMixin": true 7 | }, 8 | "properties": { 9 | "owner": { 10 | "type": "string", 11 | "required": true 12 | }, 13 | "sequence": { 14 | "type": "number", 15 | "required": true 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /test/common/models/OrderV0.js: -------------------------------------------------------------------------------- 1 | module.exports = function OrderV0(Model) { 2 | Model.remoteMethod('SpclOrder', { 3 | description: 'Remote method to add special order status', 4 | accessType: 'WRITE', 5 | accepts: [{ 6 | arg: 'data', 7 | type: 'object', 8 | http: { 9 | source: 'body' 10 | }, 11 | description: 'Model data to be posted' 12 | }, { 13 | arg: 'options', 14 | type: 'object', 15 | http: 'optionsFromRequest' 16 | }], 17 | http: { 18 | verb: 'post', 19 | path: '/special-order' 20 | }, 21 | returns: { 22 | arg: 'response', 23 | type: 'object', 24 | root: true 25 | } 26 | }); 27 | 28 | Model.SpclOrder = function specialOrder(data, options, next) { 29 | if (typeof next === 'undefined') { 30 | next = options; 31 | options = {}; 32 | } 33 | data.specialOrder = true; 34 | next(null, data); 35 | }; 36 | 37 | Model.remoteMethod('SpclOrderUpdate', { 38 | description: 'Remote method to add special order status', 39 | accessType: 'WRITE', 40 | accepts: [{ 41 | arg: 'data', 42 | type: 'object', 43 | http: { 44 | source: 'body' 45 | }, 46 | description: 'Model data to be posted' 47 | }, { 48 | arg: 'options', 49 | type: 'object', 50 | http: 'optionsFromRequest' 51 | }], 52 | http: { 53 | verb: 'put', 54 | path: '/special-order' 55 | }, 56 | returns: { 57 | arg: 'response', 58 | type: 'object', 59 | root: true 60 | } 61 | }); 62 | 63 | Model.SpclOrderUpdate = function specialOrderUpdate(data, options, next) { 64 | if (typeof next === 'undefined') { 65 | next = options; 66 | options = {}; 67 | } 68 | data.specialOrder = true; 69 | next(null, data); 70 | }; 71 | 72 | Model.remoteMethod('SpclOrderBYId', { 73 | description: 'Remote method to add special order status', 74 | accessType: 'WRITE', 75 | accepts: [{ 76 | arg: 'id', 77 | type: 'string', 78 | http: { 79 | source: 'path' 80 | }, 81 | description: 'id of the model data' 82 | }, { 83 | arg: 'data', 84 | type: 'object', 85 | http: { 86 | source: 'body' 87 | }, 88 | description: 'Model data to be posted' 89 | }, { 90 | arg: 'options', 91 | type: 'object', 92 | http: 'optionsFromRequest' 93 | }], 94 | http: { 95 | verb: 'put', 96 | path: '/special-order/:id' 97 | }, 98 | returns: { 99 | arg: 'response', 100 | type: 'object', 101 | root: true 102 | } 103 | }); 104 | 105 | Model.SpclOrderBYId = function specialOrderById(id, data, options, next) { 106 | if (typeof next === 'undefined') { 107 | next = options; 108 | options = {}; 109 | } 110 | 111 | data.id = id; 112 | data.specialOrder = true; 113 | Model.create(data, options, next); 114 | }; 115 | }; 116 | -------------------------------------------------------------------------------- /test/common/models/OrderV0.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "OrderV0", 3 | "base": "BaseEntity", 4 | "properties": { 5 | "quantity": { 6 | "type": "number", 7 | "required": true 8 | }, 9 | "buyer": { 10 | "type": "string", 11 | "required": true 12 | }, 13 | "specialOrder": { 14 | "type": "boolean", 15 | "default": false 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /test/common/models/OrderV1.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "OrderV1", 3 | "base": "BaseEntity", 4 | "properties": { 5 | "quantity": { "type": "number", "required": true }, 6 | "buyer": { "type": "string", "required": true } 7 | } 8 | } -------------------------------------------------------------------------------- /test/common/models/OrderV2.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "OrderV2", 3 | "base": "BaseEntity", 4 | "mixins": { 5 | "VersionMixin": true, 6 | "AuditFieldsMixin": true 7 | }, 8 | "properties": { 9 | "quantity": { "type": "number", "required": true }, 10 | "buyer": { "type": "string", "required": true } 11 | } 12 | } -------------------------------------------------------------------------------- /test/common/models/Person.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Person", 3 | "base": "BaseEntity", 4 | "idInjection": true, 5 | "options": { 6 | "validateUpsert": true 7 | }, 8 | "properties": { 9 | "name": { 10 | "type": "string", 11 | "required": true 12 | }, 13 | "dob": { 14 | "type": "date", 15 | "required": true 16 | } 17 | }, 18 | "validations": [], 19 | "relations": { 20 | "addresses": { 21 | "type": "hasMany", 22 | "model": "Address" 23 | } 24 | }, 25 | "acls": [], 26 | "methods": {} 27 | } -------------------------------------------------------------------------------- /test/common/models/Stock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Stock", 3 | "base": "BaseEntity", 4 | "idInjection": true, 5 | "options": { 6 | "validateUpsert": true 7 | }, 8 | "mixins": { 9 | "VersionMixin": true, 10 | "AuditFieldsMixin": true 11 | }, 12 | "properties": { 13 | "name": { 14 | "type": "string", 15 | "required": true 16 | }, 17 | "quantityAvailable": { 18 | "type": "number", 19 | "required": true 20 | }, 21 | "instock": { 22 | "type": "boolean", 23 | "default": true 24 | } 25 | }, 26 | "validations": [], 27 | "acls": [], 28 | "methods": {} 29 | } -------------------------------------------------------------------------------- /test/common/models/StoreV0.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "StoreV0", 3 | "base": "BaseEntity", 4 | "idInjection": true, 5 | "options": { 6 | "validateUpsert": true 7 | }, 8 | "mixins": { 9 | "VersionMixin": true, 10 | "AuditFieldsMixin": true, 11 | "SoftDeleteMixin": true 12 | }, 13 | "properties": { 14 | "owner": { 15 | "type": "string", 16 | "required": true 17 | }, 18 | "sequence": { 19 | "type": "number", 20 | "required": true 21 | } 22 | }, 23 | "validations": [], 24 | "relations": { 25 | }, 26 | "acls": [], 27 | "methods": {} 28 | } -------------------------------------------------------------------------------- /test/common/models/StoreV1.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "StoreV1", 3 | "base": "BaseEntity", 4 | "idInjection": true, 5 | "options": { 6 | "validateUpsert": true 7 | }, 8 | "mixins": { 9 | "VersionMixin": true, 10 | "AuditFieldsMixin": true, 11 | "SoftDeleteMixin": true 12 | }, 13 | "properties": { 14 | "owner": { 15 | "type": "string", 16 | "required": true 17 | }, 18 | "sequence": { 19 | "type": "number", 20 | "required": true 21 | } 22 | }, 23 | "validations": [], 24 | "relations": { 25 | "address": { 26 | "type": "hasOne", 27 | "model": "AddressV1" 28 | }, 29 | "orders": { 30 | "type": "hasMany", 31 | "model": "OrdersV1" 32 | } 33 | }, 34 | "acls": [], 35 | "methods": {} 36 | } -------------------------------------------------------------------------------- /test/common/models/StoreV2.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "StoreV2", 3 | "base": "BaseEntity", 4 | "idInjection": true, 5 | "options": { 6 | "validateUpsert": true 7 | }, 8 | "mixins": { 9 | "VersionMixin": true, 10 | "AuditFieldsMixin": true 11 | }, 12 | "properties": { 13 | "owner": { 14 | "type": "string", 15 | "required": true 16 | }, 17 | "sequence": { 18 | "type": "number", 19 | "required": true 20 | }, 21 | "comments": { 22 | "type": "string" 23 | } 24 | }, 25 | "validations": [], 26 | "relations": { 27 | "address": { 28 | "type": "hasOne", 29 | "model": "AddressV2" 30 | }, 31 | "orders": { 32 | "type": "hasMany", 33 | "model": "OrderV2" 34 | } 35 | }, 36 | "acls": [], 37 | "methods": {} 38 | } -------------------------------------------------------------------------------- /test/component-config.json: -------------------------------------------------------------------------------- 1 | { 2 | } 3 | -------------------------------------------------------------------------------- /test/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "restApiRoot": "/api", 3 | "host": "0.0.0.0", 4 | "port": 3000, 5 | "remoting": { 6 | "context": false, 7 | "rest": { 8 | "normalizeHttpPath": false, 9 | "xml": false 10 | }, 11 | "json": { 12 | "strict": false, 13 | "limit": "100kb" 14 | }, 15 | "urlencoded": { 16 | "extended": true, 17 | "limit": "100kb" 18 | }, 19 | "cors": false, 20 | "handleErrors": false 21 | }, 22 | "client":{ 23 | "templatePath": ["test/client/templates"] 24 | }, 25 | "workflow":{ 26 | "addonModule": "test/utils/addon-functions", 27 | "recovery": { 28 | "retryInterval": 2000 29 | }, 30 | "disableMakerCheckerBeforeSave": false, 31 | "disableMakerCheckerParallelValidations": false 32 | }, 33 | "masterJobExecutor": { 34 | "initDelay": 1000, 35 | "checkMasterInterval":2000, 36 | "heartbeatInterval":1000, 37 | "masterJobTolerance": 3000 38 | }, 39 | "subPath":"appsubpath", 40 | "legacyExplorer": false 41 | } 42 | -------------------------------------------------------------------------------- /test/datasources.json: -------------------------------------------------------------------------------- 1 | { 2 | "memdb": { 3 | "name": "memdb", 4 | "connector": "memory" 5 | }, 6 | "transient": { 7 | "name": "transient", 8 | "connector": "transient" 9 | }, 10 | "db": { 11 | "host": "localhost", 12 | "port": 27017, 13 | "url": "mongodb://localhost:27017/oe-workflow-test", 14 | "database": "oe-workflow-test", 15 | "password": "admin", 16 | "name": "db", 17 | "connector": "oe-connector-mongodb", 18 | "user": "admin", 19 | "connectionTimeout": 500000, 20 | "connectTimeoutMS": 500000, 21 | "socketTimeoutMS": 500000 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /test/datasources.mongo.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * ©2016-2017 EdgeVerve Systems Limited (a fully owned Infosys subsidiary), 4 | * Bangalore, India. All Rights Reserved. 5 | * 6 | */ 7 | var mongoHost = process.env.MONGO_HOST || 'localhost'; 8 | var mongoPort = process.env.MONGO_PORT ? parseInt(process.env.MONGO_PORT) : 27017; 9 | var dbName = process.env.DB_NAME || "dbname"; 10 | module.exports = { 11 | 'memdb': { 12 | 'name': 'memdb', 13 | 'connector': 'memory' 14 | }, 15 | 'transient': { 16 | 'name': 'transient', 17 | 'connector': 'transient' 18 | }, 19 | 'db': { 20 | 'host': mongoHost, 21 | 'port': mongoPort, 22 | 'url': 'mongodb://' + mongoHost + ':' + mongoPort + '/' + dbName, 23 | 'database': dbName, 24 | 'name': 'db', 25 | 'connector': 'oe-connector-mongodb', 26 | 'connectionTimeout': 500000 27 | } 28 | }; 29 | 30 | -------------------------------------------------------------------------------- /test/datasources.oracle.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * ©2016-2017 EdgeVerve Systems Limited (a fully owned Infosys subsidiary), 4 | * Bangalore, India. All Rights Reserved. 5 | * 6 | */ 7 | 8 | var oracleSID = process.env.ORACLE_SID; 9 | var oracleHost = process.env.ORACLE_HOST || 'localhost'; 10 | var oraclePort = process.env.ORACLE_PORT ? parseInt(process.env.ORACLE_PORT) : 1521; 11 | var oracleUserName = process.env.ORACLE_USERNAME; 12 | var oracleUserPassword = process.env.ORACLE_PASSWORD; 13 | 14 | module.exports = { 15 | 'nullsrc': { 16 | 'name': 'nullsrc', 17 | 'connector': 'memory' 18 | }, 19 | 'transient': { 20 | 'name': 'transient', 21 | 'connector': 'transient' 22 | }, 23 | 'db': { 24 | 'name': 'db', 25 | 'connector': 'oe-connector-oracle', 26 | 'database': oracleSID, 27 | 'host': oracleHost, 28 | 'port': oraclePort, 29 | 'password': oracleUserPassword, 30 | 'user': oracleUserName 31 | } 32 | }; 33 | 34 | 35 | -------------------------------------------------------------------------------- /test/datasources.postgres.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * ©2016-2017 EdgeVerve Systems Limited (a fully owned Infosys subsidiary), 4 | * Bangalore, India. All Rights Reserved. 5 | * 6 | */ 7 | var postgresHost = process.env.POSTGRES_HOST || 'localhost'; 8 | var postgresPort = process.env.POSTGRES_PORT ? parseInt(process.env.POSTGRES_PORT) : 5432; 9 | var postgresPassword = process.env.POSTGRES_PASSWORD; 10 | var dbName = process.env.DB_NAME || "dbname"; 11 | module.exports = { 12 | 'memdb': { 13 | 'name': 'memdb', 14 | 'connector': 'memory' 15 | }, 16 | 'transient': { 17 | 'name': 'transient', 18 | 'connector': 'transient' 19 | }, 20 | 'db': { 21 | 'host': postgresHost, 22 | 'port': postgresPort, 23 | 'url': 'postgres://postgres:postgres@' + postgresHost + ':' + postgresPort + '/' + dbName, 24 | 'database': dbName, 25 | 'password': postgresPassword, 26 | 'name': 'db', 27 | 'connector': 'oe-connector-postgresql', 28 | 'user': 'postgres', 29 | 'max': 50, 30 | 'connectionTimeout': 50000 31 | } 32 | }; 33 | -------------------------------------------------------------------------------- /test/failTest.sh: -------------------------------------------------------------------------------- 1 | x=0 2 | while [ "$x" -eq "0" ] 3 | do 4 | npm run clean && mocha test/scripts/multi-instance-parallel-tests.js >run.log 2>&1 5 | x=$? 6 | echo "Return Status $x"; 7 | sleep 1 8 | done; 9 | -------------------------------------------------------------------------------- /test/middleware.json: -------------------------------------------------------------------------------- 1 | { 2 | "initial:before": { 3 | "loopback#favicon": {} 4 | }, 5 | "initial": { 6 | "compression": {}, 7 | "cors": { 8 | "params": { 9 | "origin": true, 10 | "credentials": true, 11 | "maxAge": 86400 12 | } 13 | } 14 | }, 15 | "session": { 16 | }, 17 | "auth": { 18 | }, 19 | "parse": { 20 | }, 21 | "routes:before": { 22 | "loopback#rest": { 23 | "paths": ["${restApiRoot}"] 24 | } 25 | }, 26 | "files": { 27 | "serve-static": { 28 | "params": "$!../client" 29 | } 30 | }, 31 | "final": { 32 | "loopback#urlNotFound": {} 33 | }, 34 | "final:after": { 35 | "strong-error-handler": {} 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /test/model-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "_meta": { 3 | "sources": [ 4 | "loopback/common/models", 5 | "loopback/server/models", 6 | "./common/models", 7 | "./test/common/models", 8 | "./models" 9 | ], 10 | "mixins": [] 11 | }, 12 | "User": { 13 | "dataSource": "db" 14 | }, 15 | "AccessToken": { 16 | "dataSource": "db", 17 | "public": false 18 | }, 19 | "ACL": { 20 | "dataSource": "db", 21 | "public": false 22 | }, 23 | "RoleMapping": { 24 | "dataSource": "db", 25 | "public": false 26 | }, 27 | "Role": { 28 | "dataSource": "db", 29 | "public": false 30 | }, 31 | "Address": { 32 | "dataSource": "db", 33 | "public": false 34 | }, 35 | "Person": { 36 | "dataSource": "db", 37 | "public": false 38 | }, 39 | "LuckyDraw": { 40 | "dataSource": "db", 41 | "public": false 42 | }, 43 | "StoreV0": { 44 | "dataSource": "db", 45 | "public": false 46 | }, 47 | "StoreV1": { 48 | "dataSource": "db", 49 | "public": false 50 | }, 51 | "AddressV1": { 52 | "dataSource": "db", 53 | "public": false 54 | }, 55 | "OrderV1": { 56 | "dataSource": "db", 57 | "public": false 58 | }, 59 | "StoreV2": { 60 | "dataSource": "db", 61 | "public": false 62 | }, 63 | "AddressV2": { 64 | "dataSource": "db", 65 | "public": false 66 | }, 67 | "OrderV2": { 68 | "dataSource": "db", 69 | "public": false 70 | }, 71 | "OrderV0": { 72 | "dataSource": "db", 73 | "public": true 74 | }, 75 | "Stock": { 76 | "dataSource": "db", 77 | "public": false 78 | } 79 | } -------------------------------------------------------------------------------- /test/scripts/correlationid-tests.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * ©2016-2017 EdgeVerve Systems Limited (a fully owned Infosys subsidiary), 4 | * Bangalore, India. All Rights Reserved. 5 | * 6 | */ 7 | 8 | let bootstrap = require('../bootstrap.js'); 9 | let chai = bootstrap.chai; 10 | let expect = chai.expect; 11 | let models = bootstrap.app.models; 12 | let workflowInstance; 13 | let processInstance; 14 | let userTask; 15 | 16 | describe('correlationid property should exists on models', function testfunction(done) { 17 | it('correlationid should exist on workflowInstance model', function testfunction(done) { 18 | var workflowInstance = models.WorkflowInstance; 19 | expect(workflowInstance.definition.properties.correlationId).to.exist; 20 | done(); 21 | }); 22 | 23 | it('correlationid should exist on task model', function testfunction(done) { 24 | var task = models.Task; 25 | expect(task.definition.properties.correlationId).to.exist; 26 | done(); 27 | }); 28 | 29 | it('correlationid should exist on processInstance model', function testfunction(done) { 30 | var processInstance = models.ProcessInstance; 31 | expect(processInstance.definition.properties.correlationId).to.exist; 32 | done(); 33 | }); 34 | 35 | it('correlationid should exist on changeworkflowRequest model', function testfunction(done) { 36 | var changeWorkflowRequest = models.ChangeWorkflowRequest; 37 | expect(changeWorkflowRequest.definition.properties.correlationId).to.exist; 38 | done(); 39 | }); 40 | }); 41 | 42 | describe('correlationid should be populated on instances', function testFunction() { 43 | var workflowName = 'correlationid'; 44 | let workflowPayload = { 45 | correlationId: 'abcdedf' 46 | }; 47 | 48 | before(function testFunction(done) { 49 | bootstrap.loadBpmnFile(workflowName, function testFunction(err) { 50 | expect(err).to.not.exist; 51 | bootstrap.triggerWaitForUserTask(workflowName, workflowPayload, 'UserTask', function testFunction(err, wfInst, procInstance, task) { 52 | workflowInstance = wfInst; 53 | processInstance = procInstance; 54 | userTask = task; 55 | done(err); 56 | }); 57 | }); 58 | }); 59 | 60 | after(function testFunction(done) { 61 | bootstrap.cleanUp(workflowName, done); 62 | processInstance = null; 63 | userTask = null; 64 | bootstrap.removeCompleteListener(workflowName); 65 | bootstrap.removeUserTaskListener(workflowName, 'UserTask'); 66 | }); 67 | 68 | it('correlationid should be populated on workflowInstance', function testFunction(done) { 69 | expect(workflowInstance).to.exist; 70 | expect(workflowInstance.correlationId).to.exist; 71 | done(); 72 | }); 73 | 74 | it('correlationid should be populated on processInstance', function testFunction(done) { 75 | expect(processInstance).to.exist; 76 | expect(processInstance.correlationId).to.exist; 77 | expect(processInstance.correlationId).to.equal(workflowInstance.correlationId); 78 | done(); 79 | }); 80 | 81 | it('correlationid should be populated on usertask', function testFunction(done) { 82 | expect(userTask).to.exist; 83 | expect(userTask.correlationId).to.exist; 84 | expect(userTask.correlationId).to.equal(workflowInstance.correlationId); 85 | done(); 86 | }); 87 | }); 88 | -------------------------------------------------------------------------------- /test/scripts/dynamic-timer-intermediate-parallel-tests.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * ©2016-2017 EdgeVerve Systems Limited (a fully owned Infosys subsidiary), 4 | * Bangalore, India. All Rights Reserved. 5 | * 6 | */ 7 | 8 | let bootstrap = require('../bootstrap.js'); 9 | let chai = bootstrap.chai; 10 | let expect = chai.expect; 11 | 12 | let stateVerifier = require('../utils/state-verifier'); 13 | 14 | describe('Parallel IntermediateTimer Tests for Dynamic and Default Timers', function CB() { 15 | let workflowName = 'dynamic-timer-intermediate-parallel'; 16 | 17 | before('define workflow', function testFunction(done) { 18 | bootstrap.loadBpmnFile(workflowName, function testFunction(err) { 19 | done(err); 20 | }); 21 | }); 22 | 23 | after('cleanup data', function testFunction(done) { 24 | bootstrap.removeCompleteListener(workflowName); 25 | bootstrap.cleanUp(workflowName, done); 26 | }); 27 | 28 | describe('DynamicTimer - Parallel IntermediateTimer Tests', function CB() { 29 | let workflowPayload = { 30 | processVariables: { 31 | tduration1: 200, 32 | tduration2: 800 33 | } 34 | }; 35 | 36 | it('DynamicTimer - Parallel IntermediateTimer complete and resumes the workflow', function testFunction(done) { 37 | bootstrap.triggerAndComplete(workflowName, workflowPayload, function testFunction(err, wfInstance, procInstance) { 38 | expect(err).to.not.exist; 39 | stateVerifier.isComplete(procInstance); 40 | // var expectedFlow = ['Start', 'PG1', 'ITimer1', 'ITimer2', 'PG2', 'PG2', 'End']; 41 | stateVerifier.verifyTimerCompletion(procInstance, 'ITimer1', 200, 200); 42 | stateVerifier.verifyTimerCompletion(procInstance, 'ITimer2', 800, 200); 43 | // stateVerifier.verifyCompletionFlow(procInstance, expectedFlow); 44 | done(); 45 | }); 46 | }); 47 | }); 48 | 49 | describe('DefaultTimer - Parallel IntermediateTimer Tests', function CB() { 50 | let workflowPayload = { 51 | processVariables: { 52 | tduration1: 'abc', 53 | tduration2: 'xyz' 54 | } 55 | }; 56 | 57 | it('DefaultTimer - Parallel IntermediateTimer complete and resumes the workflow', function testFunction(done) { 58 | bootstrap.triggerAndComplete(workflowName, workflowPayload, function testFunction(err, wfInstance, procInstance) { 59 | expect(err).to.not.exist; 60 | stateVerifier.isComplete(procInstance); 61 | stateVerifier.verifyTimerCompletion(procInstance, 'ITimer1', 200, 400); 62 | stateVerifier.verifyTimerCompletion(procInstance, 'ITimer2', 200, 400); 63 | done(); 64 | }); 65 | }); 66 | }); 67 | }); 68 | -------------------------------------------------------------------------------- /test/scripts/dynamic-timer-intermediate-tests.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * ©2016-2017 EdgeVerve Systems Limited (a fully owned Infosys subsidiary), 4 | * Bangalore, India. All Rights Reserved. 5 | * 6 | */ 7 | 8 | let bootstrap = require('../bootstrap.js'); 9 | let chai = bootstrap.chai; 10 | let expect = chai.expect; 11 | let Status = bootstrap.Status; 12 | 13 | let stateVerifier = require('../utils/state-verifier'); 14 | 15 | describe('IntermediateTimer Tests for Dynamic and Default Timers', function CB() { 16 | let workflowName = 'dynamic-timer-intermediate'; 17 | 18 | before('define workflow', function testFunction(done) { 19 | bootstrap.loadBpmnFile(workflowName, function testFunction(err) { 20 | done(err); 21 | }); 22 | }); 23 | after('cleanup data', function testFunction(done) { 24 | bootstrap.removeCompleteListener(workflowName); 25 | bootstrap.cleanUp(workflowName, done); 26 | }); 27 | 28 | describe('DynamicTimer - IntermediateTimer Tests', function CB() { 29 | let workflowPayload = { 30 | processVariables: { 31 | tduration: 600 32 | } 33 | }; 34 | 35 | it('DynamicTimer - IntermediateTimer node completes and resumes the workflow', function testFunction(done) { 36 | bootstrap.triggerAndComplete(workflowName, workflowPayload, function testFunction(err, wfInstance, procInstance) { 37 | expect(err).to.not.exist; 38 | stateVerifier.isComplete(procInstance); 39 | stateVerifier.verifyTokens(procInstance, [{ 40 | name: 'Start', 41 | status: Status.COMPLETE 42 | }, { 43 | name: 'TaskA', 44 | status: Status.COMPLETE 45 | }, { 46 | name: 'ITimer', 47 | status: Status.COMPLETE 48 | }, { 49 | name: 'TaskB', 50 | status: Status.COMPLETE 51 | }, { 52 | name: 'End', 53 | status: Status.COMPLETE 54 | }]); 55 | stateVerifier.verifyTimerCompletion(procInstance, 'ITimer', 600, 200); 56 | done(); 57 | }); 58 | }); 59 | }); 60 | 61 | describe('DefaultTimer - IntermediateTimer Tests', function CB() { 62 | let workflowPayload = { 63 | processVariables: { 64 | tduration: 'abc' 65 | } 66 | }; 67 | 68 | it('DefaultTimer - IntermediateTimer node completes and resumes the workflow', function testFunction(done) { 69 | bootstrap.triggerAndComplete(workflowName, workflowPayload, function testFunction(err, wfInstance, procInstance) { 70 | expect(err).to.not.exist; 71 | stateVerifier.isComplete(procInstance); 72 | stateVerifier.verifyTokens(procInstance, [{ 73 | name: 'Start', 74 | status: Status.COMPLETE 75 | }, { 76 | name: 'TaskA', 77 | status: Status.COMPLETE 78 | }, { 79 | name: 'ITimer', 80 | status: Status.COMPLETE 81 | }, { 82 | name: 'TaskB', 83 | status: Status.COMPLETE 84 | }, { 85 | name: 'End', 86 | status: Status.COMPLETE 87 | }]); 88 | stateVerifier.verifyTimerCompletion(procInstance, 'ITimer', 200, 400); 89 | done(); 90 | }); 91 | }); 92 | }); 93 | }); 94 | -------------------------------------------------------------------------------- /test/scripts/eventbased-gateway-tests.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * ©2016-2017 EdgeVerve Systems Limited (a fully owned Infosys subsidiary), 4 | * Bangalore, India. All Rights Reserved. 5 | * 6 | */ 7 | 8 | let bootstrap = require('../bootstrap.js'); 9 | let chai = bootstrap.chai; 10 | let expect = chai.expect; 11 | let stateVerifier = require('../utils/state-verifier'); 12 | let Status = bootstrap.Status; 13 | 14 | describe('EventBased Gateway Tests', function CB() { 15 | let workflowName = 'eventbased-gateway'; 16 | let processInstance; 17 | before('define workflow', function testFunction(done) { 18 | /* Observed with Oracle sometimes that Upload and Execution takes around 50 seconds */ 19 | this.timeout(60000); 20 | bootstrap.loadAndTrigger(workflowName, {}, function testFunction(err, wfDefn, wfInst) { 21 | expect(err).to.not.exist; 22 | expect(wfInst).to.exist; 23 | }); 24 | bootstrap.onComplete(workflowName, function testFunction(err, procInst) { 25 | expect(err).to.not.exist; 26 | expect(procInst).to.exist; 27 | processInstance = procInst; 28 | done(); 29 | }); 30 | }); 31 | after('cleanup data', function testFunction(done) { 32 | bootstrap.removeCompleteListener(workflowName); 33 | bootstrap.cleanUp(workflowName, done); 34 | }); 35 | 36 | it('Verify the flow', function testFunction(done) { 37 | stateVerifier.isComplete(processInstance); 38 | stateVerifier.verifyTokens(processInstance, ['Start', 'PGFork', 'Timer1', 'MThrow', 'EBG1', 'MCatch', { 39 | name: 'Timer2', 40 | status: Status.INTERRUPTED 41 | }, { 42 | name: 'Signal1', 43 | status: Status.INTERRUPTED 44 | }, 'EventSync', 'PGSync', 'PGSync', 'End']); 45 | done(); 46 | }); 47 | }); 48 | -------------------------------------------------------------------------------- /test/scripts/exclusive-gateway-tests.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * ©2016-2017 EdgeVerve Systems Limited (a fully owned Infosys subsidiary), 4 | * Bangalore, India. All Rights Reserved. 5 | * 6 | */ 7 | 8 | let bootstrap = require('../bootstrap.js'); 9 | let chai = bootstrap.chai; 10 | let expect = chai.expect; 11 | let stateVerifier = require('../utils/state-verifier'); 12 | 13 | describe('Exclusive Gateway Tests', function callback() { 14 | var workflowName = 'exclusive-gateway'; 15 | before('define workflow', function testFunction(done) { 16 | bootstrap.loadBpmnFile(workflowName, function testFunction(err) { 17 | done(err); 18 | }); 19 | }); 20 | 21 | after('cleanup data', function testFunction(done) { 22 | bootstrap.cleanUp(workflowName, done); 23 | }); 24 | 25 | afterEach(function testFunction(done) { 26 | bootstrap.removeCompleteListener(workflowName); 27 | done(); 28 | }); 29 | 30 | it('Takes path A for condition 1', function testFunction(done) { 31 | bootstrap.triggerAndComplete(workflowName, { 32 | processVariables: { 33 | pvField: 1 34 | } 35 | }, function testFunction(err, wfInstance, processInstance) { 36 | expect(err).to.not.exist; 37 | stateVerifier.isComplete(processInstance); 38 | stateVerifier.verifyFlow(processInstance, ['Start', 'InitTask', 'EGIn', 'TaskA', 'EGOut', 'End']); 39 | expect(processInstance._processVariables).to.have.property('a').that.equals(10); 40 | expect(processInstance._processVariables).to.not.have.property('b'); 41 | expect(processInstance._processVariables).to.not.have.property('c'); 42 | done(); 43 | }); 44 | }); 45 | 46 | it('Takes path B for condition 2', function testFunction(done) { 47 | bootstrap.triggerAndComplete(workflowName, { 48 | processVariables: { 49 | pvField: 2 50 | } 51 | }, function testFunction(err, wfInstance, processInstance) { 52 | expect(err).to.not.exist; 53 | stateVerifier.isComplete(processInstance); 54 | stateVerifier.verifyFlow(processInstance, ['Start', 'InitTask', 'EGIn', 'TaskB', 'EGOut', 'End']); 55 | expect(processInstance._processVariables).to.have.property('b').that.equals(20); 56 | expect(processInstance._processVariables).to.not.have.property('a'); 57 | expect(processInstance._processVariables).to.not.have.property('c'); 58 | done(); 59 | }); 60 | }); 61 | 62 | it('Assumes default path when no conditions are met', function testFunction(done) { 63 | bootstrap.triggerAndComplete(workflowName, { 64 | processVariables: { 65 | pvField: 56 66 | } 67 | }, function testFunction(err, wfInstance, processInstance) { 68 | expect(err).to.not.exist; 69 | stateVerifier.isComplete(processInstance); 70 | stateVerifier.verifyFlow(processInstance, ['Start', 'InitTask', 'EGIn', 'TaskC', 'EGOut', 'End']); 71 | expect(processInstance._processVariables).to.have.property('c').that.equals(30); 72 | expect(processInstance._processVariables).to.not.have.property('a'); 73 | expect(processInstance._processVariables).to.not.have.property('b'); 74 | done(); 75 | }); 76 | }); 77 | }); 78 | -------------------------------------------------------------------------------- /test/scripts/inclusive-gateway-complex-tests.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * ©2016-2017 EdgeVerve Systems Limited (a fully owned Infosys subsidiary), 4 | * Bangalore, India. All Rights Reserved. 5 | * 6 | */ 7 | 8 | let bootstrap = require('../bootstrap.js'); 9 | let chai = bootstrap.chai; 10 | let expect = chai.expect; 11 | let stateVerifier = require('../utils/state-verifier'); 12 | 13 | describe('Inclusive Gateway Complex Tests', function callback() { 14 | var workflowName = 'inclusive-gateway-complex'; 15 | before('define workflow', function testFunction(done) { 16 | /* Observed with Oracle sometimes that Upload and Execution takes around 50 seconds */ 17 | this.timeout(60000); 18 | bootstrap.loadBpmnFile(workflowName, function testFunction(err) { 19 | done(err); 20 | }); 21 | }); 22 | 23 | after('cleanup data', function testFunction(done) { 24 | bootstrap.cleanUp(workflowName, done); 25 | }); 26 | 27 | afterEach(function testFunction(done) { 28 | bootstrap.removeCompleteListener(workflowName); 29 | done(); 30 | }); 31 | 32 | it('Multiple Inclusive Gateways Tests', function testFunction(done) { 33 | bootstrap.triggerAndComplete(workflowName, { 34 | processVariables: { 35 | pvField: 3, 36 | pvField1: 4, 37 | pvField2: 3, 38 | pvField3: 1 39 | } 40 | }, function testFunction(err, wfInstance, processInstance) { 41 | expect(err).to.not.exist; 42 | stateVerifier.isComplete(processInstance); 43 | expect(processInstance._processTokens).to.exist; 44 | let IG1Out = Object.values(processInstance._processTokens).find(item => item.name === 'IG1Out').endTime; 45 | let IG2Out = Object.values(processInstance._processTokens).find(item => item.name === 'IG2Out').endTime; 46 | let IG3Out = Object.values(processInstance._processTokens).find(item => item.name === 'IG3Out').endTime; 47 | let IG4Out = Object.values(processInstance._processTokens).find(item => item.name === 'IG4Out').endTime; 48 | let IG1EndTime = new Date(IG1Out); 49 | let IG2EndTime = new Date(IG2Out); 50 | let IG3EndTime = new Date(IG3Out); 51 | let IG4EndTime = new Date(IG4Out); 52 | expect(IG3EndTime).to.beforeTime(IG2EndTime); 53 | expect(IG2EndTime).to.beforeTime(IG1EndTime); 54 | expect(IG4EndTime).to.beforeTime(IG1EndTime); 55 | expect(processInstance._processVariables).to.not.have.property('Script2'); 56 | expect(processInstance._processVariables).to.have.property('Script4').that.equals(true); 57 | expect(processInstance._processVariables).to.not.have.property('Script6'); 58 | expect(processInstance._processVariables).to.have.property('Script9').that.equals(true); 59 | done(); 60 | }); 61 | }); 62 | }); 63 | -------------------------------------------------------------------------------- /test/scripts/message-end-tests.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * ©2016-2017 EdgeVerve Systems Limited (a fully owned Infosys subsidiary), 4 | * Bangalore, India. All Rights Reserved. 5 | * 6 | */ 7 | 8 | let bootstrap = require('../bootstrap.js'); 9 | let chai = bootstrap.chai; 10 | let expect = chai.expect; 11 | let stateVerifier = require('../utils/state-verifier'); 12 | let Status = bootstrap.Status; 13 | 14 | describe('Message End Event Tests', function CB() { 15 | let workflowName = 'message-end'; 16 | let processInstance; 17 | let userTask; 18 | before('define workflow', function testFunction(done) { 19 | bootstrap.loadBpmnFile(workflowName, function testFunction(err) { 20 | expect(err).to.not.exist; 21 | bootstrap.triggerWaitForUserTask(workflowName, {}, 'UserTask', function testFunction(err, wfInst, procInst, task) { 22 | expect(err).to.not.exist; 23 | processInstance = procInst; 24 | userTask = task; 25 | done(); 26 | }); 27 | }); 28 | }); 29 | after('cleanup data', function testFunction(done) { 30 | bootstrap.removeCompleteListener(workflowName); 31 | bootstrap.cleanUp(workflowName, done); 32 | }); 33 | 34 | it('Receiver waits for the message', function testFunction(done) { 35 | expect(processInstance).to.exist; 36 | stateVerifier.isRunning(processInstance); 37 | stateVerifier.verifyTokens(processInstance, ['Start', 'ScriptA', 'ParallelGWay', 'Wait200', { 38 | name: 'UserTask', 39 | status: Status.PENDING 40 | }, { 41 | name: 'MessageCatch', 42 | status: Status.PENDING 43 | }]); 44 | done(); 45 | }); 46 | 47 | it('MessageEnd sends the message and receiver resumes execution', function testFunction(done) { 48 | expect(userTask).to.exist; 49 | stateVerifier.isRunning(processInstance); 50 | userTask.complete({}, bootstrap.defaultContext, function testFunction(err, task) { 51 | expect(err).to.not.exist; 52 | expect(task.status).to.equal('complete'); 53 | userTask = task; 54 | }); 55 | bootstrap.onComplete(workflowName, function testFunction(err, instance) { 56 | expect(err).to.not.exist; 57 | stateVerifier.isComplete(instance); 58 | stateVerifier.verifyTokens(instance, ['Start', 'ScriptA', 'ParallelGWay', 'Wait200', 'UserTask', 'MessageCatch', 'MessageEnd', 'ScriptB', 'End']); 59 | processInstance = instance; 60 | done(); 61 | }); 62 | }); 63 | }); 64 | -------------------------------------------------------------------------------- /test/scripts/message-start-send-tests.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * ©2016-2017 EdgeVerve Systems Limited (a fully owned Infosys subsidiary), 4 | * Bangalore, India. All Rights Reserved. 5 | * 6 | */ 7 | 8 | let bootstrap = require('../bootstrap.js'); 9 | let chai = bootstrap.chai; 10 | let expect = chai.expect; 11 | let stateVerifier = require('../utils/state-verifier'); 12 | let async = require('async'); 13 | 14 | describe('Message Start Event Tests Using Send Task as Source of Message Flow', function CB() { 15 | let workflowName = 'message-start-send'; 16 | before('define workflow', function testFunction(done) { 17 | bootstrap.loadAndTrigger(workflowName, {}, function testFunction(err, wfDefn, wfInstance) { 18 | expect(err).to.not.exist; 19 | expect(wfInstance).to.exist; 20 | done(); 21 | }); 22 | }); 23 | after('cleanup data', function testFunction(done) { 24 | bootstrap.removeCompleteListener(workflowName + '$SendMessage'); 25 | bootstrap.removeCompleteListener(workflowName + '$ReceiveMessage'); 26 | bootstrap.cleanUp(workflowName, done); 27 | }); 28 | 29 | it('TIMING FAILURE: Receiver resumes and completes when message is received from sender', function testFunction(done) { 30 | async.parallel([function sendCompletion(callback) { 31 | bootstrap.onComplete(workflowName + '$SendMessage', function testFunction(err, instance) { 32 | expect(err).to.not.exist; 33 | expect(instance).to.exist; 34 | stateVerifier.isComplete(instance); 35 | stateVerifier.verifyTokens(instance, ['Start P1', 'Wait300', 'SendTask', 'End P1']); 36 | callback(null, instance); 37 | }); 38 | }, function receiveCompletion(callback) { 39 | bootstrap.onComplete(workflowName + '$ReceiveMessage', function testFunction(err, instance) { 40 | expect(err).to.not.exist; 41 | expect(instance).to.exist; 42 | stateVerifier.isComplete(instance); 43 | stateVerifier.verifyTokens(instance, ['MessageStart', 'T2', 'End P2']); 44 | callback(null, instance); 45 | }); 46 | }], function testFunction(err, results) { 47 | expect(err).to.not.exist; 48 | expect(results).to.exist; 49 | let allTokens = results.map(v => Object.values(v._processTokens)) 50 | .reduce((a, v) => { 51 | a = a || []; 52 | return a.concat(v); 53 | }).sort((a, b) => { 54 | return ((new Date(a.startTime)) - (new Date(b.startTime))); 55 | }); 56 | 57 | let sendToken = allTokens.find(v => v.name === 'SendTask'); 58 | let receiveToken = allTokens.find(v => v.name === 'MessageStart'); 59 | 60 | expect(new Date(sendToken.endTime)).to.be.beforeTime(new Date(receiveToken.endTime)); 61 | 62 | done(); 63 | }); 64 | }); 65 | }); 66 | -------------------------------------------------------------------------------- /test/scripts/parallel-gateway-tests.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * ©2016-2017 EdgeVerve Systems Limited (a fully owned Infosys subsidiary), 4 | * Bangalore, India. All Rights Reserved. 5 | * 6 | */ 7 | 8 | let bootstrap = require('../bootstrap.js'); 9 | let chai = bootstrap.chai; 10 | let expect = chai.expect; 11 | 12 | let stateVerifier = require('../utils/state-verifier'); 13 | 14 | describe('Parallel Gateway Tests', function CB() { 15 | let workflowName = 'parallel-gateway'; 16 | let processInstance; 17 | let initialMessage = {status: 'started'}; 18 | before('define workflow', function testFunction(done) { 19 | bootstrap.onComplete(workflowName, function testFunction(err, procInstance) { 20 | expect(err).to.not.exist; 21 | processInstance = procInstance; 22 | done(); 23 | }); 24 | bootstrap.loadAndTrigger(workflowName, {message: initialMessage}, function testFunction(err, wfDefn, wfInstance) { 25 | expect(err).to.not.exist; 26 | }); 27 | }); 28 | after('cleanup data', function testFunction(done) { 29 | bootstrap.removeCompleteListener(workflowName); 30 | bootstrap.cleanUp(workflowName, done); 31 | }); 32 | 33 | it('Parallel Gateway spawns parallel tokens and ends together before resuming next node', function testFunction(done) { 34 | expect(processInstance).to.exist; 35 | stateVerifier.isComplete(processInstance); 36 | /* In a parallel-gateway, there are multiple converting tokens created. 37 | * Each starts when corresponding branch completes. They all end together 38 | * and Next node starts after that. 39 | * So we can not say all PGOuts would start after all scripts complete */ 40 | stateVerifier.verifyFlowNew(processInstance, ['Start', 'PGIn', ['Script01', 'Script02', 'Script03', 'Script04', 'Script05'], 'Checks', 'End']); 41 | stateVerifier.verifyPV(processInstance, { 42 | script01: 'done', 43 | script02: 'done', 44 | script03: 'done', 45 | script04: 'done', 46 | script05: 'done' 47 | }); 48 | done(); 49 | }); 50 | 51 | it('Parallel Gateway passes message verbatim to all spawned children', function testFunction(done) { 52 | expect(processInstance).to.exist; 53 | for (let i = 1; i <= 5; i++) { 54 | let scriptToken = stateVerifier.fetchTokenByName(processInstance, 'Script0' + i); 55 | expect(scriptToken).to.exist; 56 | expect(scriptToken.message).to.deep.equal(initialMessage); 57 | } 58 | done(); 59 | }); 60 | 61 | it('Converging parallem-gateway merges message passed from each branch and passes onto the next node', function testFunction(done) { 62 | expect(processInstance).to.exist; 63 | let checksToken = stateVerifier.fetchTokenByName(processInstance, 'Checks'); 64 | expect(checksToken.message).to.exist; 65 | expect(checksToken.message).to.have.keys(['Script01', 'Script03', 'Script05']); 66 | expect(checksToken.message.Script01).to.deep.equal({status: 100}); 67 | expect(checksToken.message.Script03).to.deep.equal({status: 300}); 68 | expect(checksToken.message.Script05).to.deep.equal({status: 500}); 69 | done(); 70 | }); 71 | }); 72 | -------------------------------------------------------------------------------- /test/scripts/signal-inter-process-tests.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * ©2016-2017 EdgeVerve Systems Limited (a fully owned Infosys subsidiary), 4 | * Bangalore, India. All Rights Reserved. 5 | * 6 | */ 7 | 8 | let bootstrap = require('../bootstrap.js'); 9 | let chai = bootstrap.chai; 10 | let expect = chai.expect; 11 | let Status = bootstrap.Status; 12 | 13 | let stateVerifier = require('../utils/state-verifier'); 14 | 15 | describe('Intra-Process Signal Tests', function testFunction() { 16 | let workflowNameCatch = 'signal-inter-process-catch'; 17 | let workflowNameThrow = 'signal-inter-process-throw'; 18 | let workflowInstanceCatch; 19 | let userTask; 20 | let payloadCatch = { 21 | workflowDefinitionName: workflowNameCatch, 22 | processVariables: { 23 | catchcode: 101 24 | } 25 | }; 26 | let payloadThrow = { 27 | workflowDefinitionName: workflowNameThrow, 28 | processVariables: { 29 | throwcode: 101 30 | } 31 | }; 32 | 33 | before('define workflows', function testFunction(done) { 34 | bootstrap.loadAndTrigger(workflowNameCatch, payloadCatch, function testFunction(err1, wfDefn, wfInstance) { 35 | expect(err1).to.not.exist; 36 | workflowInstanceCatch = wfInstance; 37 | bootstrap.loadAndTrigger(workflowNameThrow, payloadThrow, function testFunction(err2, wfDefn, wfInstance) { 38 | expect(err2).to.not.exist; 39 | }); 40 | }); 41 | bootstrap.onUserTask(workflowNameThrow, 'UserTask', function testFunction(err, task) { 42 | expect(err).to.not.exist; 43 | expect(task).to.exist; 44 | userTask = task; 45 | done(); 46 | }); 47 | }); 48 | after('cleanup data', function testFunction(done) { 49 | workflowInstanceCatch = null; 50 | bootstrap.cleanUp(workflowNameCatch, function testFunction(err1) { 51 | bootstrap.cleanUp(workflowNameThrow, function testFunction(err2) { 52 | done(err1 || err2); 53 | }); 54 | }); 55 | bootstrap.removeUserTaskListener(workflowNameThrow, 'UserTask'); 56 | bootstrap.removeCompleteListener(workflowNameCatch); 57 | bootstrap.removeCompleteListener(workflowNameThrow); 58 | }); 59 | 60 | it('CatchSignal Waits for the signal to be sent', function CB(done) { 61 | expect(workflowInstanceCatch).to.exist; 62 | workflowInstanceCatch.processes({}, bootstrap.defaultContext, function testFunction(err, processes) { 63 | expect(err).to.not.exist; 64 | expect(processes).to.exist.and.be.an('array').of.length(1); 65 | stateVerifier.verifyTokens(processes[0], ['Start', { 66 | name: 'Catch Signal', 67 | status: Status.PENDING 68 | }]); 69 | done(); 70 | }); 71 | }); 72 | 73 | it('Throw sends the signal across to another process, catch receives and completes the flow', function CB(done) { 74 | expect(userTask).to.exist; 75 | userTask.complete({}, bootstrap.defaultContext, function testFunction(err, task) { 76 | expect(err).to.not.exist; 77 | expect(task).to.exist; 78 | expect(task.status).to.equal(Status.COMPLETE); 79 | }); 80 | bootstrap.onComplete(workflowNameCatch, function testFunction(err, instance) { 81 | expect(err).to.not.exist; 82 | expect(instance).to.exist; 83 | stateVerifier.isComplete(instance); 84 | stateVerifier.verifyTokens(instance, ['Start', 'Catch Signal', 'End']); 85 | done(); 86 | }); 87 | }); 88 | }); 89 | -------------------------------------------------------------------------------- /test/scripts/signal-intra-process-boundary-tests.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * ©2016-2017 EdgeVerve Systems Limited (a fully owned Infosys subsidiary), 4 | * Bangalore, India. All Rights Reserved. 5 | * 6 | */ 7 | 8 | let bootstrap = require('../bootstrap.js'); 9 | let chai = bootstrap.chai; 10 | let expect = chai.expect; 11 | let Status = bootstrap.Status; 12 | 13 | let stateVerifier = require('../utils/state-verifier'); 14 | 15 | describe('Intra-Process Boundary Signal Tests', function CB() { 16 | let workflowName = 'signal-intra-process-boundary'; 17 | before('define workflow', function testFunction(done) { 18 | bootstrap.loadBpmnFile(workflowName, function testFunction(err) { 19 | done(err); 20 | }); 21 | }); 22 | after('cleanup data', function testFunction(done) { 23 | bootstrap.cleanUp(workflowName, done); 24 | }); 25 | 26 | let workflowInstance; 27 | let workflowPayload = {}; 28 | 29 | beforeEach('trigger the workflow', function testFunction(done) { 30 | bootstrap.triggerWorkflow(workflowName, workflowPayload, function testFunction(err, wfInstance) { 31 | workflowInstance = wfInstance; 32 | done(err); 33 | }); 34 | }); 35 | 36 | afterEach('reset', function testFunction(done) { 37 | workflowInstance = null; 38 | bootstrap.removeTokenStatusListener(workflowName); 39 | bootstrap.removeUserTaskListener(workflowName, 'UserTask'); 40 | done(); 41 | }); 42 | 43 | it('Boundary catch interrupts the token', function CB(done) { 44 | expect(workflowInstance).to.exist; 45 | bootstrap.onComplete(workflowName, function testFunction(err, instance) { 46 | expect(err).to.not.exist; 47 | expect(instance).to.exist; 48 | stateVerifier.isComplete(instance); 49 | stateVerifier.verifyTokens(instance, ['Start', 'Fork', 'Wait400', 'ThrowSignal', 'End', {name: 'UserTask', status: Status.INTERRUPTED}, 'CatchSignal', 'AutoEnd']); 50 | expect(stateVerifier.fetchTokenByName(instance, 'UserEnd')).to.not.exist; 51 | done(); 52 | }); 53 | }); 54 | 55 | 56 | it('When boundary host has completed, catch-signal is interrupted', function CB(done) { 57 | expect(workflowInstance).to.exist; 58 | 59 | /* (Potential Testing issue) By the time we reach here testing, Wait400 may have elapsed and raised interrupt to user-task */ 60 | bootstrap.onUserTask(workflowName, 'UserTask', function testFunction(err, task) { 61 | expect(err).to.not.exist; 62 | task.complete({}, bootstrap.defaultContext, function testFunction(err, task) { 63 | expect(err).to.not.exist; 64 | expect(task.status).to.equal(Status.COMPLETE); 65 | }); 66 | }); 67 | 68 | bootstrap.onComplete(workflowName, function testFunction(err, instance) { 69 | expect(err).to.not.exist; 70 | expect(instance).to.exist; 71 | stateVerifier.isComplete(instance); 72 | stateVerifier.verifyTokens(instance, ['Start', 'Fork', 'Wait400', 'ThrowSignal', 'End', 'UserTask', {name: 'CatchSignal', status: Status.INTERRUPTED}, 'UserEnd']); 73 | done(); 74 | }); 75 | }); 76 | }); 77 | -------------------------------------------------------------------------------- /test/scripts/signal-intra-process-start-tests.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * ©2016-2017 EdgeVerve Systems Limited (a fully owned Infosys subsidiary), 4 | * Bangalore, India. All Rights Reserved. 5 | * 6 | */ 7 | 8 | let bootstrap = require('../bootstrap.js'); 9 | let chai = bootstrap.chai; 10 | let expect = chai.expect; 11 | let Status = bootstrap.Status; 12 | 13 | let stateVerifier = require('../utils/state-verifier'); 14 | 15 | describe('Intra-Process Signal Tests', function CB() { 16 | let workflowName = 'signal-intra-process-start'; 17 | before('define workflow', function testFunction(done) { 18 | bootstrap.loadBpmnFile(workflowName, function testFunction(err) { 19 | done(err); 20 | }); 21 | }); 22 | after('cleanup data', function testFunction(done) { 23 | bootstrap.cleanUp(workflowName, done); 24 | }); 25 | 26 | let workflowInstance; 27 | let workflowPayload = {}; 28 | 29 | beforeEach('trigger and complete workflow', function testFunction(done) { 30 | bootstrap.triggerWorkflow(workflowName, workflowPayload, function testFunction(err, wfInstance) { 31 | workflowInstance = wfInstance; 32 | done(err); 33 | }); 34 | }); 35 | 36 | afterEach('reset', function testFunction() { 37 | workflowInstance = null; 38 | bootstrap.removeTokenStatusListener(workflowName); 39 | bootstrap.removeCompleteListener(workflowName); 40 | }); 41 | 42 | it('Start-Catch Waits and Resumes when Throw Sends the signal', function CB(done) { 43 | expect(workflowInstance).to.exist; 44 | let execOrder = 0; 45 | /* (Potential Testing issue) When Wait400 is Pending, CatchSignal may not have been created. */ 46 | bootstrap.onTokenStatus(workflowName, 'Wait400', 'pending', function testFunction(err, instance, token) { 47 | expect(++execOrder).to.equal(1); 48 | expect(err).to.not.exist; 49 | expect(instance).to.exist; 50 | stateVerifier.isRunning(instance); 51 | stateVerifier.verifyTokens(instance, ['Start', 'Fork', { 52 | name: 'Wait400', 53 | status: Status.PENDING 54 | }, { 55 | name: 'Sub', 56 | status: Status.PENDING 57 | }]); 58 | }); 59 | 60 | bootstrap.onTokenStatus(workflowName, 'Wait400', 'complete', function testFunction(err, instance, token) { 61 | expect(++execOrder).to.equal(2); 62 | expect(err).to.not.exist; 63 | expect(instance).to.exist; 64 | stateVerifier.isRunning(instance); 65 | instance.subProcesses({}, bootstrap.defaultContext, function testFunction(err, subProcesses) { 66 | expect(err).to.not.exist; 67 | expect(subProcesses).to.exist.and.be.an('array').of.length(1); 68 | stateVerifier.verifyTokens(subProcesses[0], [{ 69 | name: 'CatchSignal', 70 | status: Status.PENDING 71 | }]); 72 | }); 73 | }); 74 | 75 | bootstrap.onComplete(workflowName, function testFunction(err, instance) { 76 | expect(++execOrder).to.equal(3); 77 | expect(err).to.not.exist; 78 | expect(instance).to.exist; 79 | stateVerifier.isComplete(instance); 80 | stateVerifier.verifyTokens(instance, ['Start', 'Fork', 'Wait400', 'Sub', 'ThrowSignal', 'End'], true); 81 | done(); 82 | }); 83 | }); 84 | }); 85 | -------------------------------------------------------------------------------- /test/scripts/signal-intra-process-tests.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * ©2016-2017 EdgeVerve Systems Limited (a fully owned Infosys subsidiary), 4 | * Bangalore, India. All Rights Reserved. 5 | * 6 | */ 7 | 8 | let bootstrap = require('../bootstrap.js'); 9 | let chai = bootstrap.chai; 10 | let expect = chai.expect; 11 | let Status = bootstrap.Status; 12 | 13 | let stateVerifier = require('../utils/state-verifier'); 14 | 15 | describe('Intra-Process Signal Tests', function CB() { 16 | let workflowName = 'signal-intra-process'; 17 | before('define workflow', function testFunction(done) { 18 | bootstrap.loadBpmnFile(workflowName, function testFunction(err) { 19 | done(err); 20 | }); 21 | }); 22 | after('cleanup data', function testFunction(done) { 23 | bootstrap.cleanUp(workflowName, done); 24 | }); 25 | 26 | let workflowInstance; 27 | let workflowPayload = {}; 28 | 29 | beforeEach('trigger and complete workflow', function testFunction(done) { 30 | bootstrap.triggerWorkflow(workflowName, workflowPayload, function testFunction(err, wfInstance) { 31 | workflowInstance = wfInstance; 32 | done(err); 33 | }); 34 | }); 35 | 36 | this.afterEach('reset', function testFunction() { 37 | workflowInstance = null; 38 | bootstrap.removeTokenStatusListener(workflowName); 39 | bootstrap.removeCompleteListener(workflowName); 40 | }); 41 | it('CatchSignal Waits and Resumes when Throw Sends the signal', function CB(done) { 42 | expect(workflowInstance).to.exist; 43 | 44 | /* (Potential Testing issue) When Timer200 is Pending, CatchSignal may not have been created. */ 45 | bootstrap.onTokenStatus(workflowName, 'Timer200', 'pending', function testFunction(err, instance, token) { 46 | expect(err).to.not.exist; 47 | expect(instance).to.exist; 48 | stateVerifier.isRunning(instance); 49 | stateVerifier.verifyTokens(instance, ['Start', 'Fork', { 50 | name: 'Timer200', 51 | status: Status.PENDING 52 | }, { 53 | name: 'CatchSignal', 54 | status: Status.PENDING 55 | }], true); 56 | done(); 57 | }); 58 | 59 | bootstrap.onComplete(workflowName, function testFunction(err, instance) { 60 | expect(err).to.not.exist; 61 | expect(instance).to.exist; 62 | stateVerifier.isComplete(instance); 63 | stateVerifier.verifyTokens(instance, ['Start', 'Fork', 'Timer200', 'CatchSignal', 'ThrowSignal', 'End'], true); 64 | done(); 65 | }); 66 | }); 67 | }); 68 | -------------------------------------------------------------------------------- /test/scripts/terminate-end-event-tests.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * ©2016-2017 EdgeVerve Systems Limited (a fully owned Infosys subsidiary), 4 | * Bangalore, India. All Rights Reserved. 5 | * 6 | */ 7 | let async = require('async'); 8 | let bootstrap = require('../bootstrap.js'); 9 | let chai = bootstrap.chai; 10 | let expect = chai.expect; 11 | let Status = bootstrap.Status; 12 | let stateVerifier = require('../utils/state-verifier'); 13 | 14 | describe('Terminate Event Tests', function CB() { 15 | let workflowName = 'terminate-end-event'; 16 | before('define workflow', function testFunction(done) { 17 | bootstrap.loadBpmnFile(workflowName, function testFunction(err) { 18 | done(err); 19 | }); 20 | }); 21 | after('cleanup data', function testFunction(done) { 22 | bootstrap.cleanUp(workflowName, done); 23 | }); 24 | 25 | let workflowInstance; 26 | 27 | beforeEach(function testFunction(done) { 28 | bootstrap.triggerWorkflow(workflowName, {}, function testFunction(err, wfInstance) { 29 | expect(err).to.not.exist; 30 | expect(wfInstance).to.exist; 31 | workflowInstance = wfInstance; 32 | done(); 33 | }); 34 | }); 35 | afterEach(function testFunction(done) { 36 | workflowInstance = null; 37 | bootstrap.removeUserTaskListener(workflowName, 'UserTask2'); 38 | bootstrap.removeCompleteListener(workflowName); 39 | bootstrap.removeInterruptedListener(workflowName + '$Sub'); 40 | done(); 41 | }); 42 | it('TerminateEnd Event terminates entire workflow', function testFunction(done) { 43 | expect(workflowInstance).to.exist; 44 | bootstrap.onUserTask(workflowName, 'UserTask2', function testFunction(err, task, processInstance) { 45 | expect(err).to.not.exist; 46 | task.complete({}, bootstrap.defaultContext, function testFunction(err, task) { 47 | expect(err).to.not.exist; 48 | expect(task).to.exist.and.have.property('status').that.equals(Status.COMPLETE); 49 | }); 50 | }); 51 | async.parallel([ 52 | function mainTerminate(callback) { 53 | bootstrap.onComplete(workflowName, function testFunction(err, processInstance) { 54 | expect(err).to.not.exist; 55 | stateVerifier.isComplete(processInstance); 56 | stateVerifier.verifyTokens(processInstance, ['Start', 'PGway', 'UserTask2', 'ForceEnd', { 57 | name: 'UserTask1', 58 | status: Status.INTERRUPTED 59 | }, { 60 | name: 'Sub', 61 | status: Status.INTERRUPTED 62 | }]); 63 | callback(err, true); 64 | }); 65 | }, 66 | function subTerminate(callback) { 67 | bootstrap.onInterrupted(workflowName + '$Sub', function testFunction(err, processInstance) { 68 | expect(err).to.not.exist; 69 | stateVerifier.isInterrupted(processInstance); 70 | stateVerifier.verifyTokens(processInstance, ['SubStart', { 71 | name: 'UserTaskSub', 72 | status: Status.INTERRUPTED 73 | }]); 74 | callback(err, true); 75 | }); 76 | } 77 | ], function testFunction(err, results) { 78 | expect(err).to.not.exist; 79 | done(err); 80 | }); 81 | }); 82 | }); 83 | -------------------------------------------------------------------------------- /test/scripts/timer-boundary-tests.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * ©2016-2017 EdgeVerve Systems Limited (a fully owned Infosys subsidiary), 4 | * Bangalore, India. All Rights Reserved. 5 | * 6 | */ 7 | 8 | let bootstrap = require('../bootstrap.js'); 9 | let chai = bootstrap.chai; 10 | let expect = chai.expect; 11 | let Status = bootstrap.Status; 12 | 13 | let stateVerifier = require('../utils/state-verifier'); 14 | 15 | describe('Boundary Timer Tests', function CB() { 16 | let workflowName = 'timer-boundary'; 17 | before('define workflow', function testFunction(done) { 18 | bootstrap.loadBpmnFile(workflowName, function testFunction(err) { 19 | expect(err).to.not.exist; 20 | done(err); 21 | }); 22 | }); 23 | after('cleanup data', function testFunction(done) { 24 | bootstrap.cleanUp(workflowName, done); 25 | }); 26 | 27 | afterEach('remove listeners', function testFunction(done) { 28 | bootstrap.removeCompleteListener(workflowName); 29 | bootstrap.removeUserTaskListener(workflowName, 'UserTask'); 30 | done(); 31 | }); 32 | 33 | it('Boundary Timer node interrupts the task and resumes the workflow', function testFunction(done) { 34 | bootstrap.triggerAndComplete(workflowName, {}, function testFunction(err, wfInstance, procInstance) { 35 | expect(err).to.not.exist; 36 | stateVerifier.isComplete(procInstance); 37 | stateVerifier.verifyTokens(procInstance, [{ 38 | name: 'Start', 39 | status: Status.COMPLETE 40 | }, { 41 | name: 'UserTask', 42 | status: Status.INTERRUPTED 43 | }, { 44 | name: 'BoundaryTimer', 45 | status: Status.COMPLETE 46 | }, { 47 | name: 'TaskB', 48 | status: Status.COMPLETE 49 | }, { 50 | name: 'End2', 51 | status: Status.COMPLETE 52 | }]); 53 | 54 | stateVerifier.verifyTimerCompletion(procInstance, 'BoundaryTimer', 600); 55 | done(); 56 | }); 57 | }); 58 | 59 | it('Boundary Timer is interrupted when boundary-task is completed', function testFunction(done) { 60 | bootstrap.onComplete(workflowName, function testFunction(err, procInstance) { 61 | expect(err).to.not.exist; 62 | stateVerifier.isComplete(procInstance); 63 | stateVerifier.verifyTokens(procInstance, [{ 64 | name: 'Start', 65 | status: Status.COMPLETE 66 | }, { 67 | name: 'UserTask', 68 | status: Status.COMPLETE 69 | }, { 70 | name: 'BoundaryTimer', 71 | status: Status.INTERRUPTED 72 | }, { 73 | name: 'End1', 74 | status: Status.COMPLETE 75 | }]); 76 | done(); 77 | }); 78 | bootstrap.triggerWaitForUserTask(workflowName, {}, 'UserTask', function testFunction(err, wfInstance, procInstance, userTask) { 79 | expect(err).to.not.exist; 80 | expect(wfInstance).to.exist; 81 | expect(userTask).to.exist; 82 | userTask.complete({}, bootstrap.defaultContext, function testFunction(err, userTask) { 83 | expect(err).to.not.exist; 84 | expect(userTask.status).to.equal(Status.COMPLETE); 85 | }); 86 | }); 87 | }); 88 | }); 89 | -------------------------------------------------------------------------------- /test/scripts/timer-intermediate-parallel-tests.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * ©2016-2017 EdgeVerve Systems Limited (a fully owned Infosys subsidiary), 4 | * Bangalore, India. All Rights Reserved. 5 | * 6 | */ 7 | 8 | let bootstrap = require('../bootstrap.js'); 9 | let chai = bootstrap.chai; 10 | let expect = chai.expect; 11 | 12 | let stateVerifier = require('../utils/state-verifier'); 13 | 14 | describe('Parallel Intermediate Timer Tests', function CB() { 15 | let workflowName = 'timer-intermediate-parallel'; 16 | before('define workflow', function testFunction(done) { 17 | bootstrap.loadBpmnFile(workflowName, function testFunction(err) { 18 | done(err); 19 | }); 20 | }); 21 | after('cleanup data', function testFunction(done) { 22 | bootstrap.removeCompleteListener(workflowName); 23 | bootstrap.cleanUp(workflowName, done); 24 | }); 25 | 26 | it('Parallel Intermediate Timers complete and resumes the workflow', function testFunction(done) { 27 | bootstrap.triggerAndComplete(workflowName, {}, function testFunction(err, wfInstance, procInstance) { 28 | expect(err).to.not.exist; 29 | stateVerifier.isComplete(procInstance); 30 | // var expectedFlow = ['Start', 'PG1', 'ITimer1', 'ITimer2', 'PG2', 'PG2', 'End']; 31 | stateVerifier.verifyTimerCompletion(procInstance, 'ITimer1', 200); 32 | stateVerifier.verifyTimerCompletion(procInstance, 'ITimer2', 800); 33 | // stateVerifier.verifyCompletionFlow(procInstance, expectedFlow); 34 | done(); 35 | }); 36 | }); 37 | }); 38 | -------------------------------------------------------------------------------- /test/scripts/timer-intermediate-tests.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * ©2016-2017 EdgeVerve Systems Limited (a fully owned Infosys subsidiary), 4 | * Bangalore, India. All Rights Reserved. 5 | * 6 | */ 7 | 8 | let bootstrap = require('../bootstrap.js'); 9 | let chai = bootstrap.chai; 10 | let expect = chai.expect; 11 | let Status = bootstrap.Status; 12 | 13 | let stateVerifier = require('../utils/state-verifier'); 14 | 15 | describe('Intermediate Timer Tests', function CB() { 16 | let workflowName = 'timer-intermediate'; 17 | before('define workflow', function testFunction(done) { 18 | bootstrap.loadBpmnFile(workflowName, function testFunction(err) { 19 | done(err); 20 | }); 21 | }); 22 | after('cleanup data', function testFunction(done) { 23 | bootstrap.removeCompleteListener(workflowName); 24 | bootstrap.cleanUp(workflowName, done); 25 | }); 26 | 27 | it('Intermediate Timer node completes and resumes the workflow', function testFunction(done) { 28 | bootstrap.triggerAndComplete(workflowName, {}, function testFunction(err, wfInstance, procInstance) { 29 | expect(err).to.not.exist; 30 | stateVerifier.isComplete(procInstance); 31 | stateVerifier.verifyTokens(procInstance, [{ 32 | name: 'Start', 33 | status: Status.COMPLETE 34 | }, { 35 | name: 'TaskA', 36 | status: Status.COMPLETE 37 | }, { 38 | name: 'ITimer', 39 | status: Status.COMPLETE 40 | }, { 41 | name: 'TaskB', 42 | status: Status.COMPLETE 43 | }, { 44 | name: 'End', 45 | status: Status.COMPLETE 46 | }]); 47 | stateVerifier.verifyTimerCompletion(procInstance, 'ITimer', 600, 200); 48 | done(); 49 | }); 50 | }); 51 | }); 52 | -------------------------------------------------------------------------------- /test/scripts/timer-start-tests.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * ©2016-2017 EdgeVerve Systems Limited (a fully owned Infosys subsidiary), 4 | * Bangalore, India. All Rights Reserved. 5 | * 6 | */ 7 | 8 | let bootstrap = require('../bootstrap.js'); 9 | let chai = bootstrap.chai; 10 | let expect = chai.expect; 11 | 12 | let stateVerifier = require('../utils/state-verifier'); 13 | 14 | describe('Start Timer Tests', function CB() { 15 | let workflowName = 'timer-start'; 16 | before('define workflow', function testFunction(done) { 17 | bootstrap.loadBpmnFile(workflowName, function testFunction(err) { 18 | done(err); 19 | }); 20 | }); 21 | after('cleanup data', function testFunction(done) { 22 | bootstrap.cleanUp(workflowName, done); 23 | }); 24 | 25 | 26 | describe('Simple Tests', function CB() { 27 | let workflowInstance; 28 | let processInstance; 29 | let workflowPayload = {}; 30 | 31 | before('trigger and complete workflow', function testFunction(done) { 32 | bootstrap.triggerAndComplete(workflowName, workflowPayload, function testFunction(err, wfInstance, procInstance) { 33 | workflowInstance = wfInstance; 34 | processInstance = procInstance; 35 | done(err); 36 | }); 37 | }); 38 | 39 | it('Start Timer node executes and completes', function CB(done) { 40 | expect(workflowInstance).to.exist; 41 | workflowInstance.processes({}, bootstrap.defaultContext, function CB(err, instances) { 42 | expect(err).to.not.exist; 43 | expect(instances).to.exist.and.be.an('array').of.length(1); 44 | let instance = instances[0]; 45 | stateVerifier.isComplete(instance); 46 | stateVerifier.verifyTokens(instance, ['StartTimer', 'ScriptTask', 'End']); 47 | done(); 48 | }); 49 | }); 50 | 51 | it('StartTimer waits for specified time', function testFunction(done) { 52 | expect(processInstance).to.exist; 53 | stateVerifier.verifyTimerCompletion(processInstance, 'StartTimer', 600); 54 | done(); 55 | }); 56 | }); 57 | }); 58 | -------------------------------------------------------------------------------- /test/scripts/update-via-workflow-tests.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * ©2016-2017 EdgeVerve Systems Limited (a fully owned Infosys subsidiary), 4 | * Bangalore, India. All Rights Reserved. 5 | * 6 | */ 7 | 8 | let bootstrap = require('../bootstrap.js'); 9 | let chai = bootstrap.chai; 10 | let expect = chai.expect; 11 | let models = bootstrap.app.models; 12 | 13 | let stateVerifier = require('../utils/state-verifier'); 14 | 15 | describe('Update via Workflow tests', function CB() { 16 | let workflowName = 'update-via-workflow'; 17 | let workflowMapping; 18 | before('define workflow', function testFunction(done) { 19 | bootstrap.loadBpmnFile(workflowName, function testFunction(err, wfDef) { 20 | expect(err).to.not.exist; 21 | models.WorkflowManager.attachWorkflow({ 22 | operation: 'create', 23 | modelName: 'StoreV1', 24 | version: 'v1', 25 | wfDependent: true, 26 | workflowBody: { 27 | workflowDefinitionName: workflowName 28 | } 29 | }, bootstrap.defaultContext, function testFunction(err, mappings) { 30 | expect(err).to.not.exist; 31 | expect(mappings).to.exist; 32 | expect(mappings.mappings).to.exist.and.be.an('array').of.length(1); 33 | workflowMapping = mappings.mappings[0]; 34 | done(); 35 | }); 36 | }); 37 | }); 38 | after('cleanup data', function testFunction(done) { 39 | models.WorkflowManager.detachWorkflowWithVersion(workflowMapping.id, workflowMapping._version, bootstrap.defaultContext, function testFunction(err) { 40 | expect(err).to.not.exist; 41 | models.StoreV1.destroyAll({}, function cb() { 42 | bootstrap.cleanUp(workflowName, done); 43 | }); 44 | }); 45 | }); 46 | 47 | 48 | it('finalize transaction connector updates the record', function testFunction(done) { 49 | let createdRecord; 50 | models.StoreV1.create({owner: 'Shaw', sequence: 4000}, bootstrap.defaultContext, function cb(err, tkt) { 51 | expect(err).to.not.exist; 52 | expect(tkt).to.exist; 53 | expect(tkt.owner).to.equal('Shaw'); 54 | expect(tkt.sequence).to.equal(4000); 55 | createdRecord = tkt; 56 | }); 57 | bootstrap.onComplete(workflowName, function cb(err, instance) { 58 | expect(err).to.not.exist; 59 | stateVerifier.isComplete(instance); 60 | models.StoreV1.findById(createdRecord.id, bootstrap.defaultContext, function cb(err, record) { 61 | expect(err).to.not.exist; 62 | expect(record).to.exist; 63 | expect(record.owner).to.equal('Sia'); 64 | expect(record.sequence).to.equal(9000); 65 | done(); 66 | }); 67 | }); 68 | }); 69 | }); 70 | -------------------------------------------------------------------------------- /test/scripts/user-task-ui-tests.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * ©2016-2017 EdgeVerve Systems Limited (a fully owned Infosys subsidiary), 4 | * Bangalore, India. All Rights Reserved. 5 | * 6 | */ 7 | 8 | let bootstrap = require('../bootstrap.js'); 9 | let chai = bootstrap.chai; 10 | let expect = chai.expect; 11 | let async = require('async'); 12 | 13 | describe('User Task UI Tests', function callback() { 14 | let workflowName = 'user-task-ui'; 15 | let userTask1; let userTask2; let userTask3; 16 | let processInstance; 17 | before('define workflow', function testFunction(done) { 18 | async.parallel([ 19 | function testFunction(cb) { 20 | bootstrap.onUserTask(workflowName, 'UserTask1', function testFunction(err, task, instance) { 21 | expect(err).to.not.exist; 22 | userTask1 = task; 23 | processInstance = instance; 24 | cb(); 25 | }); 26 | }, 27 | function testFunction(cb) { 28 | bootstrap.onUserTask(workflowName, 'UserTask2', function testFunction(err, task) { 29 | expect(err).to.not.exist; 30 | userTask2 = task; 31 | cb(); 32 | }); 33 | }, 34 | function testFunction(cb) { 35 | bootstrap.onUserTask(workflowName, 'UserTask3', function testFunction(err, task) { 36 | expect(err).to.not.exist; 37 | userTask3 = task; 38 | cb(); 39 | }); 40 | } 41 | ], function testFunction(err, results) { 42 | done(err); 43 | }); 44 | 45 | bootstrap.loadAndTrigger(workflowName, { processVariables: { var1: 'val1', age: 28, name: 'Alice', myForm: 'elem:/element/dynamic-form.html' } }, function testFunction(err) { 46 | expect(err).to.not.exist; 47 | }); 48 | }); 49 | 50 | after('cleanup data', function testFunction(done) { 51 | bootstrap.cleanUp(workflowName, done); 52 | }); 53 | 54 | it('Task with FormKey', function testFunction(done) { 55 | expect(userTask1).to.exist; 56 | expect(userTask1.formType).to.equal('FormKey'); 57 | expect(userTask1.formKey).to.equal('import:/element/task-form.html'); 58 | expect(userTask1.formVariables).to.deep.equal(processInstance._processVariables); 59 | done(); 60 | }); 61 | 62 | it('Task with FormData', function testFunction(done) { 63 | expect(userTask2).to.exist; 64 | expect(userTask2.formType).to.equal('FormData'); 65 | expect(userTask2.formKey).to.not.exist; 66 | expect(userTask2.formVariables).to.exist; 67 | expect(userTask2.formVariables.name).to.exist.and.have.property('label'); 68 | expect(userTask2.formVariables.name.defaultValue).to.equal('Alice'); 69 | expect(userTask2.formVariables.age).to.exist.and.have.property('label'); 70 | expect(userTask2.formVariables.age.defaultValue).to.equal('28'); 71 | expect(userTask2.formVariables.occupation).to.exist.and.have.property('label'); 72 | expect(userTask2.formVariables.occupation.defaultValue).to.equal('UnEmployed'); 73 | done(); 74 | }); 75 | 76 | it('Task with dynamic FormKey', function testFunction(done) { 77 | expect(userTask3).to.exist; 78 | expect(userTask3.formType).to.equal('FormKey'); 79 | expect(userTask3.formKey).to.equal('elem:/element/dynamic-form.html'); 80 | expect(userTask3.formVariables).to.deep.equal(processInstance._processVariables); 81 | done(); 82 | }); 83 | }); 84 | -------------------------------------------------------------------------------- /test/server.js: -------------------------------------------------------------------------------- 1 | var oecloud = require('oe-cloud'); 2 | 3 | oecloud.observe('loaded', function loadedCb(ctx, next) { 4 | return next(); 5 | }); 6 | 7 | oecloud.boot(__dirname, function bootCb(err) { 8 | if (err) { 9 | throw err; 10 | } 11 | oecloud.start(); 12 | oecloud.emit('test-start'); 13 | }); 14 | -------------------------------------------------------------------------------- /test/utils/addon-functions.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | testCreation: function preCreateFunction(options, taskDef, taskData, cb) { 3 | if (this._processVariables.testingHook && this._processVariables.sla) { 4 | let date = new Date(Date.now()); 5 | taskData.dueDate = new Date(Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate() + this._processVariables.sla)); 6 | } 7 | return cb(null, taskData); 8 | }, 9 | testCompletion: function preCompleteFunction(options, payload, taskInstance, taskDef, cb) { 10 | let err = null; 11 | if (this._processVariables.testingHook && !payload.__comments__) { 12 | err = new Error('Comments must be provided'); 13 | } 14 | return cb(err); 15 | }, 16 | testPostCompletion: function postCompleteFunction(options, taskInstance, cb) { 17 | if (this._processVariables.testingHook && this._processVariables.modifyOptions) { 18 | options.modifyOptions = this._processVariables.modifyOptions; 19 | } 20 | return cb(options, taskInstance); 21 | }, 22 | 23 | defaultTaskCreationHook: function defaultTaskCreationHook(options, taskDef, taskData, cb) { 24 | if (this._processVariables.testingHook) { 25 | let date = new Date(Date.now()); 26 | taskData.dueDate = new Date(Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate() + 2)); 27 | taskData.excludedRoles = ['a', 'b', 'c']; 28 | } 29 | return cb(null, taskData); 30 | }, 31 | defaultTaskCompletionHook: function defaultTaskCompletionHook(options, payload, taskInstance, taskDef, cb) { 32 | let err = null; 33 | if (this._processVariables.testingHook && !payload.__comments__) { 34 | err = new Error('Default: Comments must be provided'); 35 | } 36 | return cb(err); 37 | }, 38 | defaultTaskPostCompletionHook: function defaultTaskPostCompletionHook(options, taskInstance, cb) { 39 | if (this._processVariables.testingHook) { 40 | options.modifyOptions = 'defaultModifiedOptions'; 41 | } 42 | return cb(options, taskInstance); 43 | }, 44 | }; 45 | -------------------------------------------------------------------------------- /utils/addon-functions.js: -------------------------------------------------------------------------------- 1 | module.exports = {}; 2 | --------------------------------------------------------------------------------