Skip to content

Commit 2de4306

Browse files
committed
Added Simulation documentation.
1 parent f948cbe commit 2de4306

File tree

22 files changed

+642
-532
lines changed

22 files changed

+642
-532
lines changed

00-docs/src/docs/company/03-dmn.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,4 +59,4 @@ dmnPaths: Seq[os.Path] = Seq(
5959
exposedPort: Int = 8883,
6060
// the image version of the DMN Tester
6161
imageVersion: String = "latest"
62-
```
62+
```
Lines changed: 104 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,104 @@
1-
# 03-simulation
1+
# 03-simulation
2+
Use this to add Company specific Simulation stuff like the configuration of the auth method.
3+
4+
The following structure is generated by `./helperCompany.scala init`:
5+
6+
```bash
7+
03-simulation/src
8+
| main/resources
9+
| main/scala/company/simulation
10+
| | CompanySimulation.scala
11+
| test/scala/company/simulation
12+
```
13+
## CompanySimulation
14+
The Company's base class to run the Simulations.
15+
16+
Example (generated by `./helperCompany.scala init`):
17+
18+
```scala
19+
package mycompany.camundala.simulation
20+
21+
import camundala.simulation.custom.*
22+
23+
/**
24+
* Add here company specific stuff, to run the Simulations.
25+
*/
26+
trait CompanySimulation extends BasicSimulationDsl:
27+
28+
override def config =
29+
super.config //TODO Adjust config if needed
30+
31+
end CompanySimulation
32+
```
33+
34+
## SimulationConfig
35+
You can customize the Simulation Configuration.
36+
37+
```scala
38+
super.config
39+
.withTenantId("myTenant")
40+
```
41+
### Default Config
42+
43+
```scala
44+
// define tenant if you have one
45+
tenantId: Option[String] = None,
46+
// the Camunda Port
47+
// there are Requests that wait until the process is ready - like getTask.
48+
// the Simulation waits 1 second between the Requests.
49+
// so with a timeout of 10 sec it will try 10 times (retryDuration = 1.second)
50+
maxCount: Int = 10,
51+
// REST endpoint of Camunda
52+
endpoint: String = "http://localhost:8080/engine-rest",
53+
// you can add authentication with this - default there is none.
54+
// see BasicSimulationDsl / OAuthSimulationDsl for examples
55+
authHeader: B => B = (b: B) => b,
56+
// the maximum LogLevel you want to print the LogEntries.
57+
logLevel: LogLevel = LogLevel.INFO
58+
```
59+
60+
61+
## Authentication
62+
We provide at the moment the following authentication methods:
63+
64+
### Basic Authentication
65+
66+
```scala
67+
import camundala.simulation.custom.*
68+
69+
trait CompanySimulation extends BasicSimulationDsl:
70+
71+
override lazy val username = sys.env.getOrElse("CAMUNDA_USER", "demo")
72+
override lazy val password = sys.env.getOrElse("CAMUNDA_PASSWORD", "demo")
73+
//...
74+
```
75+
76+
You can override the `username` and `password` to use your credentials,
77+
default is `demo`/`demo`.
78+
79+
### OAuth2 Authentication
80+
81+
```scala
82+
import camundala.simulation.custom.*
83+
84+
trait CompanySimulation extends OAuthSimulationDsl:
85+
86+
lazy val fsso: Fsso = Fsso(
87+
s"$fssoBaseUrl/auth/realms/${config.tenantId.get}/protocol/openid-connect",
88+
Map(
89+
"grant_type" -> "password",
90+
"client_id" -> "bpf",
91+
"client_secret" -> fssoClientSecret,
92+
"username" -> fssoUser,
93+
"password" -> fssoPassword,
94+
"scope" -> "fcs"
95+
))
96+
//...
97+
private lazy val fssoBaseUrl = sys.env.getOrElse("FSSO_BASE_URL", "http://host.lima.internal:8090")
98+
//...
99+
```
100+
101+
Here you have to provide the FSSO configuration.
102+
- `Fsso.url` is the URL of the FSSO Server.
103+
- `Fsso.bodyForm` is the body of the POST request to get the token.
104+

00-docs/src/docs/functionalityDsls/simulation.md

Lines changed: 41 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ The diagrams must be deployed.
1111

1212
@:callout(info)
1313
For the deployment I created a script that also starts the Simulation.
14+
15+
See [deploy](../development/projectDev.md#deploy).
1416
@:@
1517

1618
## Why
@@ -42,15 +44,10 @@ Let's start with a basic example:
4244
// put your simulations in the simulation package of your project (it)
4345
package camundala.examples.invoice.simulation
4446
// import the projects bpmns (Processes, UserTasks etc.)
45-
4647
import camundala.examples.invoice.bpmn.*
47-
// import Camundala simulation DSL - for now this is the one and only
48-
import camundala.simulation.custom.CustomSimulation
4948

5049
// define a class that extends from a simulation DSL
51-
class InvoiceSimulation extends CustomSimulation
52-
53-
:
50+
class InvoiceSimulation extends CompanySimulation:
5451

5552
simulate(
5653
// add scenarios (comma separated)
@@ -71,6 +68,10 @@ class InvoiceSimulation extends CustomSimulation
7168
end InvoiceSimulation
7269
```
7370

71+
@:callout(info)
72+
This class is automatically created with `./helper.scala process <processName>` - see [development > process](../development/projectDev.md#process).
73+
@:@
74+
7475
#### simulate
7576

7677
This is the entry point for your Simulation.
@@ -89,11 +90,11 @@ In your _sbt-console_:
8990

9091
- run all simulations:
9192

92-
`It/test`
93+
`simulation/test`
9394

9495
- run some simulations:
9596

96-
`It/testOnly *MySimulation`
97+
`simulation/testOnly *MySimulation`
9798

9899
You can use any pattern, where `*` is wildcard for any characters.
99100

@@ -172,36 +173,21 @@ These names are then used in the output Log:
172173

173174
### Configuration
174175

175-
The following is the default configuration:
176-
177-
```scala
178-
case class SimulationConfig[B](
179-
// define tenant if you have one
180-
tenantId: Option[String] = None,
181-
// the Camunda Port
182-
// there are Requests that wait until the process is ready - like getTask.
183-
// the Simulation waits 1 second between the Requests.
184-
// so with a timeout of 10 sec it will try 10 times (retryDuration = 1.second)
185-
maxCount: Int = 10,
186-
// REST endpoint of Camunda
187-
endpoint: String = "http://localhost:8080/engine-rest",
188-
// you can add authentication with this - default there is none.
189-
// see BasicSimulationDsl / OAuthSimulationDsl for examples
190-
authHeader: B => B = (b: B) => b,
191-
// the maximum LogLevel you want to print the LogEntries.
192-
logLevel: LogLevel = LogLevel.INFO
193-
)
194-
```
176+
The configuration is described in [03-simulation].
195177

196178
You can easily override it in your Simulation:
197179

198180
```scala
199-
override implicit def config =
181+
override implicit def config =
200182
super.config
201-
.withPort(8034)
202183
.withLogLevel(LogLevel.DEBUG)
184+
.withMaxCount(20)
203185
```
204186

187+
Especially interesting on the level of each Simulation are:
188+
- `logLevel` to debug the Simulation.
189+
- `maxCount` to increase the timeout for the interactions (one count is one second).
190+
205191
## Scenarios
206192

207193
The following chapters explain the different scenario types:
@@ -438,7 +424,7 @@ scenario(
438424

439425
### Only a Scenario
440426

441-
You can run only a scenario at the time by just prefix your Scenario with `only`.
427+
You can run only one are a few scenario at the time by just prefix your Scenarios with `only`.
442428

443429
#### Examples:
444430

@@ -455,7 +441,7 @@ simulate(
455441
ApproveInvoiceUT,
456442
PrepareBankTransferUT
457443
),
458-
scenario(InvoiceAssignApproverDMN)
444+
only.scenario(InvoiceAssignApproverDMN)
459445
)
460446
```
461447

@@ -503,31 +489,29 @@ the following possibilities:
503489
@:callout(info)
504490
This only works for one hierarchy of sub processes.
505491
When you have more complex sub processes, you must mock them.
492+
493+
**Not recommended**: please test each process separately.
506494
@:@
507495

508496
## Validation
509497

510498
The simulation uses your BPMN DSL objects not just to run the process and its interactions.
511-
It also uses the the input- and output domain objects to validate variables of the process.
499+
It also uses the input- and output domain objects to validate variables of the process.
512500

513501
```scala
514502
// domain classes
515-
case class InvoiceReceipt(
516-
creditor: String = "Great Pizza for Everyone Inc.",
517-
amount: Double = 300.0,
518-
519-
...
503+
case class In(
504+
creditor: String = "Great Pizza for Everyone Inc.",
505+
amount: Double = 300.0,
506+
//...
520507
)
521-
522-
case class ApproveInvoice(
523-
approved: Boolean = true
524-
)
525-
526-
...
508+
case class Out(
509+
approved: Boolean = true,
510+
//...
511+
)
512+
//...
527513
// bpmn object
528514
process(
529-
id = "example-invoice-c7-review",
530-
descr = "This starts the Review Invoice Process.",
531515
in = InvoiceReceipt(),
532516
out = InvoiceReviewed()
533517
)
@@ -748,6 +732,15 @@ It checks if the state of the process is `COMPLETED`.
748732
It simple tries until there is a User Task in the process available.
749733
If there are more than one, it just takes the first one.
750734

735+
To complete a User Task, you can also wait some seconds.
736+
This is useful, if you want to check if intermediate events were triggered.
737+
```scala
738+
scenario(userTaskExampleProcess)(
739+
userTaskExample
740+
.waitForSec(2) // wait 2 seconds
741+
)
742+
```
743+
751744
#### Receive Message Event
752745

753746
We try to correlate the message until it is successful.
@@ -808,6 +801,8 @@ Mocking is handled directly in the processes itself.
808801
This is especially useful in _Simulations_.
809802

810803
However, you can mock on any environment, like local or production (e.g. with _Postman_).
804+
805+
See also [General Concerns](../generalConcerns.md#mocking).
811806
@:@
812807

813808
### Generic Mocking

00-docs/src/docs/generalConcerns.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ However, it turns out that this is quite helpful:
4646
The mocking is done with General Variables - see also the chapter above.
4747

4848
**The Usage** is described here under [_General Variables_](exampleApi/OpenApi.html)
49+
50+
As **Simulations** use mocking the most, we describe it [there](functionalityDsls/simulation.md#mocking)
51+
in more detail.
4952
@:@
5053

5154
We have four ways to mock. Each possibility is done with a dedicated Process Variable.

03-simulation/src/main/scala/camundala/simulation/custom/SEventExtensions.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ trait SEventExtensions extends SimulationHelper:
7979
else None
8080
val tenant = // only set if there is no processInstanceId
8181
if sEvent.processInstanceId then None
82-
else summon[SimulationConfig[?]].tenantId
82+
else config.tenantId
8383
val body = CorrelateMessageIn(
8484
messageName = event.messageName,
8585
tenantId = tenant,

03-simulation/src/main/scala/camundala/simulation/custom/SScenarioExtensions.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ trait SScenarioExtensions extends SStepExtensions:
6464
val process = scenario.process
6565
val body = CorrelateMessageIn(
6666
messageName = process.processName,
67-
tenantId = summon[SimulationConfig[?]].tenantId,
67+
tenantId = config.tenantId,
6868
businessKey = Some(scenario.name),
6969
processVariables = Some(process.camundaInMap)
7070
).asJson.deepDropNullValues.toString

03-simulation/src/main/scala/camundala/simulation/custom/SimulationHelper.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import scala.util.Try
1111
trait SimulationHelper extends ResultChecker, Logging:
1212

1313
// not possible to override given instance
14-
implicit def config: SimulationConfig[RequestT[Empty, Either[String, String], Any]] =
14+
def config: SimulationConfig[RequestT[Empty, Either[String, String], Any]] =
1515
SimulationConfig[RequestT[Empty, Either[String, String], Any]]()
1616

1717
lazy val backend: SttpBackend[Identity, Any] = HttpClientSyncBackend()

03-simulation/src/main/scala/camundala/simulation/custom/auth.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import sttp.client3.*
66
trait BasicSimulationDsl extends CustomSimulation:
77
def username = "demo"
88
def password = "demo"
9-
override implicit def config: SimulationConfig[RequestT[Empty, Either[String, String], Any]] =
9+
override def config: SimulationConfig[RequestT[Empty, Either[String, String], Any]] =
1010
super.config
1111
.withAuthHeader((r: RequestT[Empty, Either[String, String], Any]) =>
1212
r.auth.basic(username, password)
@@ -21,7 +21,7 @@ trait OAuthSimulationDsl extends CustomSimulation:
2121

2222
def fsso: Fsso
2323

24-
override implicit def config: SimulationConfig[RequestT[Empty, Either[String, String], Any]] =
24+
override def config: SimulationConfig[RequestT[Empty, Either[String, String], Any]] =
2525
super.config
2626
.withAuthHeader((r: RequestT[Empty, Either[String, String], Any]) =>
2727
val token = getToken

04-helper/src/main/scala/camundala/helper/dev/company/CompanyWrapperGenerator.scala

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ case class CompanyWrapperGenerator()(using config: DevConfig):
5757
| lazy val companyProjectVersion = BuildInfo.version
5858
|
5959
|object CompanyApiCreator:
60-
| lazy val apiConfig = ApiConfig(companyId = "$companyName")
60+
| lazy val apiConfig = ApiConfig(companyName = "$companyName")
6161
|""".stripMargin
6262

6363
private lazy val dmnWrapper =
@@ -81,8 +81,10 @@ case class CompanyWrapperGenerator()(using config: DevConfig):
8181
| */
8282
|trait CompanySimulation extends BasicSimulationDsl:
8383
|
84-
| override implicit def config =
84+
| override def config =
8585
| super.config //TODO Adjust config if needed
86+
|
87+
|end CompanySimulation
8688
|""".stripMargin
8789

8890
private lazy val workerWrapper =

05-examples/demos/03-simulation/src/test/scala/camundala/examples/demos/simulation/BasicAuthExampleSimulation.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,6 @@ class BasicAuthExampleSimulation extends BasicSimulationDsl:
1212
DateExampleDMN
1313
)
1414

15-
override implicit def config =
15+
override def config =
1616
super.config.withPort(8033)
1717
end BasicAuthExampleSimulation

0 commit comments

Comments
 (0)