Skip to content

Commit 1d77e01

Browse files
committed
Documenting bpmnDsl and worker.
1 parent a7eecd5 commit 1d77e01

File tree

2 files changed

+243
-5
lines changed

2 files changed

+243
-5
lines changed

00-documentation/src/docs/bpmnDsl.md

Lines changed: 104 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ object MyProcess extends CompanyBpmnProcessDsl:
9797
)
9898
end MyProcess
9999
```
100-
Next to the _In_ and _Out_ classes we have an _InitIn_ and _InConfig_ class.
100+
Next to the _In_ and _Out_ classes we have an _InitIn_- and _InConfig_ class.
101101

102102
### InitIn
103103
Each process has an _InitWorker_ that is the first worker that is called when the process is started.
@@ -106,6 +106,7 @@ Use this class to:
106106
- init the _Process Variables_ that are needed in the process (e.g. counters, variables used in expressions that must be defined (Camunda 7 restriction)).
107107
- init the _Process Variables_ with default values, that are not provided by the client.
108108
So you can be sure that they are always set - from Option to required in the process.
109+
- extract some information from the input variables to simplify the process.
109110

110111
### InConfig
111112
These are technical _Process Variables_, like:
@@ -114,7 +115,8 @@ These are technical _Process Variables_, like:
114115

115116
@:callout(info)
116117
The _InitWorker_ will automatically put these variables on the process.
117-
That means you can override them for example in _Postman_.
118+
That means you can override them for example in _Postman_
119+
- just set them as _process variables_ (`inConfig` object is not needed).
118120
@:@
119121

120122
## Business Rule Tasks (Decision DMNs)
@@ -215,6 +217,106 @@ end MyUserTask
215217
- The `In` object are the input variables you expect for the UI-Form of the _UserTask_.
216218
- The `Out` object are the process variables, the UI-Form sends, when it completes the _UserTask_.
217219

220+
## External Task
221+
An _External Task_ describes a worker.
222+
We distinguish different types of Tasks, which are described in the next subchapters.
223+
224+
```scala
225+
### Custom Task
226+
A _Custom Task_ is a description for a worker that does some business logic, like mapping.
227+
228+
In General, you can do whatever you want with a _Custom Task_. See also _CustomWorker_.
229+
230+
```scala
231+
object MyCustomTask extends CompanyBpmnCustomTaskDsl:
232+
233+
val topicName = "mycompany-myproject-myprocessV1.MyCustomTask"
234+
val descr: String = "my custom task..."
235+
236+
case class In(...)
237+
object In:
238+
given ApiSchema[In] = deriveApiSchema
239+
given InOutCodec[In] = deriveInOutCodec
240+
241+
case class Out(...)
242+
object Out:
243+
given ApiSchema[Out] = deriveApiSchema
244+
given InOutCodec[Out] = deriveInOutCodec
245+
246+
lazy val example = customTask(
247+
In(),
248+
Out()
249+
)
250+
end MyCustomTask
251+
```
252+
253+
### Init Task
254+
An _Init Task_ is a description for a worker that initializes a _Process_.
255+
256+
In General, you map the `In` object to the `InitIn` object like init process variables.
257+
See also _InitWorker_.
258+
259+
So no extra BPMN Element is needed for this, it is automatically defined by the _Process_.
260+
261+
```scala
262+
object MyProcess extends CompanyBpmnProcessDsl:
263+
...
264+
case class In(
265+
...
266+
inConfig: Option[InConfig] = None
267+
) extends WithConfig[InConfig]
268+
...
269+
case class InitIn(...)
270+
...
271+
end MyProcess
272+
```
273+
274+
### Service Task
275+
A _Service Task_ is a description for a worker that provides a REST API request.
276+
277+
See also _ServiceWorker_.
278+
279+
```scala
280+
object MyServiceTask extends CompanyBpmnServiceTaskDsl:
281+
282+
val topicName = "mycompany-myproject-myservicetask"
283+
val descr: String = "my service task..."
284+
val path = "POST: /myService"
285+
286+
type ServiceIn = MyServiceBody
287+
type ServiceOut = NoOutput
288+
lazy val serviceInExample = MyServiceBody()
289+
lazy val serviceMock = MockedServiceResponse.success204
290+
291+
case class In(...)
292+
object In:
293+
given ApiSchema[In] = deriveApiSchema
294+
given InOutCodec[In] = deriveInOutCodec
295+
296+
case class Out(...)
297+
object Out:
298+
given ApiSchema[Out] = deriveApiSchema
299+
given InOutCodec[Out] = deriveInOutCodec
300+
301+
lazy val example = serviceTask(
302+
In(),
303+
Out(),
304+
serviceMock,
305+
serviceInExample
306+
)
307+
end MyServiceTask
308+
```
309+
This task is more specific, and so we need to define
310+
- The method and the path of the REST service for the documentation.
311+
- The _ServiceIn_ and _ServiceOut_ types.
312+
They represent the bodies of the service-request and -response.
313+
- In the _example_ we define also the _serviceInExample_ and the _serviceMock_.
314+
315+
@:callout(info)
316+
At the moment we only support these 3 types of _External Tasks_.
317+
Depending on the use case we can add more types.
318+
@:@
319+
218320
## Receive Message Event
219321
A _Receive Message Event_ represents a catching message event.
220322
The input defines the message you expect.
Lines changed: 139 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,146 @@
11
# Workers
2+
The implementation of an **_External Task_** is done by a _**Worker**_.
23

