forked from e2ebridge/bpmn
-
Notifications
You must be signed in to change notification settings - Fork 0
/
package.json
110 lines (110 loc) · 30.7 KB
/
package.json
1
2
3
4
5
6
7
8
9
10
11
12
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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
{
"_args": [
[
{
"raw": "bpmn",
"scope": null,
"escapedName": "bpmn",
"name": "bpmn",
"rawSpec": "",
"spec": "latest",
"type": "tag"
},
"C:\\Users\\kleandrovaa\\WebstormProjects\\NodeBpmn"
]
],
"_from": "bpmn@latest",
"_id": "bpmn@0.2.2",
"_inCache": true,
"_location": "/bpmn",
"_nodeVersion": "2.4.0",
"_npmUser": {
"name": "cschmitt",
"email": "cschmitt@e2ebridge.com"
},
"_npmVersion": "2.13.0",
"_phantomChildren": {},
"_requested": {
"raw": "bpmn",
"scope": null,
"escapedName": "bpmn",
"name": "bpmn",
"rawSpec": "",
"spec": "latest",
"type": "tag"
},
"_requiredBy": [
"#USER",
"/"
],
"_resolved": "https://registry.npmjs.org/bpmn/-/bpmn-0.2.2.tgz",
"_shasum": "6000ca09777e1e2d59f9625ec5e3fafb4043568e",
"_shrinkwrap": null,
"_spec": "bpmn",
"_where": "C:\\Users\\kleandrovaa\\WebstormProjects\\NodeBpmn",
"author": {
"name": "support@e2ebridge.com"
},
"bugs": {
"url": "https://github.com/e2ebridge/bpmn/issues"
},
"dependencies": {
"async": "0.9.0",
"bunyan": ">= 0.21.3",
"e2e-transaction-logger": "~0.1.0",
"jaguardb": ">= 0.1.3",
"mongodb": ">= 2.2.6",
"node-fs": ">= 0.1.5",
"node-uuid": ">= 1.4.0",
"restify": ">= 2.5.1",
"sax": ">= 0.5.2",
"underscore.string": "^2.3.3",
"winston": ">= 0.7.1"
},
"description": "BPMN 2.0 execution engine",
"devDependencies": {
"commander": ">= 2.0.0",
"istanbul": ">= 0.1.44",
"nodeunit": ">= 0.7.4"
},
"directories": {},
"dist": {
"shasum": "6000ca09777e1e2d59f9625ec5e3fafb4043568e",
"tarball": "https://registry.npmjs.org/bpmn/-/bpmn-0.2.2.tgz"
},
"gitHead": "2a339a4ea2edcddeeea7598f8758b77bfc81afe1",
"homepage": "https://github.com/e2ebridge/bpmn#readme",
"keywords": [
"bpmn",
"workflow",
"process",
"automation",
"integration",
"system integration"
],
"license": "MIT",
"main": "./lib/public.js",
"maintainers": [
{
"name": "mrassinger",
"email": "mrassinger@e2ebridge.com"
},
{
"name": "cschmitt",
"email": "cschmitt@e2ebridge.com"
}
],
"name": "bpmn",
"optionalDependencies": {
"e2e-transaction-logger": "~0.1.0",
"mongodb": ">= 1.3.10"
},
"readme": "bpmn\n================\nThis module executes BPMN 2.0 processes.\n\nBPMN execution is deemed to be a good way to describe process oriented business logic. This is especially true if we have to describe the orchestration and collaboration of service- and UI-interactions. Many of these interactions are asynchronous and event driven making Node.js an ideal candidate for implementing a BPMN engine.\n\nTo draw the BPMN file to be executed each BPMN 2.0 compliant tool can be used.\n\nWe are working on a simple browser based BPMN 2.0 editor also utilizing Node.js as backend.\nYou may learn more about our efforts and other Node.js packages on [http://e2ebridge.com](http://e2ebridge.com).\n\nThe e2e-transaction-logger package can be used optionally. The generated transaction log files enable the [E2E Dashboards](http://docu.e2ebridge.com/E2E+Dashboards) to provide graphical views of your processes.\n\nInstallation\n------------\nThe easiest way to install it is via NPM:\n\n npm install bpmn\n\nIf you don't have a compiler on your platform the restify dtrace dependency won't be installed. Just ignore it.\n\nAssumptions\n-----------\n\n- This package assumes each BPMN 2.0 file is accompanied by an equal named JS file. For example, the directory containing `myprocess.bpmn` must contain also `myprocess.js` holding the BPMN event handlers.\n- Each BPMN element name is unique per process. This simplifies live considerably because we can use names instead of IDs simplifying the world for users and developers alike. If this is not the case, an error is thrown while creating the process.\n\nRemarks\n-------\n\nProcess can be managed or unmanaged. Unmanaged processes are not stored in any way, the developer is responsible of storing the returned process objects to be able to use them later. Process manager allow to create multiple processes and store them during their execution. The managers have functions to retrieve existing processes by id, filter by property or state. Managers will also persist the managed processes if persistency options are set.\n\nBasic Example\n=============\n\nThese following samples assume that you installed bpmn via npm.\n\nAssume myProcess.bpmn describes the following process\n\n![](https://raw.githubusercontent.com/e2ebridge/bpmn/master/examples/processes/task.png)\n\nthen this process can be created by\n\n \n\tvar bpmn = require(\"bpmn\");\n\t// We assume there is a myProcess.js besides myProcess.bpmn that contains the handlers\n\tbpmn.createUnmanagedProcess(\"path/to/myProcess.bpmn\", function(err, myProcess){\n\n // we start the process\n myProcess.triggerEvent(\"MyStart\");\n\n\t});\n\nThe handler file looks like:\n\n\texports.MyStart = function(data, done) {\n \t// called after the start event arrived at MyStart\n \tdone(data);\n\t};\n\n\texports.MyTask = function(data, done) {\n \t// called at the beginning of MyTask\n \tdone(data);\n\t};\n\n\texports.MyTaskDone = function(data, done) {\n \t// Called after the process has been notified that the task has been finished\n\t\t// by invoking myProcess.taskDone(\"MyTask\").\n\t\t// Note: <task name> + \"Done\" handler are only called for \n\t\t// user tasks, manual task, and unspecified tasks\n \tdone(data);\n\t};\n\n\texports.MyEnd = function(data, done) {\n \t// Called after MyEnd has been reached\n \tdone(data);\n\t};\n\nProcesses can also be created from an xml string instead of file. In this case the handler can be an object or a javascript string that would be parsed.\n\n\n\tbpmn.createUnmanagedProcessFromXML(\"<definitions ... </definitions>\", \"exports.MyStart = ...\", function(err, myProcess){\n\n // we start the process\n myProcess.triggerEvent(\"MyStart\");\n\n\t});\n\n\n\nIf no handler is defined, the default handler is being called. This handler can also be specified in the handler file by:\n\n\t/**\n \t * @param {String} eventType Possible types are: \"activityFinishedEvent\", \"callHandler\"\n \t * @param {String?} currentFlowObjectName The current activity or event\n \t * @param {String} handlerName\n \t * @param {String} reason Possible reasons:\n\t * \t\t\t\t\t\t\t- no handler given\n\t *\t\t\t\t\t\t\t- process is not in a state to handle the incoming event\n\t *\t\t\t\t\t\t\t- the event is not defined in the process\n\t *\t\t\t\t\t\t\t- the current state cannot be left because there are no outgoing flows\n \t */\t\n\texports.defaultEventHandler = function(eventType, currentFlowObjectName, handlerName, reason, done) {\n\t\t// Called, if no handler could be invoked. \n \tdone(data);\n\t};\n\nIf the default handler is not specified the default default event handler is being called which just logs a message to stdout.\n\nBesides the default event handler, it is also possible to specify a default error handler:\n\t\n\texports.defaultErrorHandler = function(error, done) {\n \t// Called if errors are thrown in the event handlers\n \tdone();\n\t};\n\nSometimes it is useful to call handlers before or after each activity, task, or catch event. To do this specify\n\n\texports.onBeginHandler = function(currentFlowObjectName, data, done) {\n // do something\n\t\tdone(data);\n };\n exports.onEndHandler = function(currentFlowObjectName, data, done) {\n // do something\n\t\tdone(data);\n };\n\n\nHandler Context (this)\n----------------------\n\nEach handler is called in the context of the current process. More formally: `this` is bound to `BPMNProcessClient`. This object offers the following interface to the current process instance:\n\n- `taskDone(taskName, data)`: notify the process that a task has been done. This triggers calling the event handler: `taskName` + \"Done\"\n- `triggerEvent(eventName, data)`: send an event to the process\n- `getState()`: get the state of the current process. The state object is `BPMNProcessState`.\n- `getHistory()`: get the history of the current process. Basically a list of all visited activities and events encapsulated in `BPMNProcessHistory`\n- `setProperty(name, value)`: set a process property. This property is also persisted together with the process. The value is a valid JS data object. That is, we do not persist functions.\n- `getProperty(name)`: get property.\n- `getParentProcess()`: if this process has been called by a `callActivity` activity, this call returns a `BPMNProcessClient` instance of the calling process. Otherwise it returns `null`.\n- `getParticipantByName(participantName)`: if this process collaborates with other processes (see section *Collaboration Processes*), this call returns a `BPMNProcessClient` instance of a participating process instance having the name `participantName`. This allows to send for example an event to a participating process by\n\tthis.getParticipantName(\"Another process\").triggerEvent(\"my event\");\n\nHandler Names\n-------------\nThe handler names are derived by replacing all not allowed JS characters by '_'. For example, \"My decision?\" becomes `My_decision_`. The bpmn module exports `mapName2HandlerName(bpmnName)` that can be invoked to get the handler name for a given BPMN name.\n\nExclusive Gateways (Decisions)\n==============================\n\nIf the following process has to be implemented, we have to provide three handlers for the exclusive gateway:\n\t\n\texports.Is_it_ok_ = function(data, done) {\n \t// called after arriving at \"Is it ok?\"\n \tdone(data);\n\t};\n\n\texports.Is_it_ok_$ok = function(data) {\n \t// has to return true or false\n\t\t// the name of the sequence flow follows after \"$\".\n\t\t// if there is no name, an error is thrown \n \treturn true;\n\t};\n\n\texports.Is_it_ok_$nok = function(data) {\n \t// has to return true or false\n\t\t// the name of the sequence flow follows after \"$\".\n\t\t// if there is no name, an error is thrown \n \treturn false;\n\t};\n\n\n![](https://raw.githubusercontent.com/e2ebridge/bpmn/master/examples/processes/exclusiveGateway.png)\n\n**Note**: \nFor each outgoing transition we have a condition handler that hast to evaluate synchronously. So if backend data are required, fetch them in the gateway callback.\nFurthermore, BPMN does not specify the order of evaluating the flow conditions, so the implementer has to make sure, that only one operation returns `true`. Additionally, we ignore the condition expression. We consider this as part of the implementation.\n\nTimer Events\n============\n\nBoundary Timer Events\n---------------------\n\nBoundary timer events are timeouts on the activity they are attached to. To implement timeouts use two handlers:\n\n\texports.MyTimeout$getTimeout = function(data, done) {\n \t// called when arriving on \"MyTask\"\n\t\t// should return timeout in ms.\n \treturn 1000;\n\t};\n\n\texports.MyTimeout = function(data, done) {\n \t// called if the timeout triggers\n \tdone(data);\n\t};\n\n![](https://raw.githubusercontent.com/e2ebridge/bpmn/master/examples/processes/timeout.png)\n\nIntermediate Timer Events\n-------------------------\nIntermediate catch timer events are used to stop the process for a given time. If the timer event occurs, the process proceeds. The implementation is very similar to boundary timer events:\n\n\texports.MyTimeout$getTimeout = function(data, done) {\n \t// called when arriving on \"Intermediate Catch Timer Event\"\n\t\t// should return wait time in ms.\n \treturn 10000;\n\t};\n\n\texports.Intermediate_Catch_Timer_Event = function(data, done) {\n \t// called if the timeout triggers\n \tdone(data);\n\t};\n\n![](https://raw.githubusercontent.com/e2ebridge/bpmn/master/examples/processes/intermediateTimerEvent.png)\n\n\nCollaborations\n==============\n\nBPMN also supports collaborating processes as depicted below.\n\n![](https://raw.githubusercontent.com/e2ebridge/bpmn/master/examples/processes/collaboration.png)\n\nThese processes must be created together:\n\n\t// create collaborating processes\n bpmn.createUnmanagedCollaboratingProcesses(\"my/collaboration/example.bpmn\", function(err, collaboratingProcesses){\n\n // start the second process\n var secondProcess = collaboratingProcesses[1];\n secondProcess.triggerEvent(\"Start Event 2\");\n\n });\n\nThe collaboration of the processes is then implemented in the handlers. For example, it is possible to get a partner process by name and then send an event to this process. This is frequently done to start the partner process:\n\n\texports.Task_2 = function(data, done) {\n \t// after arriving ot \"Task 2\" we start process 1\n \tvar partnerProcess = this.getParticipantByName(\"My First Process\");\n \tpartnerProcess.triggerEvent(\"Start Event 1\");\n \tdone(data);\n\t};\n\nHowever, another option is to get all outgoing message flows and send a message along these flows. In the current example we have exactly one flow, so sending the message is done by:\n\n\texports.End_Event_1 = function(data, done) {\n \t// after reaching the end of process 1, we send a message\n \tvar messageFlows = this.getOutgoingMessageFlows(\"End Event 1\");\n \tthis.sendMessage(messageFlows[0], {gugus: \"blah\"});\n \tdone(data);\n\t};\n\nCollaborating processes can also be created from strings using createUnmanagedCollaboratingProcessesFromXML(bpmnXML, handler, callback).\n\n**Note**: all task and event names must be unique\n\nLogging\n=======\nBy default, only errors are logged. However, it is easy to change the log level:\n\n\tvar logLevels = require('bpmn').logLevels;\n\t\n\tmyProcess.setLogLevel(logLevels.debug);\n\nIt is also possible to use log level strings instead of the log level enumeration:\n\n\tmyProcess.setLogLevel(\"debug\");\n\nOr within a handler:\n\n\tthis.setLogLevel(\"trace\");\n\nBy default, logs are written to the console and `./process.log`. Of course, this can be changed. For details see the section *Log Transports*.\n\nThe supported log levels are:\n\n- **none**: switches logging off\n- **error** (default): Errors, error handler calls, and default event handler calls are logged\n- **trace**: process actions are logged: sendMessage, triggerEvent, callHandler, callHandlerDone, taskDone, catchBoundaryEvent\n- **debug**: internal process actions are logged, such as putTokenAt, tokenArrivedAt, doneSaving, etc.\n- **silly, verbose, info, warn**: these levels are reserved for further use but not yet implemented: \n\nLog Transports\n--------------\nWe use [winston](https://github.com/flatiron/winston) as log library. This allows as to define different ways of storing our logs by defining so called winston transports (for details see [here](https://github.com/flatiron/winston/blob/master/docs/transports.md)). The default transports used by this library are\n\n\ttransports: [\n new (winston.transports.Console)({\n colorize: true\n }),\n new (winston.transports.File)({\n level: 'verbose',\n filename: './process.log',\n maxsize: 64 * 1024 * 1024,\n maxFiles: 100,\n timestamp: function() {\n return Date.now();\n }\n })\n ]\n\nHowever, these transports can be overridden or completely new transports can be added. For example, the following code snippet adds a file transport used for errors, max size of one megabyte, and not writing timestamps:\n\n\tvar winston = require('winston'); \n\tmyProcess.addLogTransport(winston.transports.File,\n {\n level: 'error',\n filename: \"my/log/file.log\",\n maxsize: 1024 * 1024,\n timestamp: false\n }\n );\n\n**Note**: the directory containing the log file must exist, otherwise an error is thrown. \n\nOf course, transports can be removed as well, e.g.:\n\n\tbpmnProcess.removeLogTransport(winston.transports.File);\n\nManaging processes\n==================\n\nProcess managers are used to create multiple processes using the same definitions and find them back later.\n\n var manager = new bpmn.ProcessManager();\n\n manager.addBpmnFilePath(\"path/to/myProcess.bpmn\");\n\n manager.createProcess(\"myId\", function(err, myProcess){\n\n // we start the process\n myProcess.triggerEvent(\"MyStart\");\n\n });\n\nIf the process id is already used an error is returned.\n\nIf the manager have multiple bpmn definitions a descriptor object must be passed to the create function.\n\n manager.createProcess({id: \"myId\", name: \"MyProcess\"}, function(err, myProcess){\n\n // we start the process\n myProcess.triggerEvent(\"MyStart\");\n\n });\n\nTo create collaborating processes and array of descriptors must be passed to the create function.\n\n var processDescriptors = [\n {name: \"My First Process\", id: \"myFirstProcessId_1\"},\n {name: \"My Second Process\", id: \"mySecondProcessId_1\"}\n ];\n manager.createProcess(processDescriptors, function(err, collaboratingProcesses){\n\n var secondProcess = collaboratingProcesses[1];\n secondProcess.triggerEvent(\"Start Event 2\");\n\n });\n\n\nProcess definitions and handlers can be add in the manager creator or using add* functions.\n\nCreator options:\n\n- **handlerFilePath**: Object with name and filePath. Can be an array of theses object to define multiple handlers.\n * **name**: The name of the process definition for which the handler will be used.\n * **filePath**: Path to the javascript file defining the handler module.\n- **handlerString**: Object with name and string. Can be an array of theses object to define multiple handlers.\n * **name**: The name of the process definition for which the handler will be used.\n * **string**: The javascript string defining the handler module.\n- **handler**: Object with name and module. Can be an array of theses object to define multiple handlers.\n * **name**: The name of the process definition for which the handler will be used.\n * **module**: The javascript object defining the handler module.\n\n- **bpmnFilePath**: Path to the bpmn file. Can be an array to define multiple definitions. will try to load the handler from the corresponding javascript file.\n- **bpmnXML**: Object with name and xml. Can be an array of theses object to define multiple definitions.\n * **name**: The name of the process definition.\n * **xml**: The xml string definition.\n\n\n**Note**: If no handler is found for a process definition an error is thrown.\n\n var manager = new bpmn.ProcessManager({\n bpmnFilePath: \"path/to/myProcess.bpmn\"\n });\n\n\n\nProcessManager.addHandlerFilePath(name, handlerFilePath)\n\n- **name**: The name of the process definition for which the handler will be used.\n- **handlerFilePath**: Path to the javascript file defining the handler module.\n\nProcessManager.addHandlerString = function(name, handlerString)\n\n- **name**: The name of the process definition for which the handler will be used.\n- **handlerString**: The javascript string defining the handler module.\n\nProcessManager.addHandler = function(name, handler)\n\n- **name**: The name of the process definition for which the handler will be used.\n- **handlerString**: The javascript object defining the handler module.\n\n\nProcessManager.addBpmnFilePath = function(bpmnFilePath, processHandler)\n\n- **bpmnFilePath**: Path to the bpmn file.\n- **processHandler**: Optional. The javascript object defining the handler module or the path to the javascript file defining the handler module.\n\nIf no processHandler is passed we try to load the corresponding javascript file to the bpmn file. If no handler is found or defined before for this definition an error is thrown.\n\n\nProcessManager.addBpmnXML = function(bpmnXml, processName, processHandler)\n\n- **bpmnXml**: The xml string definition.\n- **processName**: The name of the process definition.\n- **processHandler**: Optional. The javascript object defining the handler module or the javascript string defining the handler module.\n\nIf no processHandler is passed and no handler was defined before for this definition an error is thrown.\n\n\nFinding processes\n-----------------\n\nExisting processes in a manager can be retrived using these functions:\n\n\t// returns the process with the corresponding id\n\tbpmn.get(processId, function(err, process){\n ...\n\t});\n\n\t// returns all processes\n bpmn.getAllProcesses(function(err, processes){\n ...\n });\n\n\t// returns all processes having the property names\n\tbpmn.findByProperty({propName1: propValue1, propName2: propValue2, ...}, function(err, processes){\n ...\n });\n\n\t// returns all processes in this state (callActivity, tasks, event, ...)\n\tbpmn.findByState(stateName, function(err, processes){\n ...\n });\n\n\t// returns all processes using this definition\n\tbpmn.findByName(definitionName, function(err, processes){\n ...\n });\n\n\nPersistency\n-----------\n\nThe manager constructor also takes persistency options. The engine will save the state while waiting for a task being done. After a manager is created with persistency options all stored processes can be retrived using the functions above. The process can be persisted to the file system or to a MongoDB. We recommend the latter approach for productive use cases.\n\n // using files\n var manager = new bpmn.ProcessManager({\n persistencyOptions: {\n uri: \"path/to/folder\"\n }\n });\n\n\n // using mongodb\n var manager = new bpmn.ProcessManager({\n persistencyOptions: {\n uri: \"mongodb://host:port/db_name\"\n }\n });\n\n\nMain module is an instance of ProcessManager\n--------------------------------------------\n\nThe main bpmn module is an instance of ProcessManager without options meaning you can use manager functions directly from it.\n\n var bpmn = require('bpmn');\n\n bpmn.addBpmnFilePath(\"path/to/myProcess.bpmn\");\n\n bpmn.createProcess(\"myId\", function(err, myProcess){\n\n // we start the process\n myProcess.triggerEvent(\"MyStart\");\n\n });\n\n\nREST\n====\n\nServer\n------\n\nThe above API can also be called by REST HTTP calls. To do this, you have first to instantiate a server from ta manager. For example:\n\n\t// Returns a restify server.\n\tvar server = manager.createServer();\n\tserver.listen(9009, function() {\n \tconsole.log('%s listening at %s', server.name, server.url);\n\t});\n\nThe server is a node restify server. So all features of this package can be used.\nThe full signature of `createProcess` is\n\n\tvar server = manager.createServer(options, restifyOptions);\n\nThe parameters are:\n\n- **options**: optional object having the following optional properties\n \t* **createProcessId**: Function that returns a UUID. Default: `node-uuid.v1()`\n \t* **logLevel**: used log level. Default: Error. Use logger.logLevels to set.\n- **restifyOptions**: these options are given to the restify.createServer call. If not given, the log property is set to the internal winston logger and the name property is set to 'bpmnRESTServer'.\n\nClient\n------\n\nThe following sections describe how a client would use the REST API provided by the server above. The API calls are illustrated using the [restify client library](http://mcavage.github.io/node-restify/#client-api).\n\n**Creating a process**\n\nTo create a process send a `POST` request:\n\n\t// This example used the node-restify client\n\tvar client = restify.createJsonClient({url: \"http://localhost:9009\"});\n\n client.post('/TaskExampleProcess', function(err, req, res, obj) { ... });\n\nWhen receiving this request the server will use the `urlMap` to find the BPMN file associated with the process name in the URL, instantiate this process and return the process state in the response body as a JSON object:\n\n\t{\n\t\t\"id\": \"3c5e28f0-cec1-11e2-b076-31b0fecf7b6f\",\n\t\t\"name\": \"TaskExampleProcess\",\n\t\t\"link\": {\n\t\t \"rel\": \"self\",\n\t\t \"href\": \"/TaskExampleProcess/3c5e28f0-cec1-11e2-b076-31b0fecf7b6f\"\n\t\t},\n\t\t\"state\": [],\n\t\t\"history\": [],\n\t\t\"properties\": {}\n\t}\n\nThe process has now been created but not yet started! Thus, `state`, `history`, and `properties` are empty. To do this, you have either to send a start event using a PUT request (see below) or you can **create and start** the process in one go by appending the start event to the process URI:\n\n var message = {\n\t\t\t\"gugus\": \"blah\", // a process property ...\n\t\t\t\"sugus\": \"foo\", // and another one.\n };\n\n client.post('/TaskExampleProcess/MyStart', message, function(err, req, res, obj) { ... });\n\nIf the `MyStart` event handler sets a process property such as\n\n\texports.MyStart = function(data, done) {\n \tthis.setProperty(\"myFirstProperty\", data);\n \tdone(data);\n\t};\n\nThe result of above POST request may look like:\n\n\t{\n\t \"id\": \"3c5e28f0-cec1-11e2-b076-31b0fecf7b6f\",\n\t \"name\": \"TaskExampleProcess\",\n\t \"link\": {\n\t \"rel\": \"self\",\n\t \"href\": \"/TaskExampleProcess/3c5e28f0-cec1-11e2-b076-31b0fecf7b6f\"\n\t },\n\t \"state\": [\n\t {\n\t \"position\": \"MyTask\",\n\t \"owningProcessId\": \"3c5e28f0-cec1-11e2-b076-31b0fecf7b6f\"\n\t }\n\t ],\n\t \"history\": [\n\t {\n\t \"name\": \"MyStart\"\n\t },\n\t {\n\t \"name\": \"MyTask\"\n\t }\n\t ],\n\t \"properties\": {\n\t \"myFirstProperty\": {\n\t \"gugus\": \"blah\",\n\t\t\t\t\"sugus\": \"foo\"\n\t }\n\t }\n\t}\n\n**Note**: all REST request return either the process state or an array of process states.\n\n**Getting the process state, history, and properties**\n\nTo the current state, history, and properties of process use\n\n\tclient.get('/TaskExampleProcess/3c5e28f0-cec1-11e2-b076-31b0fecf7b6f', function(err, req, res, obj) {...});\n\nThe returned object is the same as in the last POST request. Following REST convetions, the operation giving all processes of a given type is\n\n\tclient.get('/TaskExampleProcess', function(err, req, res, obj) {...});\n\nOr if is also possible using query strings. For example, the following query returns all processes having property `x` containing the attribute `y` having the value `uvw`\n\n\tclient.get('/TaskExampleProcess?x.y=uvw', function(err, req, res, obj) {...});\n\nIt is also possible to query processes executing a task, an activity, or waiting for an event to happen by sending the following request:\n\n\tclient.get('/TaskExampleProcess?state=MyTask', function(err, req, res, obj) {...});\n\nOf course, all queries can be combined in one request.\n\n**Sending messages and triggering events**\n\nBoth is done by send a `PUT` request containing the send message or triggered event data as body:\n\n\tvar data = {\n \"gugus\": \"blah\"\n };\n\tclient.put('/TaskExampleProcess/myprocessid/MyStart/myeventid', data, function(err, req, res, obj) {...});\n\nor \n\n\tvar message = {\n \"gugus\": \"blah\"\n };\n\tclient.put('/TaskExampleProcess/myprocessid/MyStart/mymessageid', data, function(err, req, res, obj) {...});\n\nBPMN\n====\n\nSupported Elements\n-----------------------\n- **Start events**: all kind of start events are mapped to the none start event. Any further specialization is then done in the implementation of the handler.\n- **End events**: all kind of end events are mapped to the none end event. Any further specialization is then done in the implementation of the handler.\n- **Gateways**: Parallel- and exclusive gateways are supported.\n- **Task, User Task, Manual Task, Receive Task**: These tasks call an event handler when the task starts and then wait until `taskDone(taskName, data)` is invoked on the process.\n- Service Task, Script Task, Business Rule Task, Send Task (Wait Tasks): These tasks call an event handler when the task starts and proceed immediately after the the handler finishes.\n- **Throw Intermediate Events**: the handler is triggered when the intermediate event is reached. All types of intermediate events are treated the same.\n- **Catch Intermediate Events**: the handler is triggered if the event is catched and not when it is reached. For example, if we have an intermediate catch message event, the handler is triggered when the message arrives. If we have an intermediate catch timer event, the handler is triggered when the timout occurs. However, in both cases, no handler is triggered when the intermediate event is reached.\n- **Call Activity**: an external sub-process is called. The sub-process must not be a collaboration and must have exactly one start event.\n- **Boundary Events**: message and timeout boundary elements are supported for all wait tasks (Task, User Task, Manual Task, Receive Task). The handler is triggered if the events occur.\n\nLimitations \n-----------\n- **Start events**: all kind of start events are mapped to the none start event. Any further specialization is then done in the implementation of the handler.\n- **End events**: all kind of end events are mapped to the none end event. Any further specialization is then done in the implementation of the handler.\n- **Gateway**s: only parallel- and exclusive gateways are supported yet.\n- Data objects: are ignored by the engine\n\n\nLicensing\n---------\n\n(The MIT License)\n\nCopyright (c) 2014 [E2E Technologies Ltd](http://www.e2ebridge.com)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n\nby [E2E Technologies Ltd](http://www.e2ebridge.com)\n\n\nQuestions, comments, thoughts?\n------------------------------\nThis is a very rough work in progress. \n\nFeel free to contact me at mrassinger@e2e.ch with questions or comments about this project.\n\n\n\n",
"readmeFilename": "README.md",
"repository": {
"type": "git",
"url": "git+https://github.com/e2ebridge/bpmn.git"
},
"scripts": {},
"version": "0.2.2"
}