4+
So for each _External Task_ type we have a DSL for an according _Worker_.
5+
6+
## Custom Worker
7+
The _Custom Worker_ is a general _Worker_ that can used for any business logic or integration.
8+
9+
It automatically does:
10+
- validate the input variables
11+
12+
You can create:
13+
- business logic that can't be handled by the expression language in the BPMN itself
14+
- a service integration that is not covered by the _Service Worker_
15+
- whatever you want
16+
17+
```scala
18+
import mycompany.myproject.bpmn.myprocess.v1.MyCustomTask.*
19+
20+
@Configuration
21+
class MyCustomTaskWorker extends CompanyCustomWorkerDsl[In, Out]:
22+
23+
lazy val customTask = example
24+
25+
def runWork(in: In): Either[CamundalaWorkerError.CustomError, Out] =
26+
// your business logic
27+
???
28+
override def validate(in: In): Either[CamundalaWorkerError.ValidatorError, In] =
29+
??? // custom validation logic here
30+
```
31+
- `lazy val customTask` is just needed for the compiler to check the correctness of the types.
32+
- `runWork` is the method that is called by the _Worker_ to execute the business logic.
33+
- The code can either:
34+
- complete the task successfully with a result -> `Right[Out]`
35+
- fail the task with an error -> `Left[CamundalaWorkerError.CustomError]`
36+
- `override def validate(in: In)` is optional and can be used to add more sophisticated validation logic.
37+
If the validation fails, the process will fail.
38+
39+
Examples:
40+
41+
### runWork
42+
TODO
43+
### validate
44+
This is the same in every worker type.
45+
TODO
46+
47+
```scala
348
## Init Process Worker
49+
The _Init Process Worker_ is a special _Worker_ that is used to start a process.
50+
51+
It automatically does:
52+
- validate the input variables
53+
- merge the _inConfig_ variables with manual overrides
54+
55+
You can:
56+
- init input process variables with default values.
57+
- init process variables used to control the process flow,
58+
like counters, variables that may not be on the process.
59+
- create simplified process variables to simplify the process flow.
60+
- validate the input variables, if you need more sophisticated validation logic,
61+
than you can do with the type definition.
62+
63+
```scala
64+
import mycompany.myproject.bpmn.myprocess.v1.MyProcess.*
65+
66+
@Configuration
67+
class MyProcessWorker extends CompanyInitWorkerDsl[In, Out, InitIn, InConfig]:
68+
69+
lazy val inOutExample = example
70+
71+
def customInit(in: In): InitIn =
72+
??? // init logic here
73+
override def validate(in: In): Either[CamundalaWorkerError.ValidatorError, In] =
74+
??? // custom validation logic here
75+
```
76+
- `lazy val inOutExample` is just needed for the compiler to check the correctness of the types.
77+
- `customInit` is the method that is called by the _Worker_ to execute the init logic.
78+
- The method sets the process variables according the _InitIn_ object.
79+
Be aware that this can not fail, as the input variables are already validated.
80+
- `override def validate(in: In)` is optional and can be used to add more sophisticated validation logic.
81+
If the validation fails, the process will fail.
82+
83+
Examples:
84+
85+
### customInit
486
TODO
587

688
## Service Worker
7-
TODO
89+
The _Service Worker_ is a special _Worker_ that is used to call a REST API service.
890

9-
## Custom Worker
10-
TODO
91+
It automatically does:
92+
- validate the input variables
93+
94+
You can provide:
95+
- the method and the path of the service
96+
- the query parameters
97+
- the headers
98+
- the mapping of the input- or output request body
99+
100+
```scala
101+
import mycompany.myproject.bpmn.myprocess.v1.MyServiceTask.*
102+
103+
@Configuration
104+
class MyServiceTaskWorker extends CompanyServiceWorkerDsl[In, Out]:
105+
106+
lazy val serviceTask = example
107+
108+
def apiUri(in: In) = uri"$serviceBasePath/myService"
109+
override protected lazy val method: Method = Method.POST
110+
111+
override protected def inputHeaders(in: In): Map[String, String] =
112+
??? // map the input variables to the headers
113+
override def querySegments(in: In) =
114+
??? // map the input variables to the query parameters
115+
override def inputMapper(in: In): Option[ServiceIn] =
116+
??? // map the input variables to the service request body
117+
override def outputMapper(
118+
out: ServiceResponse[ServiceOut],
119+
in: In
120+
): Either[ServiceMappingError, Out] =
121+
??? // map the service response body and header to the output variables
122+
override def validate(in: In): Either[CamundalaWorkerError.ValidatorError, In] =
123+
??? // custom validation logic here
124+
```
125+
- `lazy val serviceTask` is just needed for the compiler to check the correctness of the types.
126+
- `def apiUri(in: In)` the path of the service, with the path parameters from the `in` object.
127+
The only required function.
128+
- `override protected lazy val method: Method` is the HTTP method. Default is `Method.GET`.
129+
- `override def querySegments(in: In)` is optional and can be used to add query parameters to the request.
130+
- `override def inputHeaders(in: In)` is optional and can be used to add headers to the request.
131+
- `override def inputMapper(in: In)` is optional and can be used to map the input variables to the request body.
132+
- `override def outputMapper(out: ServiceResponse[ServiceOut], in: In)` is optional and can be used to map the response body and -headers to the output variables.
133+
- `override def validate(in: In)` is optional and can be used to add more sophisticated validation logic.
134+
If the validation fails, the process will fail.
135+
136+
Examples:
137+
138+
### apiUri
139+
TODO
140+
### querySegments
141+
TODO
142+
### inputHeaders
143+
TODO
144+
### inputMapper
145+
TODO
146+
### outputMapper

0 commit comments

Comments
 (0)