From e0155e03dc1b580e85335d99bd628fa90b937db8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20B=C3=B6hringer?= Date: Mon, 8 Apr 2024 09:05:38 +0200 Subject: [PATCH 01/14] Added learning material from tutorial. Contents not changed yet and still reference tutorial --- .../concepts/bpmn/bpmn-model.md | 4 + .../concepts/bpmn/conditions.md | 12 + .../concepts/bpmn/gateways.md | 20 + .../concepts/bpmn/messaging.md | 33 + .../concepts/bpmn/sequence-flow.md | 3 + .../concepts/bpmn/service-tasks.md | 7 + .../timer-intermediate-catching-events.md | 7 + .../about-version-placeholders-and-urls.md | 54 ++ .../concepts/dsf/bpmn-process-execution.md | 10 + .../concepts/dsf/bpmn-process-variables.md | 9 + .../concepts/dsf/certificates.md | 19 + .../concepts/dsf/draft-task-resources.md | 26 + .../concepts/dsf/environment-variables.md | 14 + ...es-for-requester-and-recipient-elements.md | 247 ++++++ .../concepts/dsf/message-correlation.md | 13 + .../concepts/dsf/message-delegates.md | 24 + .../concepts/dsf/organization-identifiers.md | 15 + .../concepts/dsf/process-api.md | 16 + .../concepts/dsf/read-access-tag.md | 26 + .../concepts/dsf/service-delegates.md | 14 + .../concepts/dsf/spring-integration.md | 15 + .../dsf/the-process-plugin-definition.md | 15 + .../concepts/fhir/activitydefinition.md | 27 + .../concepts/fhir/codesystem.md | 9 + .../concepts/fhir/info.md | 7 + .../concepts/fhir/task.md | 22 + .../concepts/fhir/valueset.md | 7 + .../accessing-bpmn-process-variables.md | 9 + ...cessing-task-resources-during-execution.md | 19 + ...-task-input-parameters-to-task-profiles.md | 236 ++++++ .../guides/configuring-the-read-access-tag.md | 429 ++++++++++ .../guides/creating-an-activity-definition.md | 797 ++++++++++++++++++ .../creating-codesystems-for-dsf-processes.md | 42 + ...ng-task-resources-based-on-a-definition.md | 266 ++++++ .../creating-valuesets-for-dsf-processes.md | 69 ++ ...-incoming-messages-and-missing-messages.md | 19 + .../setting-targets-for-message-events.md | 14 + .../starting-a-process-via-task-resources.md | 68 ++ 38 files changed, 2643 insertions(+) create mode 100644 docs/src/developer-documentation/concepts/bpmn/bpmn-model.md create mode 100644 docs/src/developer-documentation/concepts/bpmn/conditions.md create mode 100644 docs/src/developer-documentation/concepts/bpmn/gateways.md create mode 100644 docs/src/developer-documentation/concepts/bpmn/messaging.md create mode 100644 docs/src/developer-documentation/concepts/bpmn/sequence-flow.md create mode 100644 docs/src/developer-documentation/concepts/bpmn/service-tasks.md create mode 100644 docs/src/developer-documentation/concepts/bpmn/timer-intermediate-catching-events.md create mode 100644 docs/src/developer-documentation/concepts/dsf/about-version-placeholders-and-urls.md create mode 100644 docs/src/developer-documentation/concepts/dsf/bpmn-process-execution.md create mode 100644 docs/src/developer-documentation/concepts/dsf/bpmn-process-variables.md create mode 100644 docs/src/developer-documentation/concepts/dsf/certificates.md create mode 100644 docs/src/developer-documentation/concepts/dsf/draft-task-resources.md create mode 100644 docs/src/developer-documentation/concepts/dsf/environment-variables.md create mode 100644 docs/src/developer-documentation/concepts/dsf/examples-for-requester-and-recipient-elements.md create mode 100644 docs/src/developer-documentation/concepts/dsf/message-correlation.md create mode 100644 docs/src/developer-documentation/concepts/dsf/message-delegates.md create mode 100644 docs/src/developer-documentation/concepts/dsf/organization-identifiers.md create mode 100644 docs/src/developer-documentation/concepts/dsf/process-api.md create mode 100644 docs/src/developer-documentation/concepts/dsf/read-access-tag.md create mode 100644 docs/src/developer-documentation/concepts/dsf/service-delegates.md create mode 100644 docs/src/developer-documentation/concepts/dsf/spring-integration.md create mode 100644 docs/src/developer-documentation/concepts/dsf/the-process-plugin-definition.md create mode 100644 docs/src/developer-documentation/concepts/fhir/activitydefinition.md create mode 100644 docs/src/developer-documentation/concepts/fhir/codesystem.md create mode 100644 docs/src/developer-documentation/concepts/fhir/info.md create mode 100644 docs/src/developer-documentation/concepts/fhir/task.md create mode 100644 docs/src/developer-documentation/concepts/fhir/valueset.md create mode 100644 docs/src/developer-documentation/guides/accessing-bpmn-process-variables.md create mode 100644 docs/src/developer-documentation/guides/accessing-task-resources-during-execution.md create mode 100644 docs/src/developer-documentation/guides/adding-task-input-parameters-to-task-profiles.md create mode 100644 docs/src/developer-documentation/guides/configuring-the-read-access-tag.md create mode 100644 docs/src/developer-documentation/guides/creating-an-activity-definition.md create mode 100644 docs/src/developer-documentation/guides/creating-codesystems-for-dsf-processes.md create mode 100644 docs/src/developer-documentation/guides/creating-task-resources-based-on-a-definition.md create mode 100644 docs/src/developer-documentation/guides/creating-valuesets-for-dsf-processes.md create mode 100644 docs/src/developer-documentation/guides/managing-mutiple-incoming-messages-and-missing-messages.md create mode 100644 docs/src/developer-documentation/guides/setting-targets-for-message-events.md create mode 100644 docs/src/developer-documentation/guides/starting-a-process-via-task-resources.md diff --git a/docs/src/developer-documentation/concepts/bpmn/bpmn-model.md b/docs/src/developer-documentation/concepts/bpmn/bpmn-model.md new file mode 100644 index 000000000..66e2e5314 --- /dev/null +++ b/docs/src/developer-documentation/concepts/bpmn/bpmn-model.md @@ -0,0 +1,4 @@ +## BPMN Model + +The DSF expects BPMN 2.0 for its process execution. This write-up covers the BPMN elements +most commonly used in DSF process plugins. \ No newline at end of file diff --git a/docs/src/developer-documentation/concepts/bpmn/conditions.md b/docs/src/developer-documentation/concepts/bpmn/conditions.md new file mode 100644 index 000000000..c523ee82c --- /dev/null +++ b/docs/src/developer-documentation/concepts/bpmn/conditions.md @@ -0,0 +1,12 @@ +### Conditions + +[Conditions](https://docs.camunda.org/manual/7.20/user-guide/process-engine/expression-language/#conditions) +allow you to change the behaviour of BPMN processes during execution. There are two ways you +are able to add decision logic to Conditions. The [Camunda Modeler](https://camunda.com/download/modeler/) refers to them as `Type`. You can find them in the ``Condition`` tab of +certain BPMN elements. The first one is `Script`. This allows you to add arbitrary complexity +to your decisions logic and is rarely used for process plugins. The more common Type is `Expression`. +Expressions have the following syntax: `${expression}`. For this tutorial, _expression_ will +use a boolean condition like `var == true`. You can learn more advanced features of Expressions [here](https://docs.camunda.org/manual/7.20/user-guide/process-engine/expression-language/). +For this to work during BPMN process execution, the variable you want to use for the boolean +condition must be available in the BPMN process variables before [Sequence Flow](../../concepts/bpmn/sequence-flow.md) +reaches the evaluation of the expression. \ No newline at end of file diff --git a/docs/src/developer-documentation/concepts/bpmn/gateways.md b/docs/src/developer-documentation/concepts/bpmn/gateways.md new file mode 100644 index 000000000..6732c17f7 --- /dev/null +++ b/docs/src/developer-documentation/concepts/bpmn/gateways.md @@ -0,0 +1,20 @@ +### Gateways + +[Gateways](https://docs.camunda.org/manual/7.20/reference/bpmn20/gateways/) allow you to control the [Sequence Flow](../../concepts/bpmn/sequence-flow.md). Different +types of gateways will be useful for different scenarios. + +#### Exclusive Gateways + +[Exclusive Gateways](https://docs.camunda.org/manual/7.20/reference/bpmn20/gateways/exclusive-gateway/) +allow you to decide which [Sequence Flow](../../concepts/bpmn/sequence-flow.md) should be followed based on [conditions](https://docs.camunda.org/manual/7.20/user-guide/process-engine/expression-language/#conditions). +[Conditions](https://docs.camunda.org/manual/7.20/user-guide/process-engine/expression-language/#conditions) are not part of the +[Exclusive Gateways](https://docs.camunda.org/manual/7.20/reference/bpmn20/gateways/exclusive-gateway/) themselves. You set them +through the sequence Flow Exiting the [Exclusive Gateway](https://docs.camunda.org/manual/7.20/reference/bpmn20/gateways/exclusive-gateway/). +In the [Camunda Modeler](https://camunda.com/download/modeler/), you can add conditions to [Sequence Flow](../../concepts/bpmn/sequence-flow.md) by selecting +a [Sequence Flow](../../concepts/bpmn/sequence-flow.md) and opening the `Condition` tab. You can find more information on how to +use Conditions [here](../../concepts/bpmn/conditions.md). + +#### Event-based Gateway + +The [Event-based Gateway](https://docs.camunda.org/manual/7.20/reference/bpmn20/gateways/event-based-gateway/) +allows you model scenarios where you are expecting one out of a number of events to occur. \ No newline at end of file diff --git a/docs/src/developer-documentation/concepts/bpmn/messaging.md b/docs/src/developer-documentation/concepts/bpmn/messaging.md new file mode 100644 index 000000000..d9bb2b812 --- /dev/null +++ b/docs/src/developer-documentation/concepts/bpmn/messaging.md @@ -0,0 +1,33 @@ +### Messaging + +In order to enable communication with other lanes, pools or even entirely separate processes you need to be able +to exchange information. In BPMN, you can use [Message Events](https://docs.camunda.org/manual/7.20/reference/bpmn20/events/message-events/) +to model this information exchange. Modeling communication with [Message Events](https://docs.camunda.org/manual/7.20/reference/bpmn20/events/message-events/) in the same diagram +uses Message Flow. Message Flow is typically represented by a dashed line arrow between BPMN elements with a black (send) or white (receive) envelope icon. +The following BPMN collaboration diagram shows message exchange between two processes. + + + + + BPMN collaboration diagram with two processes using message flow to exchange information between two organizations + + +#### Message Start Event + +[Message Start Events](https://docs.camunda.org/manual/7.20/reference/bpmn20/events/message-events/#message-start-event) +allow a BPMN process to be started by an incoming message. In the DSF, all BPMN processes are started via messages. Therefore, +you will have to include a [Message Start Event](https://docs.camunda.org/manual/7.20/reference/bpmn20/events/message-events/#message-start-event) at +the beginning of all of your BPMN models. + +#### Message Intermediate Throwing Event +[Message Intermediate Throwing Events](https://docs.camunda.org/manual/7.20/reference/bpmn20/events/message-events/#message-intermediate-throwing-event) +are used to send messages during process execution. + +#### Message Intermediate Catching Event +[Message Intermediate Catching Events](https://docs.camunda.org/manual/7.20/reference/bpmn20/events/message-events/#message-intermediate-catching-event) serve as +the counterpart to [Message Intermediate Throwing Events](messaging.md#message-intermediate-throwing-event). +Use them whenever you expect to receive a message from another process or organization during execution. + +#### Message End Event +The [Message End Event](https://docs.camunda.org/manual/7.20/reference/bpmn20/events/message-events/#message-end-event) will +stop the execution of a BPMN process and finish by sending a message. \ No newline at end of file diff --git a/docs/src/developer-documentation/concepts/bpmn/sequence-flow.md b/docs/src/developer-documentation/concepts/bpmn/sequence-flow.md new file mode 100644 index 000000000..ab4c470e9 --- /dev/null +++ b/docs/src/developer-documentation/concepts/bpmn/sequence-flow.md @@ -0,0 +1,3 @@ +### Sequence Flow +BPMN 2.0 calls the continuous arrows connecting the BPMN elements in BPMN models, Sequence Flow. +Sequence Flow exits one BPMN element and points at the next BPMN element to be processed. diff --git a/docs/src/developer-documentation/concepts/bpmn/service-tasks.md b/docs/src/developer-documentation/concepts/bpmn/service-tasks.md new file mode 100644 index 000000000..6e7c9d528 --- /dev/null +++ b/docs/src/developer-documentation/concepts/bpmn/service-tasks.md @@ -0,0 +1,7 @@ +### Service Tasks + +You will primarily use [Service Tasks](https://docs.camunda.org/manual/7.20/reference/bpmn20/tasks/service-task/) +when creating BPMN models. They are different from regular BPMN Tasks in that they offer the ability to +link an implementation to the [Service Task](https://docs.camunda.org/manual/7.20/reference/bpmn20/tasks/service-task/) +which can be called and executed by a BPMN engine. The BPE (Business Process Engine) server of the DSF leverages +this engine to execute your BPMN processes. \ No newline at end of file diff --git a/docs/src/developer-documentation/concepts/bpmn/timer-intermediate-catching-events.md b/docs/src/developer-documentation/concepts/bpmn/timer-intermediate-catching-events.md new file mode 100644 index 000000000..6651f52cb --- /dev/null +++ b/docs/src/developer-documentation/concepts/bpmn/timer-intermediate-catching-events.md @@ -0,0 +1,7 @@ +### Timer Intermediate Catching Events + +A [Timer Intermediate Catching Event](https://docs.camunda.org/manual/7.17/reference/bpmn20/events/timer-events/#timer-intermediate-catching-event) +allows you model stopwatch behavior. A timer is started once the BPMN execution arrives at the event. +The duration until the timer runs out is specified using the [ISO 8601 Durations](http://en.wikipedia.org/wiki/ISO_8601#Durations) format. +Examples can be found [here](https://docs.camunda.org/manual/7.17/reference/bpmn20/events/timer-events/#time-duration). After running out, the BPMN process executes the [Sequence Flow](../../concepts/bpmn/sequence-flow.md) following +the [Timer Intermediate Catching Event](https://docs.camunda.org/manual/7.17/reference/bpmn20/events/timer-events/#timer-intermediate-catching-event). \ No newline at end of file diff --git a/docs/src/developer-documentation/concepts/dsf/about-version-placeholders-and-urls.md b/docs/src/developer-documentation/concepts/dsf/about-version-placeholders-and-urls.md new file mode 100644 index 000000000..218bb9cea --- /dev/null +++ b/docs/src/developer-documentation/concepts/dsf/about-version-placeholders-and-urls.md @@ -0,0 +1,54 @@ +### About Versions, Placeholders and URLs + +#### Version Pattern + +Process plugin versions have to obey the pattern: +``` +\d+\.\d+\.\d+\.\d+ Example: 1.0.1.2 +``` + +The first two numbers (`1.0`) are used in FHIR resources and signal changes which break compatibility with previous +process versions. For example, altering FHIR resources usually results in a breaking change. The latter two (`1.2`) signal changes which do not break compatibility with previous process versions. Specifically, +the 4th number is reserved for bug-fixes and the 3rd number includes all other non-breaking changes. + +#### Placeholders + +To avoid the need to specify the version and release date for each [ActivityDefinition](../../concepts/fhir/activitydefinition.md), [CodeSystem](../../concepts/fhir/codesystem.md), +[Task](../../concepts/fhir/task.md) profile and [ValueSet](../../concepts/fhir/valueset.md) resource, +the placeholders `#{version}` and `#{date}` can be used when creating FHIR resources or even in BPMN models. +They are replaced with the values returned by the methods `ProcessPluginDefinition#getResourceVersion` +and `ProcessPluginDefinition#getReleaseDate` respectively during deployment of a process plugin by the DSF BPE server. +There is also a placeholder for the organization the DSF instance is running in: `#{organization}`. You would typically use +this placeholder in [Draft Task Resources](draft-task-resources.md) but like the other placeholders, it can be used anywhere +as long as the file gets loaded by the [BPE](https://dsf.dev/intro/info/architecture.html#business-process-engine-bpe). + +#### URLs + +BPMN models have an ID we call process definition key. The BPMN process definition key needs to be specified following the pattern: +``` +^[-a-zA-Z0-9]+_[-a-zA-Z0-9]+$ Example: domainorg_processKey +``` +In addition, the BPMN model needs to specify a version. You should be using the ``#{version}`` [placeholder](../../concepts/dsf/about-version-placeholders-and-urls.md#placeholders) +for this as well. The DSF will also reference this process in URL form in FHIR resources: +``` +http://domain.org/bpe/Process/processKey|1.0 +``` + +As you can see, the version in the URL ``|1.0`` only uses the resource version and omits the code base version. +As mentioned in [Version Pattern](about-version-placeholders-and-urls.md#version-pattern), this means that only changes to the first two +version numbers are significant to signal compatibility when communicating with other process plugin instances. +The process definition key and URL are also related to each other. The DSF will try to match BPMN models +to FHIR resources by transforming the URL into a process definition key. That is why it is important you obey +the pattern above. + +You will use the above URL as your instantiatesCanonical value for [Task](../../concepts/fhir/task.md) profile definitions as well as references +to [Task](../../concepts/fhir/task.md) profiles in other resources. +You will also use it as the URL value for your [ActivityDefinitions](../../concepts/fhir/activitydefinition.md). In this case though, you +have to split up the URL into two parts. You will separate the version (``|1.0``) from the URL and use it as a value for the +`ActivityDefinition.version` element. Since it refers to the plugin's resource version, you should also use the `#{version}` +[placeholder](about-version-placeholders-and-urls.md#placeholders) here instead. Going by the example from above, you will be left with a URL that looks +like this: +``` +http://domain.org/bpe/Process/processKey +``` +This will be the value for your `ActivityDefinition.url` element with `#{version}` as the value for your `ActivityDefinition.version` element. \ No newline at end of file diff --git a/docs/src/developer-documentation/concepts/dsf/bpmn-process-execution.md b/docs/src/developer-documentation/concepts/dsf/bpmn-process-execution.md new file mode 100644 index 000000000..18e331962 --- /dev/null +++ b/docs/src/developer-documentation/concepts/dsf/bpmn-process-execution.md @@ -0,0 +1,10 @@ +### BPMN Process Execution + +The BPMN process execution is the in-memory representation of a running BPMN process. BPMN processes have their +executions structured as a tree hierarchy. Each BPMN process +starts with the [process instance](https://docs.camunda.org/manual/7.20/user-guide/process-engine/process-engine-concepts/#process-instances) +as its root level execution. If, for example, this root execution reaches a parallel gateway with two paths, it would spawn two child executions +under itself for them to process all tasks along their paths on their own. +Executions can access all the BPMN elements from the BPMN model as well as the [BPMN process variables](../../concepts/dsf/bpmn-process-variables.md). +You have access to this representation in your Java code when overriding certain methods in [Service](../../concepts/dsf/service-delegates.md) / [Message](../../concepts/dsf/message-delegates.md) Delegates +like `doExecute` or `getAdditionalInputParameters` through the `execution` parameter. \ No newline at end of file diff --git a/docs/src/developer-documentation/concepts/dsf/bpmn-process-variables.md b/docs/src/developer-documentation/concepts/dsf/bpmn-process-variables.md new file mode 100644 index 000000000..3a63ae94d --- /dev/null +++ b/docs/src/developer-documentation/concepts/dsf/bpmn-process-variables.md @@ -0,0 +1,9 @@ +### BPMN Process Variables + +BPMN process variables hold additional information which has to be available during BPMN process execution. +Variables can be directly related to BPMN elements like the boolean value for [Conditions](../../concepts/bpmn/conditions.md), but +do not have to be. BPMN process variables are stored as key-value pairs with the key being the variable name. +They are accessible during the entirety of the execution to all [Service](../../concepts/dsf/service-delegates.md) / +[Message](../../concepts/dsf/message-delegates.md) Delegates. + +You can learn how to access to the BPMN process variables [here](../../guides/accessing-bpmn-process-variables.md). \ No newline at end of file diff --git a/docs/src/developer-documentation/concepts/dsf/certificates.md b/docs/src/developer-documentation/concepts/dsf/certificates.md new file mode 100644 index 000000000..28591b8a2 --- /dev/null +++ b/docs/src/developer-documentation/concepts/dsf/certificates.md @@ -0,0 +1,19 @@ +### Certificates + +There is a number of certificates that need to be generated in order for DSF instances to communicate with each other securely. +You can find a comprehensive lists of certificates needed by the [DSF FHIR](https://dsf.dev/stable/maintain/fhir/configuration.html) +and [DSF BPE](https://dsf.dev/stable/maintain/bpe/configuration.html) servers on the DSF website. +Certificates will be created by the `test-data-generator` project through Maven by the time of the `package` phase in your process plugin build. +You can also invoke the generation of certificates separately by running the Maven build of `test-data-generator` until (and including) the `package` phase. +Since this tutorial comes with three preconfigured DSF instances, the only time you will need to interact with certificates +is when you want to make requests to the DSF FHIR server. Either for access to the web frontend under https://instance-host-name/fhir/, +or when [starting your process plugin](../../guides/starting-a-process-via-task-resources.md). +In case of the web frontend, you will need to add the CA certificate and client certificate of the DSF instance you want to access to your browser. +Certificates can be found in `test-data-generator/cert`. + +**Example:** +You want to access the `dic` DSF FHIR server. You add the CA certificate located in `test-data-generator/cert/ca` to your +browser's certificate store. You also add the client certificate for `dic` located in `test-data-generator/cert/dic-client` +to your browser's client certificates. + +**Important: Passwords for .p12 files are always "password"** diff --git a/docs/src/developer-documentation/concepts/dsf/draft-task-resources.md b/docs/src/developer-documentation/concepts/dsf/draft-task-resources.md new file mode 100644 index 000000000..6c412ddd5 --- /dev/null +++ b/docs/src/developer-documentation/concepts/dsf/draft-task-resources.md @@ -0,0 +1,26 @@ +### Draft Task Resources + +[Task](../../concepts/fhir/task.md) resources with status `draft` are used to create the DSF FHIR server's functionality +of starting processes via its web interface. They are stored in `.../tutorial-process/src/main/resources/fhir/Task`. +Compared to regular [Task](../../concepts/fhir/task.md) resources used to +start BPMN processes, this type of [Task](../../concepts/fhir/task.md) resource requires the status `draft` instead the usual `requested`. +It also replaces the value for `authoredOn` with the placeholder `#{date}`, the values of organization +identifiers with the placeholder `#{organization}` and all instances of version numbers with `#{version}`. +Additionally, it requires setting the `Task.identifier` +element. It should look something like this: + +```xml + + + + +``` +`processKey` should be the same one used in [URLs](../../concepts/dsf/about-version-placeholders-and-urls.md#urls). +`task-name` can be any String you wish to identify this task with. E.g. you can use the file name of the Draft Task. + +For a complete example you can take a look at the Draft Task Resource in one of the solution branches +and compare it to the one needed for cURL. The [Task](../../concepts/fhir/task.md) resource created +for cURL can be found at `.../tutorial-process/src/main/resources/example-task.xml`. + +You might also want to check out [this guide](../../guides/creating-task-resources-based-on-a-definition.md) +if you do not know how to create [Task](../../concepts/fhir/task.md) resources in general. \ No newline at end of file diff --git a/docs/src/developer-documentation/concepts/dsf/environment-variables.md b/docs/src/developer-documentation/concepts/dsf/environment-variables.md new file mode 100644 index 000000000..a5208920a --- /dev/null +++ b/docs/src/developer-documentation/concepts/dsf/environment-variables.md @@ -0,0 +1,14 @@ +### Environment Variables + +Environment variables offer a way to make configuration data available at the start of a [BPMN process execution](../../concepts/dsf/bpmn-process-execution.md). +They are the same for all running process instances. They can be defined by adding a member variable with +the [Spring-Framework @Value](https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#beans-value-annotations) annotation to the configuration class `TutorialConfig`. The value of the annotation uses +the `${..}` notation and follows the form `${some.property:defaultValue}`, where each dot in the property name corresponds +to an underscore in the equivalent environment variable. Environment variables are always written upper-case. +The property `some.property` therefore corresponds to the environment variable `SOME_PROPERTY`. + +The DSF provides a feature to automatically generate documentation of environment variables during the Maven build process. +You can use the `@ProcessDocumentation` annotation to automatically generate Markdown documentation for all fields with this annotation. +You simply have to add [dsf-tools-documentation-generator](https://mvnrepository.com/artifact/dev.dsf/dsf-tools-documentation-generator) as a maven plugin. +You can take a look at the `pom.xml` for the `tutorial-process` submodule to see how you can add it to your own project. +Keep in mind to point the `` field to the package you want documentation for. \ No newline at end of file diff --git a/docs/src/developer-documentation/concepts/dsf/examples-for-requester-and-recipient-elements.md b/docs/src/developer-documentation/concepts/dsf/examples-for-requester-and-recipient-elements.md new file mode 100644 index 000000000..51dbdff1b --- /dev/null +++ b/docs/src/developer-documentation/concepts/dsf/examples-for-requester-and-recipient-elements.md @@ -0,0 +1,247 @@ +### Examples for Requester and Recipient Elements + +Below you will find a set of examples for each Coding used by `requester` and `recipient` elements from +the [dsf-extension-process-authorization](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-extension-process-authorization-1.0.0.xml). CodeSystems referenced in the examples can be found [here](https://github.com/datasharingframework/dsf/tree/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/CodeSystem). +Use this collection as a reference point when creating your own [ActivityDefinitions](../../concepts/fhir/activitydefinition.md). + +#### Requester +The `requester` element uses one of the following Codings: +```xml + + + + + + + + + +``` + +##### Local All +```xml + + + + + + +``` + +##### Local All Practitioner +```xml + + + + + + + + + + + + +``` + +##### Local Organization +```xml + + + + + + + + + + + + +``` + +##### Local Organization Practitioner +```xml + + + + + + + + + + + + + + + + + + + + +``` + +##### Local Parent Organization Role +```xml + + + + + + + + + + + + + + + + + + + + +``` + +##### Local Parent Organization Role Practitioner +```xml + + + + + + + + + + + + + + + + + + + + + + + + + + +``` + +##### Remote All +```xml + + + + + + +``` + +##### Remote Organization +```xml + + + + + + + + + + + + +``` + +##### Remote Parent Organization Role +```xml + + + + + + + + + + + + + + + + + + + + +``` + +#### Recipient +The `recipeint` element uses one of the following Codings: +```xml + + + +``` + +##### Local All +```xml + + + + + + +``` + +##### Local Organization +```xml + + + + + + + + + + + + +``` + +##### Local Parent Organization Role +```xml + + + + + + + + + + + + + + + + + + + + +``` diff --git a/docs/src/developer-documentation/concepts/dsf/message-correlation.md b/docs/src/developer-documentation/concepts/dsf/message-correlation.md new file mode 100644 index 000000000..45610c5f2 --- /dev/null +++ b/docs/src/developer-documentation/concepts/dsf/message-correlation.md @@ -0,0 +1,13 @@ +### Message Correlation + +In order for messages to be able to be sent back and forth between organizations with potentially multiple of the +same process plugin instances running at the same time and still arriving at the correct process instance, +we need some mechanism to map messages to their rightful process instance. +This mechanism is called Message Correlation and requires attaching a unique identifier to every process instance. +This identifier is called the `business-key`. The `business-key` will get attached to every outgoing message automatically. + +It is possible that the `business-key` is insufficient to map messages to the correct process instance. This happens +when you use subprocesses in your BPMN model which all expect messages to be sent to them, not the parent process. +To solve this issue, [Task](../../concepts/fhir/task.md) resources also come with an [Input Parameter](../../concepts/fhir/task.md#task-input-parameters) called `correlation-key`. +This is a secondary identifier you can attach to all messages if you need them to arrive at a specific subprocess. +You can learn more about how `correlation-keys` are used by studying the [Ping-Pong Process](https://github.com/datasharingframework/dsf-process-ping-pong). \ No newline at end of file diff --git a/docs/src/developer-documentation/concepts/dsf/message-delegates.md b/docs/src/developer-documentation/concepts/dsf/message-delegates.md new file mode 100644 index 000000000..621f3d688 --- /dev/null +++ b/docs/src/developer-documentation/concepts/dsf/message-delegates.md @@ -0,0 +1,24 @@ +### Message Delegates + +Message Delegates are the Java representation of the [Message Events](../../concepts/bpmn/messaging.md) in your BPMN model. +You link a Message Delegate to a certain [Message Event](../../concepts/bpmn/messaging.md) by selecting the Message Event +in the [Camunda Modeler](https://camunda.com/download/modeler/) and adding a Java class to the `Implementation` field. +Make sure you use the fully qualified class name. Like this: +``` +org.package.myClass +``` + +You will only need Message Delegates for [Message Send Events](../../concepts/bpmn/messaging.md). Incoming messages will +be resolved to the correct [BPMN process execution](../../concepts/dsf/bpmn-process-execution.md) automatically using [Message Correlation](../../concepts/dsf/message-correlation.md) +and the message inputs will be added to that execution's [process variables](../../concepts/dsf/bpmn-process-variables.md). + +To make a Message Delegate for [Message Send Events](../../concepts/bpmn/messaging.md), your Java class needs to extend +`AbstractTaskMessageSend`. Most of the time, you will not be adding any processing logic to your Message Delegates, therefore you usually won't be overwriting +the `doExecute` method like with [Service Delegates](../../concepts/dsf/service-delegates.md). Instead, you most likely want to +aggregate the information you processed in earlier steps and attach it to a message. For this you need to overwrite the +`getAdditionalInputParamters` method. The DSF translates BPMN messages +into FHIR [Task](../../concepts/fhir/task.md) resources to execute the communication modeled by your BPMN diagrams. The information +you are sending to another BPMN process is specified in the Task.input elements a.k.a. [Input Parameters](../../concepts/fhir/task.md#task-input-parameters), +hence the name of the method. +The constructor of your delegate class should also forward a `ProcessPluginApi` instance to its superclass constructor. +You can learn more about the `ProcessPluginApi` [here](../../concepts/dsf/process-api.md). diff --git a/docs/src/developer-documentation/concepts/dsf/organization-identifiers.md b/docs/src/developer-documentation/concepts/dsf/organization-identifiers.md new file mode 100644 index 000000000..6576882d6 --- /dev/null +++ b/docs/src/developer-documentation/concepts/dsf/organization-identifiers.md @@ -0,0 +1,15 @@ +### Organization Identifiers +DSF FHIR server instances always have something called an `organization identifer`. It uniquely identifies +the organization the DSF FHIR server instance belongs to for its [Allow-List mechanism](https://dsf.dev/intro/info/allowList.html). +It is configured as an [environment variable](https://dsf.dev/stable/maintain/fhir/configuration.html#dev-dsf-fhir-server-organization-identifier-value). +You can make a GET request to `https://domain/fhir/Organization` to get a list of all organizations for the DSF FHIR server +instance running under `domain`. The results will also include the `organization identifier` of each organization. + +#### Organization Identifiers in Task Resources +[Task](../../concepts/fhir/task.md) resources require you to reference an organization via its identifier as +the `Task.requester` and `Task.restriction.recipient` elements. The exact values for these elements +depend on the [ActivityDefinition](../../concepts/fhir/activitydefinition.md) the [Task](../../concepts/fhir/task.md) resource +should conform to. +As a general rule, you will want to put the identifier of your own organization as the `Task.requester` and `Task.restriction.recipient` elements +for [Task](../../concepts/fhir/task.md) resources which initially start processes. All other cases depend on the context of +the message being sent during process execution. \ No newline at end of file diff --git a/docs/src/developer-documentation/concepts/dsf/process-api.md b/docs/src/developer-documentation/concepts/dsf/process-api.md new file mode 100644 index 000000000..bc50946f4 --- /dev/null +++ b/docs/src/developer-documentation/concepts/dsf/process-api.md @@ -0,0 +1,16 @@ +### DSF Process API Package + +The [DSF Process API package](https://mvnrepository.com/artifact/dev.dsf/dsf-bpe-process-api-v1) consists of a set of utility classes designed to provide easy access to solutions for process plugin use cases. +This includes for example the `Variables` class, which provides access to the [BPMN process variables](../../concepts/dsf/bpmn-process-variables.md). + +#### Process Plugin Api +When creating [Service Delegates](../../concepts/dsf/service-delegates.md) or [Message Delegates](../../concepts/dsf/message-delegates.md) you will +notice that you need to provide a constructor which expects a `ProcessPluginApi` object and forward it to the superclasses' constructor. +This API instance provides a variety of utility classes: +- `ProxyConfig`**:** forward proxy configuration +- `EndpointProvider`**:** access to Endpoint resources +- `FhirContext`**:** HAPI FHIR Context for parsing/serializing +- `FhirWebserviceClientProvider`**:** Webservice client to access DSF FHIR server +- `MailService`**:** for sending automatic E-Mails (if configured) +- `OrganizationProvider`**:** access to Organization resources +- `Variables`**:** access to BPMN execution variables \ No newline at end of file diff --git a/docs/src/developer-documentation/concepts/dsf/read-access-tag.md b/docs/src/developer-documentation/concepts/dsf/read-access-tag.md new file mode 100644 index 000000000..9cc75a2f7 --- /dev/null +++ b/docs/src/developer-documentation/concepts/dsf/read-access-tag.md @@ -0,0 +1,26 @@ +### Read Access Tag + +Axiomatically, nobody is allowed to write FHIR resources (except [Task](../../concepts/fhir/task.md)) to the DSF FHIR server +unless it is your own organization. By default, the same applies to reading FHIR resources +(again except [Task](../../concepts/fhir/task.md)). But since the DSF is often used to offer medical data in form of +FHIR resources, you will find yourself wanting other organizations to be allowed to read the resources you are offering. +The `Resource.meta.tag` element is used define access rules for all FHIR resources in the DSF, with the +exception of [Task](../../concepts/fhir/task.md) resources. We will explain the reason for this exception shortly. +For example, allowing read access for all organizations, you would use the following `system` and `code` in your FHIR resource: + +```xml + + + + + + +``` +You can find all codes for the Read Access Tag in its [CodeSystem](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/CodeSystem/dsf-read-access-tag-1.0.0.xml). + +The read access rules for [Task](../../concepts/fhir/task.md) resources are defined through the `requester` and `recipient` elements of the [dsf-extension-process-authorization](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-extension-process-authorization-1.0.0.xml) in your plugin's +[ActivityDefinitions](../../concepts/fhir/activitydefinition.md). Therefore, no `read-access-tag` is needed. + +It is also possible to restrict read access of FHIR resources to organizations with +a specific role in a parent organization or a specific identifier. +If you want to find out more, you may look at the [guide on configuring the Read Access Tag](../../guides/configuring-the-read-access-tag.md). diff --git a/docs/src/developer-documentation/concepts/dsf/service-delegates.md b/docs/src/developer-documentation/concepts/dsf/service-delegates.md new file mode 100644 index 000000000..4eb2645fb --- /dev/null +++ b/docs/src/developer-documentation/concepts/dsf/service-delegates.md @@ -0,0 +1,14 @@ +### Service Delegates + +Service Delegates are the Java representation of the [Service Tasks](../../concepts/bpmn/service-tasks.md) in your BPMN model. +You link a Service Delegate to a certain [Service Task](../../concepts/bpmn/service-tasks.md) by selecting the [Service Task](../../concepts/bpmn/service-tasks.md) +in the [Camunda Modeler](https://camunda.com/download/modeler/) and adding a Java class to the `Implementation` field. +Make sure you use the fully qualified class name. Like this: +``` +org.package.myClass +``` +All that is left is for your Java class to extend `AbstractServiceDelegate` and override the `doExecute` method. +This is the place where you can put your actual business logic. The method will be called when the [BPMN process execution](../../concepts/dsf/bpmn-process-execution.md) +arrives at the [Service Task](../../concepts/bpmn/service-tasks.md) your Service Delegate is linked to. +The constructor of your delegate class should also forward a `ProcessPluginApi` instance to its superclass constructor. +You can learn more about the `ProcessPluginApi` [here](../../concepts/dsf/process-api.md). \ No newline at end of file diff --git a/docs/src/developer-documentation/concepts/dsf/spring-integration.md b/docs/src/developer-documentation/concepts/dsf/spring-integration.md new file mode 100644 index 000000000..8aacf65ab --- /dev/null +++ b/docs/src/developer-documentation/concepts/dsf/spring-integration.md @@ -0,0 +1,15 @@ +### Spring Integration + +Since the DSF also employs the use of the [Spring Framework](https://spring.io/projects/spring-framework) you will also +have to provide some Spring functionality. +When deployed, every process plugin exists in its own [Spring context](https://docs.spring.io/spring-framework/reference/core/beans/introduction.html). To make the process plugin work, you +have to provide [Spring Beans](https://docs.spring.io/spring-framework/reference/core/beans/definition.html) with `prototype` [scope](https://docs.spring.io/spring-framework/reference/core/beans/factory-scopes.html) for all classes which either extend or implement the following classes/interfaces (as of version 1.4.0): +- `AbstractTaskMessageSend` +- `AbstractServiceDelegate` +- `DefaultUserTaskListener` +- `ProcessPluginDeploymentStateListener` + +A [Spring-Framework configuration class](https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#beans-java-basic-concepts) located in `spring/config` is expected to provide the Spring Beans. +For this tutorial, the `TutorialConfig` class will take this role. +If you are unfamiliar with the Spring Framework, you might want to check out the chapter [Java-based Container Configuration](https://docs.spring.io/spring-framework/reference/core/beans/java.html) +of the Spring Framework documentation, specifically the topics [Using the @Bean Annotation](https://docs.spring.io/spring-framework/reference/core/beans/java/bean-annotation.html) and [Using the @Configuration Annotation](https://docs.spring.io/spring-framework/reference/core/beans/java/configuration-annotation.html). \ No newline at end of file diff --git a/docs/src/developer-documentation/concepts/dsf/the-process-plugin-definition.md b/docs/src/developer-documentation/concepts/dsf/the-process-plugin-definition.md new file mode 100644 index 000000000..d3e05595a --- /dev/null +++ b/docs/src/developer-documentation/concepts/dsf/the-process-plugin-definition.md @@ -0,0 +1,15 @@ +### The Process Plugin Definition + +In order for the DSF BPE server to load your plugin you need to provide it with the following information: +* A plugin [version](../../concepts/dsf/about-version-placeholders-and-urls.md#version-pattern) +* A release date +* A plugin name +* The BPMN model files +* The FHIR resources grouped by BPMN process ID. Your plugin may have any number of BPMN models. Each has their own BPMN process ID and FHIR resources specific to that BPMN process (think [Task](../../concepts/fhir/task.md) resources needed for messages specific to that BPMN model) +* The Class holding your [Spring Configuration](../../concepts/dsf/spring-integration.md) + +You will provide this information by implementing the `dev.dsf.bpe.ProcessPluginDefinition` interface. +The DSF BPE server then searches for classes implementing this interface using the +Java [ServiceLoader](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/ServiceLoader.html) mechanism. Therefore, you will have to register your interface implementation in the `src/main/resources/META-INF/services/dev.dsf.bpe.ProcessPluginDefinition` file. +For this tutorial, the class implementing the `ProcessPluginDefinition` interface, `TutorialProcessPluginDefinition`, +has already been added to the file. You can use it as a reference for later when you want to create your own plugin. \ No newline at end of file diff --git a/docs/src/developer-documentation/concepts/fhir/activitydefinition.md b/docs/src/developer-documentation/concepts/fhir/activitydefinition.md new file mode 100644 index 000000000..1ebc78282 --- /dev/null +++ b/docs/src/developer-documentation/concepts/fhir/activitydefinition.md @@ -0,0 +1,27 @@ +### ActivityDefinition + +[ActivityDefinitions](http://hl7.org/fhir/R4/activitydefinition.html) are used by the DSF to advertise which processes are +available at any given instance and who is allowed to request and who is allowed to execute a process. The DSF defined elements +for this purpose in the [dsf-activity-definition](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-activity-definition-1.0.0.xml) profile. + + +The most important elements in ActivityDefinitions are: +- `message-name` +- `task-profile` +- `requester` +- `recipient` + +The `message-name` element contains the name of the [BPMN message start event](../../concepts/bpmn/messaging.md#message-start-event) or +[BPMN message intermediate catching event](../../concepts/bpmn/messaging.md#message-intermediate-catching-event) which expects +a [Task](../../concepts/fhir/task.md) resource complying to the profile defined by `task-profile`. + +The `requester` and `recipient` elements define the organisation(s) or person(s) who are allowed to request or receive the message +specified by `message-name`. The receiving DSF instance is the one who will execute the process connected to the message. + +You will have to create your own [ActivityDefinitions](../../concepts/fhir/activitydefinition.md) when developing a process plugin. +If you are fluent in reading XML FHIR definitions and translating them into XML resources, you can take a look at the +DSF's profile for ActivityDefinitions [here](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-activity-definition-1.0.0.xml). +ActivityDefinitions also reference other resource definitions. Depending on the resource, you will find them in one of [these folders](https://github.com/datasharingframework/dsf/tree/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir). +If you are not as comfortable with these requirements you might want to check out the guide on [creating ActivityDefinitions](../../guides/creating-an-activity-definition.md). + +You can also find examples for all possible `requester` and `recipient` elements [here](../../concepts/dsf/examples-for-requester-and-recipient-elements.md). \ No newline at end of file diff --git a/docs/src/developer-documentation/concepts/fhir/codesystem.md b/docs/src/developer-documentation/concepts/fhir/codesystem.md new file mode 100644 index 000000000..f9418e37f --- /dev/null +++ b/docs/src/developer-documentation/concepts/fhir/codesystem.md @@ -0,0 +1,9 @@ +### CodeSystem + +[CodeSystems](https://www.hl7.org/fhir/R4/codesystem.html) usually represent a set of concepts which +can be assigned to a code (think LOINC). If you want to use a Code in a resource, you will usually include them in a +[ValueSet](../../concepts/fhir/valueset.md). + +Plugin development for the DSF requires the use of [CodeSystems](https://www.hl7.org/fhir/R4/codesystem.html) in two major ways: +1. Using existing [DSF CodeSystems](https://github.com/datasharingframework/dsf/tree/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/CodeSystem) in other FHIR resources like the [dsf-extension-process-authorization](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-extension-process-authorization-1.0.0.xml). +2. Creating your own CodeSystem to add additional [Input Parameters](../../concepts/fhir/task.md#task-input-parameters) to your [Task](../../concepts/fhir/task.md) profiles. \ No newline at end of file diff --git a/docs/src/developer-documentation/concepts/fhir/info.md b/docs/src/developer-documentation/concepts/fhir/info.md new file mode 100644 index 000000000..de33a5d62 --- /dev/null +++ b/docs/src/developer-documentation/concepts/fhir/info.md @@ -0,0 +1,7 @@ +## FHIR + +The DSF uses a variety of [FHIR resources](https://dsf.dev/intro/info/basics.html#why-are-we-using-fhir-and-bpmn). The DSF uses XML as the format for FHIR resources. +The most important resources for plugin development are [ActivityDefinitions](../../concepts/fhir/activitydefinition.md), [Tasks](../../concepts/fhir/task.md), +[CodeSystems](../../concepts/fhir/codesystem.md) and [ValueSets](../../concepts/fhir/valueset.md). +There is also a catalogue of DSF-specific FHIR resources including CodeSystems, ValueSets and Extensions. For now, you can find them in the official +DSF GitHub repository [here](https://github.com/datasharingframework/dsf/tree/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir). diff --git a/docs/src/developer-documentation/concepts/fhir/task.md b/docs/src/developer-documentation/concepts/fhir/task.md new file mode 100644 index 000000000..484b46ba2 --- /dev/null +++ b/docs/src/developer-documentation/concepts/fhir/task.md @@ -0,0 +1,22 @@ +### Task + +The [FHIR Task](https://www.hl7.org/fhir/R4/task.html) resource enables the DSF's distributed communication. +Whenever a BPMN process instance communicates with a different process instance, the DSF will create a Task resource +based on parameters you set in the BPMN model and during execution. It will then +automatically send the Task resource to the recipient to start or continue whatever process the Task resource referred to. +All Task resources used in the DSF derive from the [dsf-task-base](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-task-base-1.0.0.xml). +This profile includes a splicing for `Task.input` with three additional [Input Parameters](../../concepts/fhir/task.md#task-input-parameters): +- `message-name` +- `business-key` +- `correlation-key` + +When creating your own plugin, you will want to create your own profiles based on the [dsf-task-base](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-task-base-1.0.0.xml). + +#### Task Input Parameters + +Task Input Parameters allow you to add additional information to [Task](task.md#task) resources. +For example, if your particular data exchange requires additional medical data, you would add a slice to your Task profile in the same +way the [dsf-task-base](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-task-base-1.0.0.xml) adds slices to the original [FHIR Task](https://www.hl7.org/fhir/R4/task.html) resource. Notice that this also requires creating a [CodeSystem](../../concepts/fhir/codesystem.md) and +including it in a [ValueSet](../../concepts/fhir/valueset.md) to be able to use it in the Task resource. + +If these instructions are insufficient you can check out the guide on [how to add Task Input Parameters](../../guides/adding-task-input-parameters-to-task-profiles.md). \ No newline at end of file diff --git a/docs/src/developer-documentation/concepts/fhir/valueset.md b/docs/src/developer-documentation/concepts/fhir/valueset.md new file mode 100644 index 000000000..807de4324 --- /dev/null +++ b/docs/src/developer-documentation/concepts/fhir/valueset.md @@ -0,0 +1,7 @@ +### ValueSet + +[ValueSets](https://www.hl7.org/fhir/R4/valueset.html) bind codes from [CodeSystems](../../concepts/fhir/codesystem.md) to coded elements like +`code`, `Coding` or `CodeableConcept`. + +[ValueSets](https://www.hl7.org/fhir/R4/valueset.html) are mostly needed to use the [Concepts](https://www.hl7.org/fhir/R4/codesystem-definitions.html#CodeSystem.concept) from [CodeSystems](../../concepts/fhir/codesystem.md) +in your [Task](../../concepts/fhir/task.md) profiles. \ No newline at end of file diff --git a/docs/src/developer-documentation/guides/accessing-bpmn-process-variables.md b/docs/src/developer-documentation/guides/accessing-bpmn-process-variables.md new file mode 100644 index 000000000..0177613ee --- /dev/null +++ b/docs/src/developer-documentation/guides/accessing-bpmn-process-variables.md @@ -0,0 +1,9 @@ +### Accessing BPMN Process Variables + +After creating a [Service Delegate](../concepts/dsf/service-delegates.md) or [Message Delegate](../concepts/dsf/message-delegates.md), you might want to +retrieve data from or store data in the [BPMN process variables](../concepts/dsf/bpmn-process-variables.md). +You can achieve this either through the [BPMN process execution](../concepts/dsf/bpmn-process-execution.md) or via the `Variables` class. +*It is very much recommended you use the latter method*. +The `Variables` class provides lots of utility methods to read or write certain types +of [BPMN process variables](../concepts/dsf/bpmn-process-variables.md). If for some reason you need to fall back on the [BPMN process execution](../concepts/dsf/bpmn-process-execution.md) +to solve your problem, we would like to learn how the current API of the `Variables` class is limiting you. Contact us, and we might turn it into a feature request ([Contribute](https://dsf.dev/stable/contribute)). diff --git a/docs/src/developer-documentation/guides/accessing-task-resources-during-execution.md b/docs/src/developer-documentation/guides/accessing-task-resources-during-execution.md new file mode 100644 index 000000000..1b1bf4ce6 --- /dev/null +++ b/docs/src/developer-documentation/guides/accessing-task-resources-during-execution.md @@ -0,0 +1,19 @@ +### Accessing Task Resources During Execution + +If you want access to the [Task](../concepts/fhir/task.md) resources in your [Service](../concepts/dsf/service-delegates.md) / [Message](../concepts/dsf/message-delegates.md) Delegates, the `Variables` class will +provide methods which return certain kinds of [Task](../concepts/fhir/task.md) resources. The most commonly used ones are +the start [Task](../concepts/fhir/task.md), referring to the [Task](../concepts/fhir/task.md) / [Message Start Event](../concepts/bpmn/messaging.md#message-start-event) responsible for starting the process, +and the latest [Task](../concepts/fhir/task.md), referring to most recently received [Task](../concepts/fhir/task.md) / Message. +In principle, this is sufficient to access all information in a [Task](basic-concepts-and-guides.md#task) resource, since you have +the [Task](../concepts/fhir/task.md) resource's Java object, but very cumbersome. +Instead of navigating the [Task](../concepts/fhir/task.md) resource's element tree, +you should first try to use the [ProcessPluginApi's](../concepts/dsf/process-api.md) `TaskHelper` in conjunction with the method above. The `TaskHelper` class +offers specific methods related to [Task](../concepts/fhir/task.md) resources. +The most common use case for this is retrieving data from a [Task's](../concepts/fhir/task.md) [Input Parameter](../concepts/fhir/task.md#task-input-parameters) or creating a new [Input Parameter](../concepts/fhir/task.md#task-input-parameters) +for a [Message Delegate's](../concepts/dsf/message-delegates.md) `getAdditionalInputParameters` method. +When retrieving data from a [Task's](../concepts/fhir/task.md) Input Parameter you first have to get to the [Input Parameter](../concepts/fhir/task.md#task-input-parameters) you are looking to extract +data from. You can use one of the `TaskHelper's` getters for [Input Parameters](../concepts/fhir/task.md#task-input-parameters) to find the right one. The methods will try to match +the provided [CodeSystem](../concepts/fhir/codesystem.md) and Code to any [Input Parameter](../concepts/fhir/task.md#task-input-parameters) of the provided [Task](../concepts/fhir/task.md) resource. +Depending on the method you chose you will for example receive all matches or just the first one. +To create new [Input Parameters](../concepts/fhir/task.md#task-input-parameters) to attach to a [Task](../concepts/fhir/task.md) resource, you may invoke the `TaskHelper#createInput` method. This +is most often used when overriding the `getAdditionalInputParamters` method of you [Message Delegate](../concepts/dsf/message-delegates.md). \ No newline at end of file diff --git a/docs/src/developer-documentation/guides/adding-task-input-parameters-to-task-profiles.md b/docs/src/developer-documentation/guides/adding-task-input-parameters-to-task-profiles.md new file mode 100644 index 000000000..8c64cc47b --- /dev/null +++ b/docs/src/developer-documentation/guides/adding-task-input-parameters-to-task-profiles.md @@ -0,0 +1,236 @@ +### Adding Task Input Parameters to Task Profiles + +When adding a new [Input Parameter](../concepts/fhir/task.md#task-input-parameters) to a [Task](../concepts/fhir/task.md) +profile, you are essentially adding a new slice to `Task.input`. [Slicing](https://www.hl7.org/fhir/R4/profiling.html#slicing) is part +of [profiling](https://www.hl7.org/fhir/R4/profiling.html) in FHIR. Profiling lets you create your own +FHIR definitions based on pre-existing FHIR definitions. A slicing defines constraints on element lists +like `Task.input` e.g. by only allowing the elements to be of certain types. For example, you +might have a list of fruits in a `FruitBasket` resource. Constraining that list to only include +fruits of type `Apple`, `Banana` and `Orange` would be considered [slicing](https://www.hl7.org/fhir/R4/profiling.html#slicing). +This guide will not cover how slicing works in general, only for the case presented by the DSF FHIR resource +context. Our goal will be to add a new [Input Parameter](../concepts/fhir/task.md#task-input-parameters) +of type `example-input` to the `task-start-dic-process.xml` profile which will be used to submit `integer` values to our `dicProcess`. + +Let us start out by adding a slice to `task-start-dic-process.xml`. Since there is already a slicing defined +on `Task.input` by `task-start-dic-process.xml`'s `baseDefinition`, we have to check out this resource first. +As a part of the [differential](https://www.hl7.org/fhir/R4/profiling.html#snapshot) statement, slicing also uses [Element Definitions](https://www.hl7.org/fhir/R4/elementdefinition.html). +The slicing for `Task.input` is defined in this part of the `baseDefinition`: +```xml + + + + + + + + + + + + + + + + + + +``` +*The resource can be found [here](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-task-base-1.0.0.xml)* + +We will only need to take a look at the `discrimitator` tag for now. +Discriminators define the elements a FHIR processor needs to distinguish slices by. In our case, a processor +would look at the values for `type.coding.system` and `type.coding.code` to determine which +slice this element belongs to. The discriminator type `value` implies that `type.coding.system` and `type.coding.code` +have to be present in all slices and need to have a fixed value. +You can learn more about discriminators [here](https://www.hl7.org/fhir/R4/profiling.html#discriminator). + +Let us revisit `task-start-dic-process.xml` and start adding a slice called `example-input` to it: +```xml + + ... + + ... + + + + + + + + +``` +*Unnecessary elements for this guide are hidden by ... placeholders.* + +We have now defined a slice on `Task.input` with the name and id of `example-input` and cardinality of `1..1`. You might +want a different cardinality for your use case. We recommend you also take a look at the documentation for [ElementDefinition.id](https://www.hl7.org/fhir/R4/elementdefinition.html#id) +and [ElementDefinition.path](https://www.hl7.org/fhir/R4/elementdefinition.html#path). They explain how to create the proper +values for these elements. Cardinality is also part of the [element definition](https://www.hl7.org/fhir/R4/elementdefinition.html) +hierarchy (see [ElementDefinition.min](https://www.hl7.org/fhir/R4/elementdefinition-definitions.html#ElementDefinition.min) and [ElementDefinition.max](https://www.hl7.org/fhir/R4/elementdefinition-definitions.html#ElementDefinition.max)). + +Next up, we need to define the binding for `Task.input:example-input.type`. Because `Task.input.type` +is a `CodeableConcept` which uses codings from a [ValueSet](../concepts/fhir/valueset.md), +the [discriminator](https://www.hl7.org/fhir/R4/profiling.html#discriminator) requires us to use `required` as the binding strength: +```xml + + ... + + ... + + + + + + + + + + + + + + + +``` +As you can see, we referenced a [ValueSet](../concepts/fhir/valueset.md) in this binding. +When adding an actual slice for your use case, you will have to reference an existing [ValueSet](../concepts/fhir/valueset.md) resource or create a new +one. A guide on how to create them can be found [here](../guides/creating-valuesets-for-dsf-processes.md). + +Since the [discriminator](https://www.hl7.org/fhir/R4/profiling.html#discriminator) requires +`Task.input.coding.code` and `Task.input.coding.system` to be present, we will make `Task.input.coding` mandatory as well: +```xml + + ... + + ... + + + + + + + + + + + + + + + + + + + +``` + +In the beginning we mentioned how `Task.input.type.coding.system` and `Task.input.type.coding.code` +have to use fixed values. Here is how we accomplish this: + +```xml + + ... + + ... + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +``` +*Notice that we also made the two elements mandatory because they are required by the discriminator.* + +For the `type.coding.system` element we referenced a [CodeSystem](../concepts/fhir/codesystem.md). +The `type.coding.code` element uses a code from this [CodeSystem](../concepts/fhir/codesystem.md) called `example-input`. +This is the mechanism by which you actually "name" your [Input Parameter](../concepts/fhir/task.md#task-input-parameters). The +`type.coding.code` value will identify your [Input Parameter](../concepts/fhir/task.md#task-input-parameters) when you use +it in an actual [Task](../concepts/fhir/task.md#task-input-parameters) resource. Here is how this would look like: + +```xml + + ... + + + + + + + + ... + + +``` + +When adding an actual slice for your use case, you will also need to reference an existing [CodeSystem](../concepts/fhir/codesystem.md) resource or create a new one to reference. +A guide on how to create them can be found [here](../guides/creating-codesystems-for-dsf-processes.md). + +`Task.input.value[x]` is the actual value you will submit using your Input Parameter. You can make it +any of [these](https://www.hl7.org/fhir/R4/datatypes.html#open) data types. This is because `Type.input.value[x]` +refers to `*` instead of any particular type in its [definition](https://www.hl7.org/fhir/R4/task-definitions.html#Task.input.value_x_). Let us define it as an `integer` type`: + +```xml + + ... + + ... + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +``` + +Now we have a new Input Parameter of type `example-input` which accepts any `integer` as its value. diff --git a/docs/src/developer-documentation/guides/configuring-the-read-access-tag.md b/docs/src/developer-documentation/guides/configuring-the-read-access-tag.md new file mode 100644 index 000000000..f8a6dfb59 --- /dev/null +++ b/docs/src/developer-documentation/guides/configuring-the-read-access-tag.md @@ -0,0 +1,429 @@ +### Configuring the Read Access Tag + +To start off, you want to take a look at the [CodeSystem](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/CodeSystem/dsf-read-access-tag-1.0.0.xml) defined for the [Read Access Tag](../concepts/dsf/read-access-tag.md) +and choose one of the codes from it: +```xml + + ... + + ... + + + + + + + + + + + + + + + + + + + + + +``` + +The codes `LOCAL` and `ALL` are trivial. Their [Read Access Tag](../concepts/dsf/read-access-tag.md) would look like this: +```xml + + + + + + +``` + +Let us try to configure a Read Access Tag whose code uses an extension. We will choose `ROLE` for this example. We start out the same way as before: +```xml + + + + + + +``` + +The `definition` element of the `ROLE` code references an extension called [dsf-extension-read-access-parent-organization-role](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-extension-read-access-parent-organization-role-1.0.0.xml). + +The most important part of it is the `differential` statement. It uses [element definitions](https://www.hl7.org/fhir/R4/elementdefinition.html) to describe how we need to implement the extension: +```xml + + ... + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +``` + +All extensions for the [Read Access Tag](../concepts/dsf/read-access-tag.md) CodeSystem are defined on the `meta.tag.extension` element through +the extension's `context` element: +```xml + + + + +``` + +That is why the first element we are adding to `meta.tag` is an `extension` element: +```xml + + + + + + + + + +``` + +We will now go through the `differential` statement one element at a time, starting at the top: +```xml + + ... + + + + + + + + + + + + ... + + +``` + +It defines a [slicing](https://www.hl7.org/fhir/R4/profiling.html#slicing) for the `Extension.extension` element, meaning we are dealing +with a nested extension. The `discriminator` element tells us that slices will be identified by the value of their `url` attribute. +A `rules` element with value `open` means other types of slices may be added later on e.g. when creating a profile. We do not have to +add any elements from here to the `meta.tag.extension` element. +Next up is the first slice called `parentOrganization`: + +```xml + + ... + + ... + + + + + + + + + + + + + + + + + + + + + + + + + + + ... + + +``` + +The first element defines a slice called `parentOrganization` on the `Extension.extension` element with cardinality `1..1`. +The second element defines the url attribute of the `parentOrganization` slice to be fixed to the value `parent-organization`. +With this information we can add the next element to `meta.tag`. Since it is defined on `Extension.extension` we will add it to +`meta.tag.extension.extension` like this: +```xml + + + + + + + + + + + +``` + +After that, it defines `parentOrganization.value[x]` to occur at least once and have a type of `Identifier`. To turn this into an +element to add to `meta.tag.extension.extension` we have to replace `[x]` with our code in `value[x].type`, which in this case is `Identifier`. It is important +to note, that should the value in the code element be lowercase, you will have make it uppercase before replacement. In our case this means we will have a +`meta.tag.extension.extension.valueIdentifier` element: +```xml + + + + + + + + + + + + + +``` + +The last two elements define a `system` element with a fixed value and `value` element we can fill in on our own, since it does not have any constraints applied. Notice that +the element definition still uses `value[x].system` and `value[x].value`. The replacement mentioned earlier does not happen in +the element definition, but since `value[x]` is defined to have the type `Identifier` it is inferred that we mean to reference `Identifier.system` +and `Identifier.value`. +We will choose an arbitrary `Idenfier` value, but you should be using an actual organization identifier depending on who you want to allow read access to the resource. + +```xml + + + + + + + + + + + + + + +``` + +Next is the slice is called `organizationRole`: +```xml + + ... + + ... + + + + + + + + + + + + + + + + + + + + + + + + + + ... + + +``` + +Like with `parentOrganization`, we will add an extension element to `meta.tag.extension` with the fixed url value defined above: +```xml + + + + + + + + + + + + + + + + + +``` + +Instead of `Identifier`, the `value[x]` element is now defined as a `Coding` type. This means we will add a `valueCoding` element to the extension: +```xml + + + + + + + + + + + + + + + + + + + +``` + +A `Coding` has to belong to some [CodeSystem](../concepts/fhir/codesystem.md). The DSF has a CodeSystem called [dsf-organization-role](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/CodeSystem/dsf-organization-role-1.0.0.xml). +Before creating your own CodeSystem, it is worth taking a look at it to see if an appropriate role already exists for your organization. +For demonstration purposes, we will be using the `DIC` role: +```xml + + + + + + + + + + + + + + + + + + + + +``` + +Now we only have two elements left in the `differential` statement: + +```xml + + ... + + ... + + + + + + + + + + +``` + +The `Extension.url` element tells us to add a url attribute to `meta.tag.extension`. The last element makes it so we must not +add a `meta.tag.extension.value[x]` element. This leaves us with this final Read Access Tag: + +```xml + + + + + + + + + + + + + + + + + + + + +``` + +You can follow the same method to configure the other types of Read Access Tags as well. \ No newline at end of file diff --git a/docs/src/developer-documentation/guides/creating-an-activity-definition.md b/docs/src/developer-documentation/guides/creating-an-activity-definition.md new file mode 100644 index 000000000..c0e2295a9 --- /dev/null +++ b/docs/src/developer-documentation/guides/creating-an-activity-definition.md @@ -0,0 +1,797 @@ +### Creating an ActivityDefinition + +This guide will teach you how to create an ActivityDefinition based on the [dsf-activity-definition](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-activity-definition-1.0.0.xml) profile for your process plugin. +It is divided into steps for each of the main components of ActivityDefinitions: +1. Read Access Tag +2. Extension: process authorization +3. BPE Managed Elements +4. Regular Elements + +*Regular elements* are all elements not part of the first 3 main components. + +*We will assume you know how to translate [ElementDefinitions](https://www.hl7.org/fhir/R4/elementdefinition.html) to actual elements in a FHIR resource. +If you do not, you might want to check out the guide on [creating Task resources](../guides/creating-task-resources-based-on-a-definition.md) first.* + +#### 1. Read Access Tag +Let us start out with an empty [ActivityDefinition](../concepts/fhir/activitydefinition.md): +```xml + + + +``` + +The first element in DSF FHIR resources is always the [Read Access Tag](../concepts/dsf/read-access-tag.md). It describes who is +allowed to read this resource through the DSF FHIR server's REST API. You can learn more complex configurations of the +[Read Access Tag](../concepts/dsf/read-access-tag.md) in [this guide](../concepts/dsf/read-access-tag.md). In this case, we will allow read access to everyone: + +```xml + + + + + + + + +``` + +#### 2. Extension: Process Authorization +This part of your ActivityDefinition will tell the DSF who is allowed to request and receive messages ([Task](../concepts/fhir/task.md) resources) +for your BPMN process. If your plugin contains more than one BPMN process, you will have to create one [ActivityDefinition](../concepts/fhir/activitydefinition.md) +for each BPMN process. It is important to note that you need to include authorization rules for **ALL** messages received in your BPMN process. +This includes the message starting your BPMN process initially. +You can find the extension [here](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-extension-process-authorization-1.0.0.xml). +Let us continue by adding the [extension element](http://hl7.org/fhir/R4/extensibility.html#extension) with the correct URL. You can get the +value for the URL from the `Extension.url` element: +```xml + + ... + + + + +``` +*Elements not relevant to the current component are hidden with ... to increase readability.* + +The [differential](https://www.hl7.org/fhir/R4/profiling.html#snapshot) statement +starts by defining the [slicing](https://www.hl7.org/fhir/R4/profiling.html#snapshot) for the `Extension.extension` element: + +```xml + + ... + + + + + + + + + + + + + + + + ... + + +``` + +The above states that whenever this extension is used in a profile, the profile needs to include this extension at least once (``). +The [slicing](https://www.hl7.org/fhir/R4/profiling.html#snapshot) on `Extension.extension` tells us that elements of this [slicing](https://www.hl7.org/fhir/R4/profiling.html#snapshot) +are identified by the value of their URL (``), which is always the case for extensions, and that other extensions can be added to the [slicing](https://www.hl7.org/fhir/R4/profiling.html#snapshot) (``). +Since there is a [slicing](https://www.hl7.org/fhir/R4/profiling.html#snapshot) on `Extension.extension`, we are dealing with a nested extension. + +After these initial element definitions come the elements relevant for your process plugin. The first one is the `message-name` slice: +```xml + + ... + + ... + + + + + + + + + + + + + + + + + + ... + + +``` + +This section tells us that we need to include exactly one extension element from the `message-name` slice in our [ActivityDefinition](../concepts/fhir/activitydefinition.md). +The extension element will have a URL value of `message-name`. If you remember the `discriminator` configuration, this URL value identifies the element to belong to the `message-name` slice on `Extension.extension`. +Lastly, the extension element includes a `valueString` element. In case you are wondering how `value[x]` turned into `valueString`, +FHIR does not allow using `value[x]` as actual element. The value in `value[x]` is always strictly bound to some kind of type. +FHIR uses the `value[x].type.code` value to determine this type and replaces `[x]` with an uppercase version of `element.type.code`. +This results in the following extension element we will add to our [ActivityDefinition](../concepts/fhir/activitydefinition.md): +```xml + + + +``` + +For your use case, you have to replace `myMessage` with the name of the [BPMN message event](../concepts/bpmn/messaging.md) that is expecting this message. + +
+This is how your ActivityDefinition should look like so far + +```xml + + + + + + + + + + + + + +``` +
+ +The next slice is called `task-profile`: +```xml + + ... + + ... + + + + + + + + + + + + + + + + + + ... + + +``` + +This section has almost the same structure as `message-name`. The only difference is the value for `value[x].type.code`. +This means that instead of `valueString`, we will have to use a `valueCanonical` element for `task-profile.value[x]`. +Canonical values referring to [Task](../concepts/fhir/task.md) profiles in ActivityDefinitions have to conform +to the rules outlined by the documentation on [URLs](../concepts/dsf/about-version-placeholders-and-urls.md#urls). +From the definition above, we will create the following extension element and add it to our [ActivityDefinition](../concepts/fhir/activitydefinition.md): +```xml + + + +``` + +
+This is how your ActivityDefinition should look like so far + +```xml + + + + + + + + + + + + + + + + +``` +
+ +The next slice is `requester`: +```xml + + ... + + ... + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ... + + +``` +Instead of a `string` or `canonical` type for `value[x]` we now have a `Coding` type. See the [FHIR documentation on Codings](https://www.hl7.org/fhir/R4/datatypes.html#Coding) +for more in-depth information. `Codings` are elements which contain, among other things, a `code` and the `system` the code belongs to. In the same way we transformed `value[x]` into `valueString` or `valueCanonical` before, we will also +have to turn `value[x]` into `valueCoding`. To use `Codings` in `valueCoding` elements, they are usually bound to the element through a [ValueSet](../concepts/fhir/valueset.md). This is the +responsibility of the `binding` element. You can also see that `value[x].type.profile` lists a number of profiles. Instead of defining the +elements in the same file, they were defined in different files for better readability. Depending on your use case, you have to pick one of the profiles. +Here is what they mean: +- `local-all`: All local requests will be allowed. Local requests are identified by matching the requester's certificate to a thumbprint which was internally marked by the DSF FHIR server as belonging to a local organization. +- `local-organization`: All local requests made from an organization with a specific `organization-identifier` will be allowed. +- `local-parent-organization-role`: All local requests made from an organization having a specific role inside a specific parent organization will be allowed. +- `remote` versions of the above rules work the same but the requester's certificate is instead required to match a thumbprint marked as a remote organization. +- `practitioner` suffixes all work the same. They include the same rules as their prefixes but now additionally require the requester to match a certain `practitioner-role`. A list of them + can be found [here](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/CodeSystem/dsf-practitioner-role-1.0.0.xml). This allows + for more granularity when defining authorization rules within an organization and can be integrated into local user management via [OpenID Connect](https://dsf.dev/stable/maintain/fhir/access-control.html). + +As you can see, there are no `practitioner` versions of `remote` authorization rules. From the perspective of the receiving DSF instance, +remote requests are always issued by an organization. They do not hold any information about the local user management of the requesting organization. +You can also find examples of all Codings from above [here](../concepts/dsf/examples-for-requester-and-recipient-elements.md). + +It is also good to keep in mind that you are allowed to add any number of `requester` elements into your [ActivityDefinition](../concepts/fhir/activitydefinition.md). +Let us start out by adding a `requester` element like we did for previous elements: + +```xml + + + + + +``` + +We now have to look at the elements that are defined in one of the profiles to fill in the remaining elements since they are not defined by the `requester` extension. For demonstration +purposes, we will choose the [dsf-coding-process-authorization-local-organization-practitioner](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-coding-process-authorization-local-organization-practitioner-1.0.0.xml) profile. +Since all elements listed in the [Coding definition](https://www.hl7.org/fhir/R4/datatypes.html#codesystem) are optional, we only have to look at the `differential` element from the profile we just selected: + +```xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +``` +It defines an extension called `organization-practitioner` which is identified through its url attribute. Again, the extension +is only referenced, its location is in a different file. You can find it [here](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-extension-process-authorization-organization-practitioner-1.0.0.xml). +Let us look at its `differential` element in the extension file to see how we need to populate the extension: +```xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +``` + +This extension does not reference any other files. This means we reached the "deepest" level. So now we can start working our way back up again from here, by translating this +definition into actual extension elements, then inserting it into the Coding we selected, translating the rest of the element +definitions from the Coding resource and adding everything to our [ActivityDefinition](../concepts/fhir/activitydefinition.md). + +We will start with the `Extension.url` element, since the `Extension` element is the parent element for all slices on the `Extension.extension` elements: +```xml + + + +``` + +Next, we will add the `organization` slice: +```xml + + + + + + + + +``` +Finally, we will add the `practitionerRole` slice: + +```xml + + + + + + + + + + + + + + +``` + +Notice that there is no `binding` element specified for `practitionerRole.value[x]`. This is intentional. In the example we used a code from the +[dsf-practitioner-role](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/CodeSystem/dsf-practitioner-role-1.0.0.xml) CodeSystem. +This CodeSystem includes a standard set of codes which are often sufficient for DSF use cases. You can freely add other CodeSystems if you find these codes +do not apply for your use case. The code you set here can be used in the [DSF role config](https://dsf.dev/stable/maintain/fhir/access-control.html) +to allow certain users with this `practitioner-role` to send requests. + +Working our way back up to the Coding we selected, we will now add the extension we just created as the `Coding.extension:organization-practitioner` element: +```xml + + + + + + + + + + + + + + + + + + +``` +Now might be a good time to look at the [differential](#coding-differential) from the Coding again. +Our next elements to be added are `Coding.system` and `Coding.code`: +```xml + + + + + + + + + + + + + + + + + + + + +``` +Now we are finished with the `requester` extension and can add it to our [ActivityDefinition](../concepts/fhir/activitydefinition.md) under +the [dsf-extension-process-authorization](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-extension-process-authorization-1.0.0.xml). + +
+This is how your ActivityDefinition should look like so far + +```xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +``` +
+ +Now we are back to looking at the [dsf-extension-process-authorization](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-extension-process-authorization-1.0.0.xml) again. +The last slice for this extension is `recipient`: +```xml + + ... + + ... + + + + + + + + + + + + + + + + + + + + + + + + ... + + +``` + +The `recipient` will decide which DSF instance is allowed to process that message. That is the reason why you will not find any Codings for `remote` or `practitioner` here. +For `requester`, we already decided that we will only allow users with a certain role from our own (local) organization to send this message. +So now we will only allow the DSF instance run by that same local organization to process the message. The right Coding for this job is +the [coding-process-authorization-local-organization](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-coding-process-authorization-local-organization-1.0.0.xml). +The configuration of a local requester and local receiver is often used for the message that starts up the first BPMN process of the plugin. +The process of adding the `recipient` slice is the exact same as it is for `requester`. You can follow the steps for the `requester` slice again +but just use a different Coding. + +
+Using the Coding we just decided on, this is how your ActivityDefinition should look like + +```xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +``` +
+ +The last element defined in the [process authorization extension](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-extension-process-authorization-1.0.0.xml) +is `Extension.url`. But since we added this element at the very beginning of the working through the extension, we are finished with it here. + +#### 3. BPE Managed Elements + +Some elements of [ActivityDefinitions](../concepts/fhir/activitydefinition.md) are managed by the DSF BPE and replaced with certain values +at appropriate times. + +The following elements are managed by the DSF BPE: +- `ActivityDefinition.version` should use the [placeholder](../concepts/dsf/about-version-placeholders-and-urls.md#placeholders) `#{version}` +- `ActivityDefinition.date` is not required, but should you decide to include it, use the [placeholder](../concepts/dsf/about-version-placeholders-and-urls.md#placeholders) `#{date}` +- `ActivityDefinition.status` must have a value of `unknown` + +
+Your ActivityDefinition should now look like this + +```xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +``` +
+ +#### 4. Regular Elements + +The only required elements in this set are `ActivityDefinition.url` and `ActivityDefinition.kind`. +Check out the documentation on [URLs](../concepts/dsf/about-version-placeholders-and-urls.md#urls) on how to choose the correct value for `ActivityDefinition.url`. `ActivityDefinition.kind` +must have the value `Task`. +All other elements can technically be omitted. Still, we recommend you include the following elements: +- `AcitivityDefinition.name` +- `AcitivityDefinition.title` +- `AcitivityDefinition.subtitle` +- `AcitivityDefinition.experimental` +- `AcitivityDefinition.publisher` +- `AcitivityDefinition.contact` +- `AcitivityDefinition.description` + +
+Your finished ActivityDefinition should now look something like this + +```xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <subtitle value="Information Processing Process"/> + <experimental value="false"/> + <publisher value="DSF"/> + <contact> + <name value="DSF"/> + <telecom> + <system value="email"/> + <value value="noreply@dsf.dev"/> + </telecom> + </contact> + <description value="My Process processes information"/> +</ActivityDefinition> +``` +</details> \ No newline at end of file diff --git a/docs/src/developer-documentation/guides/creating-codesystems-for-dsf-processes.md b/docs/src/developer-documentation/guides/creating-codesystems-for-dsf-processes.md new file mode 100644 index 000000000..5c65e3078 --- /dev/null +++ b/docs/src/developer-documentation/guides/creating-codesystems-for-dsf-processes.md @@ -0,0 +1,42 @@ +### Creating CodeSystems for DSF Processes + +You might find yourself in a situation where you need to create a [CodeSystem](../concepts/fhir/codesystem.md). +For example, when defining the type of an [Input Parameter](../concepts/fhir/task.md#task-input-parameters). +[CodeSystems](../concepts/fhir/codesystem.md) for the DSF differ from regular [CodeSystems](../concepts/fhir/codesystem.md) +in that some element's values are managed by the DSF BPE server. You can use the following XML as a template: +```xml +<CodeSystem xmlns="http://hl7.org/fhir"> + <meta> + <tag> + <system value="http://dsf.dev/fhir/CodeSystem/read-access-tag" /> + <code value="ALL" /> + </tag> + </meta> + <url value="http://dsf.dev/fhir/CodeSystem/my-code-system" /> <!--dummy value--> + <!-- version managed by bpe --> + <version value="#{version}" /> + <name value="My CodeSystem" /> <!--dummy value--> + <title value="My CodeSystem Title" /> <!--dummy value--> + <!-- status managed by bpe --> + <status value="unknown" /> + <experimental value="false" /> + <!-- date managed by bpe --> + <date value="#{date}" /> + <publisher value="DSF" /> <!--dummy value--> + <description value="CodeSystem with codes for me" /> <!--dummy value--> + <caseSensitive value="true" /> + <hierarchyMeaning value="grouped-by" /> + <versionNeeded value="false" /> + <content value="complete" /> + <concept> + <code value="my-code" /> <!--dummy value--> + <display value="My Code" /> <!--dummy value--> + <definition value="My code used for myself" /> <!--dummy value--> + </concept> +</CodeSystem> +``` +Replace dummy values with appropriate values of your own. Do not change elements managed by the DSF BPE server. +You can add as many codes as you like by defining more `concept` elements. + +The DSF BPE server will read your [CodeSystem](../concepts/fhir/codesystem.md) from +`tutorial-process/src/main/resources/fhir/CodeSystem`. \ No newline at end of file diff --git a/docs/src/developer-documentation/guides/creating-task-resources-based-on-a-definition.md b/docs/src/developer-documentation/guides/creating-task-resources-based-on-a-definition.md new file mode 100644 index 000000000..d6da6bff4 --- /dev/null +++ b/docs/src/developer-documentation/guides/creating-task-resources-based-on-a-definition.md @@ -0,0 +1,266 @@ +### Creating Task Resources Based on a Definition + +This short guide should help you understand how you can create [Task](../concepts/fhir/task.md) +resources for use in [Starting A Process Via Task Resources](../guides/starting-a-process-via-task-resources.md). +We will employ the use of the free version of [Forge](https://simplifier.net/forge?utm_source=firely-forge) to help +with visualization. You are invited to create a free account and follow along, but we will include screenshots of relevant +views either way. Remember that the free version of Forge [must not be used commercially](https://simplifier.net/pricing). +As an example, we will create a [Task](../concepts/fhir/task.md) resource from the `task-start-dic-process.xml` profile. + +#### 1st Step: Removing Placeholders +`task-start-dic-process.xml` includes placeholders for the `version` and `date` elements. For the duration of this guide, +you can either remove or comment these elements, so Forge does not try to perform type checking on them, which +would result in an error and Forge not loading the file. + +#### 2nd Step: Differential Chain +If the resource profile is only available as a [differential](https://www.hl7.org/fhir/R4/profiling.html#snapshot), like in our +case, we will want to aggregate the changes made to the base resource (in this case [Task](../concepts/fhir/task.md)) by all profiles to make +it more readable. +To do this, we first need all the profiles involved. We already have `task-start-dic-process.xml` in our `StructureDefinition` folder. +It lists a resource called `task-base` in its `baseDefinition` element. This resource is part of the DSF and can be +found [here](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-task-base-1.0.0.xml). +Put it into the `StructureDefinition` folder. Since `task-base` has the original FHIR Task as its `baseDefinition` +element, we are done with this chain. +In forge, you should now be able to open the `StructureDefinition` folder and select the `task-start-dic-process.xml` profile. +It should look something like this: + +![Forge overview](../../exercises/figures/forge_overview.png) + +#### 3rd Step: Building the Task Resource +We will now go through each element one by one and include it into our [Task](../concepts/fhir/task.md) +resource, provided it is mandatory (cardinality at least `1..1`) according to the profile. It is important +that you not use any placeholders like `#{version}` for resources not read by the DSF BPE server. This is the case +if we want a [Task](../concepts/fhir/task.md) resource for use with [cURL](../guides/starting-a-process-via-task-resources.md#using-curl). +But, placeholders should be used in [Draft Task Resources](../concepts/dsf/draft-task-resources.md) instead of actual values wherever possible, +since those are read by the DSF BPE server. This guide will create a [Task](../concepts/fhir/task.md) resource without placeholders. +We will start out with the base element for all [Task](../concepts/fhir/task.md) resources: +```xml +<Task xmlns="http://hl7.org/fhir"> + +</Task> +``` + +Before we start adding any elements listed in Forge's element tree, we have to include the `Task.meta.profile` element. +Its requirement cannot be seen here which is why we mention it specifically. This is the only instance you will not see +it in the element tree. It should look like this: +```xml +<Task xmlns="http://hl7.org/fhir"> + <meta> + <profile value="http://dsf.dev/fhir/StructureDefinition/task-start-dic-process|1.0"/> + </meta> +</Task> +``` + +The first element which can be found in the element tree is the `instantiatesCanonical` element. To add it, we +will create an XML element with the same name and the value according to [URLs](../concepts/dsf/about-version-placeholders-and-urls.md#urls): +```xml +<Task xmlns="http://hl7.org/fhir"> + <meta> + <profile value="http://dsf.dev/fhir/StructureDefinition/task-start-dic-process|1.0"/> + </meta> + <instantiatesCanonical value="http://dsf.dev/bpe/Process/dicProcess|1.0" /> +</Task> +``` +We can continue this process for all primitive elements like these. Just make sure you pay attention to use the correct +data type (e.g. proper coding value for elements with `coding` type). + +By now your [Task](../concepts/fhir/task.md) resources should look something like this: +<details> +<summary>Suggested solution</summary> + +```xml +<Task xmlns="http://hl7.org/fhir"> + <meta> + <profile value="http://dsf.dev/fhir/StructureDefinition/task-start-dic-process|1.0"/> + </meta> + <instantiatesCanonical value="http://dsf.dev/bpe/Process/dicProcess|1.0" /> + <status value="requested"/> + <intent value="order"/> + <authoredOn value="2024-02-08T10:00:00+00:00" /> +</Task> +``` +</details> + +Let us look at a more complex element like the `requester` element: + +![Forge requester view](../../exercises/figures/forge_requester_view.png) + +We will start the same way we started with primitive elements, by adding the `requester` element: +```xml +<Task xmlns="http://hl7.org/fhir"> + <meta> + <profile value="http://dsf.dev/fhir/StructureDefinition/task-start-dic-process|1.0"/> + </meta> + <instantiatesCanonical value="http://dsf.dev/bpe/Process/dicProcess|1.0" /> + <status value="requested"/> + <intent value="order"/> + <authoredOn value="2024-02-08T10:00:00+00:00" /> + <requester> + + </requester> +</Task> +``` + +Then, we will add primitive elements to `requester` like we did before for `Task`: +```xml +<Task xmlns="http://hl7.org/fhir"> + <meta> + <profile value="http://dsf.dev/fhir/StructureDefinition/task-start-dic-process|1.0"/> + </meta> + <instantiatesCanonical value="http://dsf.dev/bpe/Process/dicProcess|1.0" /> + <status value="requested"/> + <intent value="order"/> + <authoredOn value="2024-02-08T10:00:00+00:00" /> + <requester> + <type value="Organization"/> + </requester> +</Task> +``` +*Important to note here that the value for the `status` will always be `requested` for Tasks being posted using cURL and the `type` element for `requester` and `recipient` will always have the value `Organization` in the DSF context.* + +Next, we will add the `identifier` element and its primitive sub-elements just like we started out doing it for the `requester` element. The `identifier.value` in this case will be `dic.dsf.test`. To understand why, take a look at the topic on [organization identifiers](../concepts/dsf/organization-identifiers.md): +```xml +<Task xmlns="http://hl7.org/fhir"> + <meta> + <profile value="http://dsf.dev/fhir/StructureDefinition/task-start-dic-process|1.0"/> + </meta> + <instantiatesCanonical value="http://dsf.dev/bpe/Process/dicProcess|1.0" /> + <status value="requested"/> + <intent value="order"/> + <authoredOn value="2024-02-08T10:00:00+00:00" /> + <requester> + <type value="Organization"/> + <identifier> + <system value="http://dsf.dev/sid/organization-identifier"/> + <value value="dic.dsf.test" /> + </identifier> + </requester> +</Task> +``` +*Notice that `requester.identifier.system` has a `Fixed value` annotation. You can see what the value is supposed +to be by clicking on the `system` element in Forge or looking at the XML for the right Task profile. The right side will have all information about that element, including +the actual value for `Fixed value`.* + +You should now be able to fill out all elements in your [Task](../concepts/fhir/task.md) resource until you reach +the [slicing](https://www.hl7.org/fhir/R4/profiling.html#slicing) for `Task.input`. Your [Task](../concepts/fhir/task.md) +resource should look something like this: +<details> +<summary>Suggested solution</summary> + +```xml +<Task xmlns="http://hl7.org/fhir"> + <meta> + <profile value="http://dsf.dev/fhir/StructureDefinition/task-start-dic-process|1.0"/> + </meta> + <instantiatesCanonical value="http://dsf.dev/bpe/Process/dicProcess|1.0" /> + <status value="requested"/> + <intent value="order"/> + <authoredOn value="2024-02-08T10:00:00+00:00" /> + <requester> + <type value="Organization"/> + <identifier> + <system value="http://dsf.dev/sid/organization-identifier"/> + <value value="dic.dsf.test" /> + </identifier> + </requester> + <restriction> + <recipient> + <type value="Organization"/> + <identifier> + <system value="http://dsf.dev/sid/organization-identifier" /> + <value value="dic.dsf.test" /> + </identifier> + </recipient> + </restriction> +</Task> +``` +</details> + + +[Slicings](https://www.hl7.org/fhir/R4/profiling.html#slicing) are a bit different from regular elements. Let us look at the +slice `message-name`: + +![Forge slice message name](../../exercises/figures/forge_slice_message_name.png) + +If we were to continue including slices to the [Task](../concepts/fhir/task.md) resource like we did so far, +we would add a `message-name` element to our XML like this: + +```xml +<Task xmlns="http://hl7.org/fhir"> + ... + <input> + <message-name> + ... + </message-name> + </input> +</Task> +``` + +This approach however, would not work. FHIR processors do not use the name of the slice to map entries in +your [Task](../concepts/fhir/task.md) resource to the correct slice. They use [discriminators](https://www.hl7.org/fhir/R4/profiling.html#discriminator). +Discriminators define the elements a processor needs to distinguish slices by. You can see +how the discriminator is configured by selecting the `input` element in Forge. In our case, a processor +would look at the values for `input.type.coding.system` and `input.type.coding.code` to determine which +slice this element belongs to. This only works because `input.type.coding.system` and `input.type.coding.code` +are present in all slices and have a `Fixed value`. You can learn more about discriminators [here](https://www.hl7.org/fhir/R4/profiling.html#discriminator). +All this means is that we effectively ignore the name of the slice as an element and start adding elements like we did before: + +```xml +<Task xmlns="http://hl7.org/fhir"> + ... + <input> + <type> + <coding> + <system value="http://dsf.dev/fhir/CodeSystem/bpmn-message" /> + <code value="message-name" /> + </coding> + </type> + <valueString value="dicProcess" /> + </input> +</Task> +``` + +Now you should be able to add all remaining mandatory elements to your [Task](../concepts/fhir/task.md) +resource on your own. In the end, it should look something like this: +<details> +<summary>Suggested solution</summary> + +```xml +<Task xmlns="http://hl7.org/fhir"> + <meta> + <profile value="http://dsf.dev/fhir/StructureDefinition/task-start-dic-process|1.0"/> + </meta> + <instantiatesCanonical value="http://dsf.dev/bpe/Process/dicProcess|1.0" /> + <status value="requested"/> + <intent value="order"/> + <authoredOn value="2024-02-08T10:00:00+00:00" /> + <requester> + <type value="Organization"/> + <identifier> + <system value="http://dsf.dev/sid/organization-identifier"/> + <value value="dic.dsf.test" /> + </identifier> + </requester> + <restriction> + <recipient> + <type value="Organization"/> + <identifier> + <system value="http://dsf.dev/sid/organization-identifier" /> + <value value="dic.dsf.test" /> + </identifier> + </recipient> + </restriction> + <input> + <type> + <coding> + <system value="http://dsf.dev/fhir/CodeSystem/bpmn-message" /> + <code value="message-name" /> + </coding> + </type> + <valueString value="dicProcess"/> + </input> +</Task> +``` +</details> + +**Do not forget to restore the version and date placeholders in `task-start-dic-process.xml`!** \ No newline at end of file diff --git a/docs/src/developer-documentation/guides/creating-valuesets-for-dsf-processes.md b/docs/src/developer-documentation/guides/creating-valuesets-for-dsf-processes.md new file mode 100644 index 000000000..c4ca9e21a --- /dev/null +++ b/docs/src/developer-documentation/guides/creating-valuesets-for-dsf-processes.md @@ -0,0 +1,69 @@ +### Creating ValueSets for DSF Processes + +You might find yourself in the situation where you need to create a [ValueSet](../concepts/fhir/valueset.md). +For example, when adding [Input Parameters](../concepts/fhir/task.md#task-input-parameters) to DSF [Task](../concepts/fhir/task.md) +resources, you will also have to reference a [ValueSet](../concepts/fhir/valueset.md) resource in your +binding for `Task.input.type` to be able to set the type of your [Input Parameter](../concepts/fhir/task.md#task-input-parameters). +[ValueSets](../concepts/fhir/valueset.md) for the DSF differ from regular [ValueSets](../concepts/fhir/valueset.md) +in that some element's values are managed by the DSF BPE server. You can use the following template for your +[ValueSet](../concepts/fhir/valueset.md): +```xml +<ValueSet xmlns="http://hl7.org/fhir"> + <meta> + <tag> + <system value="http://dsf.dev/fhir/CodeSystem/read-access-tag" /> + <code value="ALL" /> + </tag> + </meta> + <url value="http://dsf.dev/fhir/ValueSet/my-value-set"/> <!--dummy value--> + <!-- version managed by bpe --> + <version value="#{version}" /> + <name value="My ValueSet"/> <!--dummy value--> + <title value="My ValueSet Title"/> <!--dummy value--> + <!-- status managed by bpe --> + <status value="unknown" /> + <experimental value="false"/> + <!-- date managed by bpe --> + <date value="#{date}"/> + <publisher value="DSF"/> <!--dummy value--> + <description value="ValueSet with all codes from my-code-system"/> <!--dummy value--> + <immutable value="true"/> + <compose> + <include> + <system value="http://dsf.dev/fhir/CodeSystem/my-code-system"/> <!--dummy value--> + <version value="#{version}"/> + </include> + </compose> +</ValueSet> +``` +Replace dummy values with appropriate values of your own. Do not change elements managed by the DSF BPE server. +The `compose` element defines the codes included in this [ValueSet](../concepts/fhir/valueset.md). +It holds at least one `include` element. Each `include` element refers to a [CodeSystem](../concepts/fhir/codesystem.md) +and contains a list of `concept` elements which in turn contain the actual `code` element. +Using one code from `my-code-system` and one code from `my-other-code-system` would result in the following `compose` element: +```xml +<ValueSet xmlns="http://hl7.org/fhir"> + ... + <compose> + <include> + <system value="http://dsf.dev/fhir/CodeSystem/my-code-system"/> + <version value="#{version}"/> + <concept> + <code value="my-code"/> + </concept> + </include> + <include> + <system value="http://dsf.dev/fhir/CodeSystem/my-other-code-system"/> + <version value="#{version}"/> + <concept> + <code value="my-other-code"/> + </concept> + </include> + </compose> +</ValueSet> +``` +The DSF BPE server will read your [ValueSet](../concepts/fhir/valueset.md) from +`tutorial-process/src/main/resources/fhir/ValueSet`. + +You might also want to check out [this guide](../guides/creating-codesystems-for-dsf-processes.md) +on how to create [CodeSystems](../concepts/fhir/codesystem.md). \ No newline at end of file diff --git a/docs/src/developer-documentation/guides/managing-mutiple-incoming-messages-and-missing-messages.md b/docs/src/developer-documentation/guides/managing-mutiple-incoming-messages-and-missing-messages.md new file mode 100644 index 000000000..cdc5de09c --- /dev/null +++ b/docs/src/developer-documentation/guides/managing-mutiple-incoming-messages-and-missing-messages.md @@ -0,0 +1,19 @@ +### Managing Multiple Incoming Messages and Missing Messages + +If an already running process instance is waiting for a message from another organization, the corresponding FHIR [Task](../concepts/fhir/task.md) may never arrive. +Either because the other organization decides to never send the message or because some technical problem prohibits the [Task](../concepts/fhir/task.md) resource from being posted to the DSF FHIR server. +This would result in stale process instances that never finish. + +At the same time, you might also expect to receive one out of a number of different message types at once. + +In order to solve both problems we can add an [Event Based Gateway](../concepts/bpmn/gateways.md#event-based-gateway) to the process waiting +for a response and then either handle a [Task](../concepts/fhir/task.md) resource with the response and finish the process in a success +state or trigger a [Timer Intermediate Catching Event](../concepts/bpmn/timer-intermediate-catching-events.md) after a defined wait period and finish the process in an error state. +The following BPMN collaboration diagram shows how the process at the first organization would look like if we wanted to react to multiple different messages +or missing messages: + +<picture> + <source media="(prefers-color-scheme: dark)" srcset="../../exercises/figures/exercise5_event_based_gateway_inverted.svg"> + <source media="(prefers-color-scheme: light)" srcset="../../exercises/figures/exercise5_event_based_gateway.svg"> + <img alt="BPMN collaboration diagram with an Event Based Gateway" src="../../exercises/figures/exercise5_event_based_gateway.svg"> +</picture> diff --git a/docs/src/developer-documentation/guides/setting-targets-for-message-events.md b/docs/src/developer-documentation/guides/setting-targets-for-message-events.md new file mode 100644 index 000000000..6cb427fbd --- /dev/null +++ b/docs/src/developer-documentation/guides/setting-targets-for-message-events.md @@ -0,0 +1,14 @@ +### Setting Targets for Message Events + +Setting a target for a message event requires a `Target` object. To create one, you require a target's organization identifier, endpoint identifier and endpoint address. +You can find these values by visiting the DSF FHIR server's web interface. In the top right corner, click +the `Show Bookmarks` button, then select `Endpoint`. You will be taken to a list of all Endpoints available to the FHIR server. +There are two ways of adding `targets` to the BPMN execution variables: +#### 1. Adding the target in the message event implementation +In your message event implementation (the class extending `AbstractTaskMessageSend`), you can override `AbstractTaskMessageSend#doExecute`, +add your targets and then call the super-method. +#### 2. Adding the target in a service task right before the message event +This is the preferred method of this tutorial but both methods will work perfectly fine. For our use cases, we usually prefer this one +since there is enough complexity to warrant putting it into a separate BPMN [Service Task](../concepts/bpmn/service-tasks.md). + +In both cases you can access methods to create and set `targets` through the `Variables` instance. diff --git a/docs/src/developer-documentation/guides/starting-a-process-via-task-resources.md b/docs/src/developer-documentation/guides/starting-a-process-via-task-resources.md new file mode 100644 index 000000000..ec6275622 --- /dev/null +++ b/docs/src/developer-documentation/guides/starting-a-process-via-task-resources.md @@ -0,0 +1,68 @@ +### Starting a Process via Task Resources + +To start a BPMN process, you need to create new a [Task](../concepts/fhir/task.md) resource in the DSF FHIR server +by sending an HTTP request according to the [FHIR RESTful API](https://www.hl7.org/fhir/R4/http.html). Specifically, you need to [create](https://www.hl7.org/fhir/R4/http.html#create) +a resource for the first time. Also, remember that the [Task](../concepts/fhir/task.md) +resource you are sending needs to comply to the [Task](../concepts/fhir/task.md) profile of the process you +want to start and the [ActivityDefinition's](../concepts/fhir/activitydefinition.md) authorization rules. +There are two major ways of making this HTTP request: +1. Using cURL +2. Using the DSF FHIR server's web interface + +#### Using cURL +Using cURL probably isn't as "pretty", +but since cURL requires the actual [Task](../concepts/fhir/task.md) payload as an XML, it will prove useful to +gain more insight in how actual [Task](../concepts/fhir/task.md) resources look like and how they relate to +your [Task](../concepts/fhir/task.md) profiles and [ActivityDefinitions](../concepts/fhir/activitydefinition.md). You will have to create +an appropriate [Task](../concepts/fhir/task.md) resource for this. +There already is a file called `example-task.xml` located in `tutorial-process/src/main/resources/fhir`. +You can use this as your starting point. You can try to follow [this guide](../guides/creating-task-resources-based-on-a-definition.md), +or you can check the solution branches for this +file if you need ideas on how to fill it out properly. + +Below are some cURL command skeletons. Replace all <>-Placeholders with appropriate values. Host name depends on the +instance you want to address. For this tutorial this is either one of `dic`, `cos` or `hrp`. [Certificates](../concepts/dsf/certificates.md) can be found in +`test-data-generator/cert`. Client [certificates](../concepts/dsf/certificates.md) and private keys can be found +in the folder of their respective instance e.g. `test-data-generator/cert/dic-client` for the `dic` instance. + +##### Linux: +```shell +curl https://<instance-host-name>/fhir/Task \ +--cacert <path/to/ca-certificate-file.pem> \ +--cert <path/to/client-certificate-file.pem>:password \ +--key <path/to/client-private-key-file.pem> \ +-H "Content-Type: application/fhir+xml" \ +-H "Accept: application/fhir+xml" \ +-d @<path/to/example-task.xml> +``` +##### Windows CMD: +```shell +curl https://<instance-host-name>/fhir/Task ^ +--cacert <path/to/ca-certificate-file.pem> ^ +--cert <path/to/client-certificate-file.pem>:password ^ +--key <path/to/client-private-key-file.pem> ^ +-H "Content-Type: application/fhir+xml" ^ +-H "Accept: application/fhir+xml" ^ +-d @<path/to/example-task.xml> +``` +*This may throw an error depending on which version of cURL Windows is using. If this is the case for you after making sure +you entered everything correctly, you can try using Git's version of cURL instead by adding it to the very top of your system's PATH environment +variable. Git's cURL is usually situated in C:\Program Files\Git\mingw64\bin.* + +#### Using the DSF FHIR Server's Web Interface + +When visiting the web interface of a DSF FHIR server instance (e.g. https://instance-name/fhir), you +can query the DSF FHIR server using the [FHIR RESTful API](https://www.hl7.org/fhir/R4/http.html) to return a list of all [Draft Task Resources](../concepts/dsf/draft-task-resources.md). +These [Task](../concepts/fhir/task.md) resources act like a template you can use to +instantiate [Task](../concepts/fhir/task.md) resources which start BPMN processes. +Instead of querying the DSF FHIR server manually, you can use a predefined bookmark +to navigate to the query URL. You can find a list of Bookmarks in the top right corner of +the web interface. Simply select the bookmark referencing `?_sort=_profile,identifier&status=draft` under +the `Task` section, and you will be taken to the list of all [Draft Task Resources](../concepts/dsf/draft-task-resources.md). +Once there, you can select the one which starts your BPMN process. It will take you to a detailed view +of the resource where you will also have the chance to fill any [Task Input Parameters](../concepts/fhir/task.md#task-input-parameters) +you might need to specify. +If everything is filled out correctly, you may start your process by clicking `Start Process`. +Keep in mind that, for [Draft Task Resources](../concepts/dsf/draft-task-resources.md) to be +available, you need to include them in your mapping for your BPMN process ID in `ProcessPluginDefinition#getFhirResourcesByProcessId`. +Take a look at [the Process Plugin Definition](../concepts/dsf/the-process-plugin-definition.md) if you need a reminder. \ No newline at end of file From 177d7b7eebae5e7adca3ae1ad99aa08b83ecb2f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20B=C3=B6hringer?= <jan.boehringer@hs-heilbronn.de> Date: Mon, 8 Apr 2024 09:06:48 +0200 Subject: [PATCH 02/14] Added learning material from tutorial. Contents not changed yet and still reference tutorial --- docs/package-lock.json | 2 +- docs/package.json | 2 +- .../exercise3_message_flow.bpmn | 88 ++ .../exercise3_message_flow.svg | 4 + .../exercise3_message_flow_inverted.svg | 678 +++++++++ .../exercise5_event_based_gateway.bpmn | 167 +++ .../exercise5_event_based_gateway.svg | 4 + ...exercise5_event_based_gateway_inverted.svg | 1320 +++++++++++++++++ .../forge_overview.png | Bin 0 -> 195635 bytes .../forge_requester_view.png | Bin 0 -> 42843 bytes .../forge_slice_message_name.png | Bin 0 -> 42421 bytes .../keycloak_realm_dropdown.png | Bin 0 -> 27715 bytes .../remote_debugging_eclipse.png | Bin 0 -> 42092 bytes .../remote_debugging_intellij.png | Bin 0 -> 75066 bytes docs/src/.vuepress/theme.ts | 50 +- .../concepts/bpmn/bpmn-model.md | 4 - .../concepts/bpmn/conditions.md | 5 + .../concepts/bpmn/gateways.md | 5 + .../concepts/bpmn/intro.md | 15 + .../concepts/bpmn/messaging.md | 12 +- .../concepts/bpmn/sequence-flow.md | 5 + .../concepts/bpmn/service-tasks.md | 5 + .../timer-intermediate-catching-events.md | 5 + .../about-version-placeholders-and-urls.md | 5 + .../concepts/dsf/bpmn-process-execution.md | 6 + .../concepts/dsf/bpmn-process-variables.md | 5 + .../concepts/dsf/certificates.md | 5 + .../concepts/dsf/draft-task-resources.md | 5 + .../concepts/dsf/environment-variables.md | 5 + ...es-for-requester-and-recipient-elements.md | 5 + .../concepts/dsf/message-correlation.md | 5 + .../concepts/dsf/message-delegates.md | 5 + .../concepts/dsf/organization-identifiers.md | 5 + .../concepts/dsf/process-api.md | 5 + .../concepts/dsf/read-access-tag.md | 5 + .../concepts/dsf/service-delegates.md | 5 + .../concepts/dsf/spring-integration.md | 5 + .../dsf/the-process-plugin-definition.md | 5 + .../concepts/fhir/activitydefinition.md | 5 + .../concepts/fhir/codesystem.md | 5 + .../fhir/{info.md => introduction.md} | 7 +- .../concepts/fhir/task.md | 5 + .../concepts/fhir/valueset.md | 5 + .../accessing-bpmn-process-variables.md | 5 + ...cessing-task-resources-during-execution.md | 5 + ...-task-input-parameters-to-task-profiles.md | 5 + .../guides/configuring-the-read-access-tag.md | 5 + .../guides/creating-an-activity-definition.md | 5 + .../creating-codesystems-for-dsf-processes.md | 5 + ...ng-task-resources-based-on-a-definition.md | 11 +- .../creating-valuesets-for-dsf-processes.md | 5 + ...-incoming-messages-and-missing-messages.md | 11 +- .../setting-targets-for-message-events.md | 5 + .../starting-a-process-via-task-resources.md | 5 + 54 files changed, 2523 insertions(+), 18 deletions(-) create mode 100644 docs/src/.vuepress/public/photos/developer-documentation/exercise3_message_flow.bpmn create mode 100644 docs/src/.vuepress/public/photos/developer-documentation/exercise3_message_flow.svg create mode 100644 docs/src/.vuepress/public/photos/developer-documentation/exercise3_message_flow_inverted.svg create mode 100644 docs/src/.vuepress/public/photos/developer-documentation/exercise5_event_based_gateway.bpmn create mode 100644 docs/src/.vuepress/public/photos/developer-documentation/exercise5_event_based_gateway.svg create mode 100644 docs/src/.vuepress/public/photos/developer-documentation/exercise5_event_based_gateway_inverted.svg create mode 100644 docs/src/.vuepress/public/photos/developer-documentation/forge_overview.png create mode 100644 docs/src/.vuepress/public/photos/developer-documentation/forge_requester_view.png create mode 100644 docs/src/.vuepress/public/photos/developer-documentation/forge_slice_message_name.png create mode 100644 docs/src/.vuepress/public/photos/developer-documentation/keycloak_realm_dropdown.png create mode 100644 docs/src/.vuepress/public/photos/developer-documentation/remote_debugging_eclipse.png create mode 100644 docs/src/.vuepress/public/photos/developer-documentation/remote_debugging_intellij.png delete mode 100644 docs/src/developer-documentation/concepts/bpmn/bpmn-model.md create mode 100644 docs/src/developer-documentation/concepts/bpmn/intro.md rename docs/src/developer-documentation/concepts/fhir/{info.md => introduction.md} (91%) diff --git a/docs/package-lock.json b/docs/package-lock.json index 846fb23bc..6086762fb 100644 --- a/docs/package-lock.json +++ b/docs/package-lock.json @@ -12,7 +12,7 @@ "@vuepress/bundler-vite": "2.0.0-rc.9", "sass-loader": "14.1.1", "vue": "3.4.21", - "vuepress": "2.0.0-rc.9", + "vuepress": "^2.0.0-rc.9", "vuepress-plugin-search-pro": "2.0.0-rc.32", "vuepress-theme-hope": "2.0.0-rc.32" }, diff --git a/docs/package.json b/docs/package.json index 4c911d911..bcadeb134 100644 --- a/docs/package.json +++ b/docs/package.json @@ -14,7 +14,7 @@ "@vuepress/bundler-vite": "2.0.0-rc.9", "sass-loader": "14.1.1", "vue": "3.4.21", - "vuepress": "2.0.0-rc.9", + "vuepress": "^2.0.0-rc.9", "vuepress-plugin-search-pro": "2.0.0-rc.32", "vuepress-theme-hope": "2.0.0-rc.32" }, diff --git a/docs/src/.vuepress/public/photos/developer-documentation/exercise3_message_flow.bpmn b/docs/src/.vuepress/public/photos/developer-documentation/exercise3_message_flow.bpmn new file mode 100644 index 000000000..b95e9860e --- /dev/null +++ b/docs/src/.vuepress/public/photos/developer-documentation/exercise3_message_flow.bpmn @@ -0,0 +1,88 @@ +<?xml version="1.0" encoding="UTF-8"?> +<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:modeler="http://camunda.org/schema/modeler/1.0" id="Definitions_1ngfywh" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="4.12.0" modeler:executionPlatform="Camunda Platform" modeler:executionPlatformVersion="7.15.0"> + <bpmn:collaboration id="Collaboration_1viusst"> + <bpmn:participant id="Participant_0dhadtt" name="Organization 1" processRef="Process_0m41ech" /> + <bpmn:participant id="Participant_0bv9zcu" name="Organization 2" processRef="Process_00ufu87" /> + <bpmn:messageFlow id="Flow_12vbpmr" sourceRef="Event_09zqce0" targetRef="Event_0psf27b" /> + </bpmn:collaboration> + <bpmn:process id="Process_0m41ech" isExecutable="true"> + <bpmn:sequenceFlow id="Flow_07xocd4" sourceRef="StartEvent_1" targetRef="Activity_0r3b2gx" /> + <bpmn:sequenceFlow id="Flow_0s5758j" sourceRef="Activity_0r3b2gx" targetRef="Event_09zqce0" /> + <bpmn:endEvent id="Event_09zqce0"> + <bpmn:incoming>Flow_0s5758j</bpmn:incoming> + <bpmn:messageEventDefinition id="MessageEventDefinition_1gjfdrm" /> + </bpmn:endEvent> + <bpmn:task id="Activity_0r3b2gx" name="Task 1"> + <bpmn:incoming>Flow_07xocd4</bpmn:incoming> + <bpmn:outgoing>Flow_0s5758j</bpmn:outgoing> + </bpmn:task> + <bpmn:startEvent id="StartEvent_1"> + <bpmn:outgoing>Flow_07xocd4</bpmn:outgoing> + </bpmn:startEvent> + </bpmn:process> + <bpmn:process id="Process_00ufu87" isExecutable="false"> + <bpmn:task id="Activity_0er9stz" name="Task 2"> + <bpmn:incoming>Flow_0tzyqri</bpmn:incoming> + <bpmn:outgoing>Flow_1hk1a7w</bpmn:outgoing> + </bpmn:task> + <bpmn:endEvent id="Event_0lwy8y1"> + <bpmn:incoming>Flow_1hk1a7w</bpmn:incoming> + </bpmn:endEvent> + <bpmn:sequenceFlow id="Flow_1hk1a7w" sourceRef="Activity_0er9stz" targetRef="Event_0lwy8y1" /> + <bpmn:sequenceFlow id="Flow_0tzyqri" sourceRef="Event_0psf27b" targetRef="Activity_0er9stz" /> + <bpmn:startEvent id="Event_0psf27b"> + <bpmn:outgoing>Flow_0tzyqri</bpmn:outgoing> + <bpmn:messageEventDefinition id="MessageEventDefinition_05qgs4w" /> + </bpmn:startEvent> + </bpmn:process> + <bpmndi:BPMNDiagram id="BPMNDiagram_1"> + <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Collaboration_1viusst"> + <bpmndi:BPMNShape id="Participant_0dhadtt_di" bpmnElement="Participant_0dhadtt" isHorizontal="true"> + <dc:Bounds x="129" y="110" width="351" height="120" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNEdge id="Flow_07xocd4_di" bpmnElement="Flow_07xocd4"> + <di:waypoint x="215" y="170" /> + <di:waypoint x="270" y="170" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge id="Flow_0s5758j_di" bpmnElement="Flow_0s5758j"> + <di:waypoint x="370" y="170" /> + <di:waypoint x="422" y="170" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNShape id="Event_0l1zhuy_di" bpmnElement="Event_09zqce0"> + <dc:Bounds x="422" y="152" width="36" height="36" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="Activity_0r3b2gx_di" bpmnElement="Activity_0r3b2gx"> + <dc:Bounds x="270" y="130" width="100" height="80" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1"> + <dc:Bounds x="179" y="152" width="36" height="36" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="Participant_0bv9zcu_di" bpmnElement="Participant_0bv9zcu" isHorizontal="true"> + <dc:Bounds x="540" y="110" width="351" height="120" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNEdge id="Flow_1hk1a7w_di" bpmnElement="Flow_1hk1a7w"> + <di:waypoint x="781" y="170" /> + <di:waypoint x="833" y="170" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge id="Flow_0tzyqri_di" bpmnElement="Flow_0tzyqri"> + <di:waypoint x="629" y="170" /> + <di:waypoint x="681" y="170" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNShape id="Activity_0er9stz_di" bpmnElement="Activity_0er9stz"> + <dc:Bounds x="681" y="130" width="100" height="80" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="Event_178omd2_di" bpmnElement="Event_0lwy8y1"> + <dc:Bounds x="833" y="152" width="36" height="36" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="Event_12u4qj5_di" bpmnElement="Event_0psf27b"> + <dc:Bounds x="593" y="152" width="36" height="36" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNEdge id="Flow_12vbpmr_di" bpmnElement="Flow_12vbpmr"> + <di:waypoint x="440" y="188" /> + <di:waypoint x="440" y="260" /> + <di:waypoint x="611" y="260" /> + <di:waypoint x="611" y="188" /> + </bpmndi:BPMNEdge> + </bpmndi:BPMNPlane> + </bpmndi:BPMNDiagram> +</bpmn:definitions> diff --git a/docs/src/.vuepress/public/photos/developer-documentation/exercise3_message_flow.svg b/docs/src/.vuepress/public/photos/developer-documentation/exercise3_message_flow.svg new file mode 100644 index 000000000..8b45bb326 --- /dev/null +++ b/docs/src/.vuepress/public/photos/developer-documentation/exercise3_message_flow.svg @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- created with bpmn-js / http://bpmn.io --> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> +<svg xmlns="http://www.w3.org/2000/svg" width="774" height="162" viewBox="123 104 774 162" version="1.1"><defs><marker id="sequenceflow-end-white-black-b8nwy39adcp2a2ytggevv2s2b" viewBox="0 0 20 20" refX="11" refY="10" markerWidth="10" markerHeight="10" orient="auto"><path d="M 1 5 L 11 10 L 1 15 Z" style="fill: black; stroke-width: 1px; stroke-linecap: round; stroke-dasharray: 10000, 1; stroke: black;"/></marker><marker id="messageflow-end-white-black-b8nwy39adcp2a2ytggevv2s2b" viewBox="0 0 20 20" refX="8.5" refY="5" markerWidth="20" markerHeight="20" orient="auto"><path d="m 1 5 l 0 -3 l 7 3 l -7 3 z" style="fill: white; stroke-width: 1px; stroke-linecap: butt; stroke-dasharray: 10000, 1; stroke: black;"/></marker><marker id="messageflow-start-white-black-b8nwy39adcp2a2ytggevv2s2b" viewBox="0 0 20 20" refX="6" refY="6" markerWidth="20" markerHeight="20" orient="auto"><circle cx="6" cy="6" r="3.5" style="fill: white; stroke-width: 1px; stroke-linecap: round; stroke-dasharray: 10000, 1; stroke: black;"/></marker></defs><g class="djs-group"><g class="djs-element djs-shape" data-element-id="Participant_0dhadtt" style="display: block;" transform="matrix(1 0 0 1 129 110)"><g class="djs-visual"><rect x="0" y="0" width="351" height="120" rx="0" ry="0" style="stroke: black; stroke-width: 2px; fill: white; fill-opacity: 0.95;"/><polyline points="30,0 30,120 " style="fill: none; stroke: black; stroke-width: 2px;"/><text lineHeight="1.2" class="djs-label" style="font-family: Arial, sans-serif; font-size: 12px; font-weight: normal; fill: black;" transform="matrix(-1.83697e-16 -1 1 -1.83697e-16 0 120)"><tspan x="20.9765625" y="18.6">Organization 1</tspan></text></g><rect x="-6" y="-6" width="363" height="132" class="djs-outline" style="fill: none;"/><rect class="djs-hit djs-hit-click-stroke" x="0" y="0" width="351" height="120" style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;"/><rect class="djs-hit djs-hit-all" x="0" y="0" width="30" height="120" style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;"/></g><g class="djs-children"><g class="djs-group"><g class="djs-element djs-connection" data-element-id="Flow_07xocd4" style="display: block;"><g class="djs-visual"><path d="m 215,170L270,170 " style="fill: none; stroke-width: 2px; stroke: black; stroke-linejoin: round; marker-end: url('#sequenceflow-end-white-black-b8nwy39adcp2a2ytggevv2s2b');"/></g><polyline points="215,170 270,170 " class="djs-hit djs-hit-stroke" style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;"/><rect x="209" y="164" width="67" height="12" class="djs-outline" style="fill: none;"/></g></g><g class="djs-group"><g class="djs-element djs-connection" data-element-id="Flow_0s5758j" style="display: block;"><g class="djs-visual"><path d="m 370,170L422,170 " style="fill: none; stroke-width: 2px; stroke: black; stroke-linejoin: round; marker-end: url('#sequenceflow-end-white-black-b8nwy39adcp2a2ytggevv2s2b');"/></g><polyline points="370,170 422,170 " class="djs-hit djs-hit-stroke" style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;"/><rect x="364" y="164" width="64" height="12" class="djs-outline" style="fill: none;"/></g></g><g class="djs-group"><g class="djs-element djs-shape" data-element-id="Event_09zqce0" style="display: block;" transform="matrix(1 0 0 1 422 152)"><g class="djs-visual"><circle cx="18" cy="18" r="18" style="stroke: black; stroke-width: 4px; fill: white; fill-opacity: 0.95;"/><path d="m 8.459999999999999,11.34 l 0,12.6 l 18.900000000000002,0 l 0,-12.6 z l 9.450000000000001,5.4 l 9.450000000000001,-5.4" style="fill: black; stroke-width: 1px; stroke: white;"/></g><rect class="djs-hit djs-hit-all" x="0" y="0" width="36" height="36" style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;"/><rect x="-6" y="-6" width="48" height="48" class="djs-outline" style="fill: none;"/></g></g><g class="djs-group"><g class="djs-element djs-shape" data-element-id="Activity_0r3b2gx" style="display: block;" transform="matrix(1 0 0 1 270 130)"><g class="djs-visual"><rect x="0" y="0" width="100" height="80" rx="10" ry="10" style="stroke: black; stroke-width: 2px; fill: white; fill-opacity: 0.95;"/><text lineHeight="1.2" class="djs-label" style="font-family: Arial, sans-serif; font-size: 12px; font-weight: normal; fill: black;"><tspan x="32.65625" y="43.599999999999994">Task 1</tspan></text></g><rect class="djs-hit djs-hit-all" x="0" y="0" width="100" height="80" style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;"/><rect x="-6" y="-6" width="112" height="92" class="djs-outline" style="fill: none;"/></g></g><g class="djs-group"><g class="djs-element djs-shape" data-element-id="StartEvent_1" style="display: block;" transform="matrix(1 0 0 1 179 152)"><g class="djs-visual"><circle cx="18" cy="18" r="18" style="stroke: black; stroke-width: 2px; fill: white; fill-opacity: 0.95;"/><path d="m 8.459999999999999,11.34 l 0,12.6 l 18.900000000000002,0 l 0,-12.6 z l 9.450000000000001,5.4 l 9.450000000000001,-5.4" style="fill: white; stroke-width: 1px; stroke: black;"/></g><rect class="djs-hit djs-hit-all" x="0" y="0" width="36" height="36" style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;"/><rect x="-6" y="-6" width="48" height="48" class="djs-outline" style="fill: none;"/></g></g></g></g><g class="djs-group"><g class="djs-element djs-shape" data-element-id="Participant_0bv9zcu" style="display: block;" transform="matrix(1 0 0 1 540 110)"><g class="djs-visual"><rect x="0" y="0" width="351" height="120" rx="0" ry="0" style="stroke: black; stroke-width: 2px; fill: white; fill-opacity: 0.95;"/><polyline points="30,0 30,120 " style="fill: none; stroke: black; stroke-width: 2px;"/><text lineHeight="1.2" class="djs-label" style="font-family: Arial, sans-serif; font-size: 12px; font-weight: normal; fill: black;" transform="matrix(-1.83697e-16 -1 1 -1.83697e-16 0 120)"><tspan x="20.9765625" y="18.6">Organization 2</tspan></text></g><rect x="-6" y="-6" width="363" height="132" class="djs-outline" style="fill: none;"/><rect class="djs-hit djs-hit-click-stroke" x="0" y="0" width="351" height="120" style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;"/><rect class="djs-hit djs-hit-all" x="0" y="0" width="30" height="120" style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;"/></g><g class="djs-children"><g class="djs-group"><g class="djs-element djs-connection" data-element-id="Flow_1hk1a7w" style="display: block;"><g class="djs-visual"><path d="m 781,170L833,170 " style="fill: none; stroke-width: 2px; stroke: black; stroke-linejoin: round; marker-end: url('#sequenceflow-end-white-black-b8nwy39adcp2a2ytggevv2s2b');"/></g><polyline points="781,170 833,170 " class="djs-hit djs-hit-stroke" style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;"/><rect x="775" y="164" width="64" height="12" class="djs-outline" style="fill: none;"/></g></g><g class="djs-group"><g class="djs-element djs-connection" data-element-id="Flow_0tzyqri" style="display: block;"><g class="djs-visual"><path d="m 629,170L681,170 " style="fill: none; stroke-width: 2px; stroke: black; stroke-linejoin: round; marker-end: url('#sequenceflow-end-white-black-b8nwy39adcp2a2ytggevv2s2b');"/></g><polyline points="629,170 681,170 " class="djs-hit djs-hit-stroke" style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;"/><rect x="623" y="164" width="64" height="12" class="djs-outline" style="fill: none;"/></g></g><g class="djs-group"><g class="djs-element djs-shape" data-element-id="Activity_0er9stz" style="display: block;" transform="matrix(1 0 0 1 681 130)"><g class="djs-visual"><rect x="0" y="0" width="100" height="80" rx="10" ry="10" style="stroke: black; stroke-width: 2px; fill: white; fill-opacity: 0.95;"/><text lineHeight="1.2" class="djs-label" style="font-family: Arial, sans-serif; font-size: 12px; font-weight: normal; fill: black;"><tspan x="32.65625" y="43.599999999999994">Task 2</tspan></text></g><rect class="djs-hit djs-hit-all" x="0" y="0" width="100" height="80" style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;"/><rect x="-6" y="-6" width="112" height="92" class="djs-outline" style="fill: none;"/></g></g><g class="djs-group"><g class="djs-element djs-shape" data-element-id="Event_0lwy8y1" style="display: block;" transform="matrix(1 0 0 1 833 152)"><g class="djs-visual"><circle cx="18" cy="18" r="18" style="stroke: black; stroke-width: 4px; fill: white; fill-opacity: 0.95;"/></g><rect class="djs-hit djs-hit-all" x="0" y="0" width="36" height="36" style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;"/><rect x="-6" y="-6" width="48" height="48" class="djs-outline" style="fill: none;"/></g></g><g class="djs-group"><g class="djs-element djs-shape" data-element-id="Event_0psf27b" style="display: block;" transform="matrix(1 0 0 1 593 152)"><g class="djs-visual"><circle cx="18" cy="18" r="18" style="stroke: black; stroke-width: 2px; fill: white; fill-opacity: 0.95;"/><path d="m 8.459999999999999,11.34 l 0,12.6 l 18.900000000000002,0 l 0,-12.6 z l 9.450000000000001,5.4 l 9.450000000000001,-5.4" style="fill: white; stroke-width: 1px; stroke: black;"/></g><rect class="djs-hit djs-hit-all" x="0" y="0" width="36" height="36" style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;"/><rect x="-6" y="-6" width="48" height="48" class="djs-outline" style="fill: none;"/></g></g></g></g><g class="djs-group"><g class="djs-element djs-connection" data-element-id="Flow_12vbpmr" style="display: block;"><g class="djs-visual"><path d="m 440,188L440,260 L611,260 L611,188 " style="fill: none; stroke-width: 1.5px; stroke: black; marker-end: url('#messageflow-end-white-black-b8nwy39adcp2a2ytggevv2s2b'); marker-start: url('#messageflow-start-white-black-b8nwy39adcp2a2ytggevv2s2b'); stroke-dasharray: 10, 12; stroke-linecap: round; stroke-linejoin: round;"/></g><polyline points="440,188 440,260 611,260 611,188 " class="djs-hit djs-hit-stroke" style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;"/><rect x="434" y="182" width="183" height="84" class="djs-outline" style="fill: none;"/></g></g></svg> \ No newline at end of file diff --git a/docs/src/.vuepress/public/photos/developer-documentation/exercise3_message_flow_inverted.svg b/docs/src/.vuepress/public/photos/developer-documentation/exercise3_message_flow_inverted.svg new file mode 100644 index 000000000..267c4e969 --- /dev/null +++ b/docs/src/.vuepress/public/photos/developer-documentation/exercise3_message_flow_inverted.svg @@ -0,0 +1,678 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="774" + height="162" + viewBox="123 104 774 162" + version="1.1" + id="svg203" + sodipodi:docname="exercise3_message_flow_inverted.svg" + inkscape:version="1.0.1 (3bc2e813f5, 2020-09-07)"> + <metadata + id="metadata207"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title></dc:title> + </cc:Work> + </rdf:RDF> + </metadata> + <sodipodi:namedview + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1" + objecttolerance="10" + gridtolerance="10" + guidetolerance="10" + inkscape:pageopacity="0" + inkscape:pageshadow="2" + inkscape:window-width="3840" + inkscape:window-height="2081" + id="namedview205" + showgrid="false" + inkscape:zoom="1.5581395" + inkscape:cx="387" + inkscape:cy="81" + inkscape:window-x="-9" + inkscape:window-y="-9" + inkscape:window-maximized="1" + inkscape:current-layer="svg203" /> + <defs + id="defs11"> + <marker + id="sequenceflow-end-white-black-b8nwy39adcp2a2ytggevv2s2b" + viewBox="0 0 20 20" + refX="11" + refY="10" + markerWidth="10" + markerHeight="10" + orient="auto"> + <path + d="M 1 5 L 11 10 L 1 15 Z" + style="fill: black; stroke-width: 1px; stroke-linecap: round; stroke-dasharray: 10000, 1; stroke: black;" + id="path2" /> + </marker> + <marker + id="messageflow-end-white-black-b8nwy39adcp2a2ytggevv2s2b" + viewBox="0 0 20 20" + refX="8.5" + refY="5" + markerWidth="20" + markerHeight="20" + orient="auto"> + <path + d="m 1 5 l 0 -3 l 7 3 l -7 3 z" + style="fill: white; stroke-width: 1px; stroke-linecap: butt; stroke-dasharray: 10000, 1; stroke: black;" + id="path5" /> + </marker> + <marker + id="messageflow-start-white-black-b8nwy39adcp2a2ytggevv2s2b" + viewBox="0 0 20 20" + refX="6" + refY="6" + markerWidth="20" + markerHeight="20" + orient="auto"> + <circle + cx="6" + cy="6" + r="3.5" + style="fill: white; stroke-width: 1px; stroke-linecap: round; stroke-dasharray: 10000, 1; stroke: black;" + id="circle8" /> + </marker> + <filter + style="color-interpolation-filters:sRGB;" + inkscape:label="Invert" + id="filter1342"> + <feColorMatrix + type="hueRotate" + values="180" + result="color1" + id="feColorMatrix1338" /> + <feColorMatrix + values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 -0.21 -0.72 -0.07 1.7994 0 " + result="color2" + id="feColorMatrix1340" /> + </filter> + <filter + style="color-interpolation-filters:sRGB;" + inkscape:label="Invert" + id="filter1348"> + <feColorMatrix + type="hueRotate" + values="180" + result="color1" + id="feColorMatrix1344" /> + <feColorMatrix + values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 -0.21 -0.72 -0.07 1.7994 0 " + result="color2" + id="feColorMatrix1346" /> + </filter> + <filter + style="color-interpolation-filters:sRGB;" + inkscape:label="Invert" + id="filter1354"> + <feColorMatrix + type="hueRotate" + values="180" + result="color1" + id="feColorMatrix1350" /> + <feColorMatrix + values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 -0.21 -0.72 -0.07 1.7994 0 " + result="color2" + id="feColorMatrix1352" /> + </filter> + </defs> + <g + class="djs-group" + id="g101" + style="filter:url(#filter1354)"> + <g + class="djs-element djs-shape" + data-element-id="Participant_0dhadtt" + style="display: block;" + transform="matrix(1 0 0 1 129 110)" + id="g29"> + <g + class="djs-visual" + id="g21"> + <rect + x="0" + y="0" + width="351" + height="120" + rx="0" + ry="0" + style="stroke: black; stroke-width: 2px; fill: white; fill-opacity: 0.95;" + id="rect13" /> + <polyline + points="30,0 30,120 " + style="fill: none; stroke: black; stroke-width: 2px;" + id="polyline15" /> + <text + lineHeight="1.2" + class="djs-label" + style="font-family: Arial, sans-serif; font-size: 12px; font-weight: normal; fill: black;" + transform="matrix(-1.83697e-16 -1 1 -1.83697e-16 0 120)" + id="text19"><tspan + x="20.9765625" + y="18.6" + id="tspan17">Organization 1</tspan></text> + </g> + <rect + x="-6" + y="-6" + width="363" + height="132" + class="djs-outline" + style="fill: none;" + id="rect23" /> + <rect + class="djs-hit djs-hit-click-stroke" + x="0" + y="0" + width="351" + height="120" + style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;" + id="rect25" /> + <rect + class="djs-hit djs-hit-all" + x="0" + y="0" + width="30" + height="120" + style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;" + id="rect27" /> + </g> + <g + class="djs-children" + id="g99"> + <g + class="djs-group" + id="g41"> + <g + class="djs-element djs-connection" + data-element-id="Flow_07xocd4" + style="display: block;" + id="g39"> + <g + class="djs-visual" + id="g33"> + <path + d="m 215,170L270,170 " + style="fill: none; stroke-width: 2px; stroke: black; stroke-linejoin: round; marker-end: url('#sequenceflow-end-white-black-b8nwy39adcp2a2ytggevv2s2b');" + id="path31" /> + </g> + <polyline + points="215,170 270,170 " + class="djs-hit djs-hit-stroke" + style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;" + id="polyline35" /> + <rect + x="209" + y="164" + width="67" + height="12" + class="djs-outline" + style="fill: none;" + id="rect37" /> + </g> + </g> + <g + class="djs-group" + id="g53"> + <g + class="djs-element djs-connection" + data-element-id="Flow_0s5758j" + style="display: block;" + id="g51"> + <g + class="djs-visual" + id="g45"> + <path + d="m 370,170L422,170 " + style="fill: none; stroke-width: 2px; stroke: black; stroke-linejoin: round; marker-end: url('#sequenceflow-end-white-black-b8nwy39adcp2a2ytggevv2s2b');" + id="path43" /> + </g> + <polyline + points="370,170 422,170 " + class="djs-hit djs-hit-stroke" + style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;" + id="polyline47" /> + <rect + x="364" + y="164" + width="64" + height="12" + class="djs-outline" + style="fill: none;" + id="rect49" /> + </g> + </g> + <g + class="djs-group" + id="g67"> + <g + class="djs-element djs-shape" + data-element-id="Event_09zqce0" + style="display: block;" + transform="matrix(1 0 0 1 422 152)" + id="g65"> + <g + class="djs-visual" + id="g59"> + <circle + cx="18" + cy="18" + r="18" + style="stroke: black; stroke-width: 4px; fill: white; fill-opacity: 0.95;" + id="circle55" /> + <path + d="m 8.459999999999999,11.34 l 0,12.6 l 18.900000000000002,0 l 0,-12.6 z l 9.450000000000001,5.4 l 9.450000000000001,-5.4" + style="fill: black; stroke-width: 1px; stroke: white;" + id="path57" /> + </g> + <rect + class="djs-hit djs-hit-all" + x="0" + y="0" + width="36" + height="36" + style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;" + id="rect61" /> + <rect + x="-6" + y="-6" + width="48" + height="48" + class="djs-outline" + style="fill: none;" + id="rect63" /> + </g> + </g> + <g + class="djs-group" + id="g83"> + <g + class="djs-element djs-shape" + data-element-id="Activity_0r3b2gx" + style="display: block;" + transform="matrix(1 0 0 1 270 130)" + id="g81"> + <g + class="djs-visual" + id="g75"> + <rect + x="0" + y="0" + width="100" + height="80" + rx="10" + ry="10" + style="stroke: black; stroke-width: 2px; fill: white; fill-opacity: 0.95;" + id="rect69" /> + <text + lineHeight="1.2" + class="djs-label" + style="font-family: Arial, sans-serif; font-size: 12px; font-weight: normal; fill: black;" + id="text73"><tspan + x="32.65625" + y="43.599999999999994" + id="tspan71">Task 1</tspan></text> + </g> + <rect + class="djs-hit djs-hit-all" + x="0" + y="0" + width="100" + height="80" + style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;" + id="rect77" /> + <rect + x="-6" + y="-6" + width="112" + height="92" + class="djs-outline" + style="fill: none;" + id="rect79" /> + </g> + </g> + <g + class="djs-group" + id="g97"> + <g + class="djs-element djs-shape" + data-element-id="StartEvent_1" + style="display: block;" + transform="matrix(1 0 0 1 179 152)" + id="g95"> + <g + class="djs-visual" + id="g89"> + <circle + cx="18" + cy="18" + r="18" + style="stroke: black; stroke-width: 2px; fill: white; fill-opacity: 0.95;" + id="circle85" /> + <path + d="m 8.459999999999999,11.34 l 0,12.6 l 18.900000000000002,0 l 0,-12.6 z l 9.450000000000001,5.4 l 9.450000000000001,-5.4" + style="fill: white; stroke-width: 1px; stroke: black;" + id="path87" /> + </g> + <rect + class="djs-hit djs-hit-all" + x="0" + y="0" + width="36" + height="36" + style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;" + id="rect91" /> + <rect + x="-6" + y="-6" + width="48" + height="48" + class="djs-outline" + style="fill: none;" + id="rect93" /> + </g> + </g> + </g> + </g> + <g + class="djs-group" + id="g189" + style="filter:url(#filter1348)"> + <g + class="djs-element djs-shape" + data-element-id="Participant_0bv9zcu" + style="display: block;" + transform="matrix(1 0 0 1 540 110)" + id="g119"> + <g + class="djs-visual" + id="g111"> + <rect + x="0" + y="0" + width="351" + height="120" + rx="0" + ry="0" + style="stroke: black; stroke-width: 2px; fill: white; fill-opacity: 0.95;" + id="rect103" /> + <polyline + points="30,0 30,120 " + style="fill: none; stroke: black; stroke-width: 2px;" + id="polyline105" /> + <text + lineHeight="1.2" + class="djs-label" + style="font-family: Arial, sans-serif; font-size: 12px; font-weight: normal; fill: black;" + transform="matrix(-1.83697e-16 -1 1 -1.83697e-16 0 120)" + id="text109"><tspan + x="20.9765625" + y="18.6" + id="tspan107">Organization 2</tspan></text> + </g> + <rect + x="-6" + y="-6" + width="363" + height="132" + class="djs-outline" + style="fill: none;" + id="rect113" /> + <rect + class="djs-hit djs-hit-click-stroke" + x="0" + y="0" + width="351" + height="120" + style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;" + id="rect115" /> + <rect + class="djs-hit djs-hit-all" + x="0" + y="0" + width="30" + height="120" + style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;" + id="rect117" /> + </g> + <g + class="djs-children" + id="g187"> + <g + class="djs-group" + id="g131"> + <g + class="djs-element djs-connection" + data-element-id="Flow_1hk1a7w" + style="display: block;" + id="g129"> + <g + class="djs-visual" + id="g123"> + <path + d="m 781,170L833,170 " + style="fill: none; stroke-width: 2px; stroke: black; stroke-linejoin: round; marker-end: url('#sequenceflow-end-white-black-b8nwy39adcp2a2ytggevv2s2b');" + id="path121" /> + </g> + <polyline + points="781,170 833,170 " + class="djs-hit djs-hit-stroke" + style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;" + id="polyline125" /> + <rect + x="775" + y="164" + width="64" + height="12" + class="djs-outline" + style="fill: none;" + id="rect127" /> + </g> + </g> + <g + class="djs-group" + id="g143"> + <g + class="djs-element djs-connection" + data-element-id="Flow_0tzyqri" + style="display: block;" + id="g141"> + <g + class="djs-visual" + id="g135"> + <path + d="m 629,170L681,170 " + style="fill: none; stroke-width: 2px; stroke: black; stroke-linejoin: round; marker-end: url('#sequenceflow-end-white-black-b8nwy39adcp2a2ytggevv2s2b');" + id="path133" /> + </g> + <polyline + points="629,170 681,170 " + class="djs-hit djs-hit-stroke" + style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;" + id="polyline137" /> + <rect + x="623" + y="164" + width="64" + height="12" + class="djs-outline" + style="fill: none;" + id="rect139" /> + </g> + </g> + <g + class="djs-group" + id="g159"> + <g + class="djs-element djs-shape" + data-element-id="Activity_0er9stz" + style="display: block;" + transform="matrix(1 0 0 1 681 130)" + id="g157"> + <g + class="djs-visual" + id="g151"> + <rect + x="0" + y="0" + width="100" + height="80" + rx="10" + ry="10" + style="stroke: black; stroke-width: 2px; fill: white; fill-opacity: 0.95;" + id="rect145" /> + <text + lineHeight="1.2" + class="djs-label" + style="font-family: Arial, sans-serif; font-size: 12px; font-weight: normal; fill: black;" + id="text149"><tspan + x="32.65625" + y="43.599999999999994" + id="tspan147">Task 2</tspan></text> + </g> + <rect + class="djs-hit djs-hit-all" + x="0" + y="0" + width="100" + height="80" + style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;" + id="rect153" /> + <rect + x="-6" + y="-6" + width="112" + height="92" + class="djs-outline" + style="fill: none;" + id="rect155" /> + </g> + </g> + <g + class="djs-group" + id="g171"> + <g + class="djs-element djs-shape" + data-element-id="Event_0lwy8y1" + style="display: block;" + transform="matrix(1 0 0 1 833 152)" + id="g169"> + <g + class="djs-visual" + id="g163"> + <circle + cx="18" + cy="18" + r="18" + style="stroke: black; stroke-width: 4px; fill: white; fill-opacity: 0.95;" + id="circle161" /> + </g> + <rect + class="djs-hit djs-hit-all" + x="0" + y="0" + width="36" + height="36" + style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;" + id="rect165" /> + <rect + x="-6" + y="-6" + width="48" + height="48" + class="djs-outline" + style="fill: none;" + id="rect167" /> + </g> + </g> + <g + class="djs-group" + id="g185"> + <g + class="djs-element djs-shape" + data-element-id="Event_0psf27b" + style="display: block;" + transform="matrix(1 0 0 1 593 152)" + id="g183"> + <g + class="djs-visual" + id="g177"> + <circle + cx="18" + cy="18" + r="18" + style="stroke: black; stroke-width: 2px; fill: white; fill-opacity: 0.95;" + id="circle173" /> + <path + d="m 8.459999999999999,11.34 l 0,12.6 l 18.900000000000002,0 l 0,-12.6 z l 9.450000000000001,5.4 l 9.450000000000001,-5.4" + style="fill: white; stroke-width: 1px; stroke: black;" + id="path175" /> + </g> + <rect + class="djs-hit djs-hit-all" + x="0" + y="0" + width="36" + height="36" + style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;" + id="rect179" /> + <rect + x="-6" + y="-6" + width="48" + height="48" + class="djs-outline" + style="fill: none;" + id="rect181" /> + </g> + </g> + </g> + </g> + <g + class="djs-group" + id="g201" + style="filter:url(#filter1342)"> + <g + class="djs-element djs-connection" + data-element-id="Flow_12vbpmr" + style="display: block;" + id="g199"> + <g + class="djs-visual" + id="g193"> + <path + d="m 440,188L440,260 L611,260 L611,188 " + style="fill: none; stroke-width: 1.5px; stroke: black; marker-end: url('#messageflow-end-white-black-b8nwy39adcp2a2ytggevv2s2b'); marker-start: url('#messageflow-start-white-black-b8nwy39adcp2a2ytggevv2s2b'); stroke-dasharray: 10, 12; stroke-linecap: round; stroke-linejoin: round;" + id="path191" /> + </g> + <polyline + points="440,188 440,260 611,260 611,188 " + class="djs-hit djs-hit-stroke" + style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;" + id="polyline195" /> + <rect + x="434" + y="182" + width="183" + height="84" + class="djs-outline" + style="fill: none;" + id="rect197" /> + </g> + </g> +</svg> diff --git a/docs/src/.vuepress/public/photos/developer-documentation/exercise5_event_based_gateway.bpmn b/docs/src/.vuepress/public/photos/developer-documentation/exercise5_event_based_gateway.bpmn new file mode 100644 index 000000000..8e2ae90b6 --- /dev/null +++ b/docs/src/.vuepress/public/photos/developer-documentation/exercise5_event_based_gateway.bpmn @@ -0,0 +1,167 @@ +<?xml version="1.0" encoding="UTF-8"?> +<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:modeler="http://camunda.org/schema/modeler/1.0" id="Definitions_0tk7cp7" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="4.12.0" modeler:executionPlatform="Camunda Platform" modeler:executionPlatformVersion="7.15.0"> + <bpmn:collaboration id="Collaboration_05uc86r"> + <bpmn:participant id="Participant_1u3es88" name="Organization 1" processRef="Process_0fb99l2" /> + <bpmn:participant id="Participant_0h427kw" name="Organization 2" processRef="Process_0zdj0xt" /> + <bpmn:messageFlow id="Flow_0sswg90" sourceRef="Event_1ndrm5j" targetRef="Participant_0h427kw" /> + <bpmn:messageFlow id="Flow_1wjv8rh" sourceRef="Participant_0h427kw" targetRef="Event_0qbztd3" /> + <bpmn:messageFlow id="Flow_0j7hwxl" sourceRef="Participant_0h427kw" targetRef="Event_0pq5qbd" /> + </bpmn:collaboration> + <bpmn:process id="Process_0fb99l2" isExecutable="true"> + <bpmn:task id="Activity_1qh9sf8" name="Task 1"> + <bpmn:incoming>Flow_1vux1af</bpmn:incoming> + <bpmn:outgoing>Flow_1i7hh0u</bpmn:outgoing> + </bpmn:task> + <bpmn:eventBasedGateway id="Gateway_0bsqjma"> + <bpmn:incoming>Flow_1cwt97i</bpmn:incoming> + <bpmn:outgoing>Flow_19hvbdm</bpmn:outgoing> + <bpmn:outgoing>Flow_1pre2mk</bpmn:outgoing> + <bpmn:outgoing>Flow_1bf7gvl</bpmn:outgoing> + </bpmn:eventBasedGateway> + <bpmn:intermediateCatchEvent id="Event_0qbztd3"> + <bpmn:incoming>Flow_19hvbdm</bpmn:incoming> + <bpmn:outgoing>Flow_0fn66bz</bpmn:outgoing> + <bpmn:messageEventDefinition id="MessageEventDefinition_0n8fufh" /> + </bpmn:intermediateCatchEvent> + <bpmn:endEvent id="Event_1pwd0kq" name="Option A"> + <bpmn:incoming>Flow_0fn66bz</bpmn:incoming> + </bpmn:endEvent> + <bpmn:endEvent id="Event_1voo3le" name="Option B"> + <bpmn:incoming>Flow_1qeyly0</bpmn:incoming> + </bpmn:endEvent> + <bpmn:intermediateThrowEvent id="Event_1ndrm5j"> + <bpmn:incoming>Flow_1i7hh0u</bpmn:incoming> + <bpmn:outgoing>Flow_1cwt97i</bpmn:outgoing> + <bpmn:messageEventDefinition id="MessageEventDefinition_0kl5mue" /> + </bpmn:intermediateThrowEvent> + <bpmn:sequenceFlow id="Flow_1vux1af" sourceRef="StartEvent_1" targetRef="Activity_1qh9sf8" /> + <bpmn:sequenceFlow id="Flow_1i7hh0u" sourceRef="Activity_1qh9sf8" targetRef="Event_1ndrm5j" /> + <bpmn:sequenceFlow id="Flow_19hvbdm" sourceRef="Gateway_0bsqjma" targetRef="Event_0qbztd3" /> + <bpmn:sequenceFlow id="Flow_1pre2mk" sourceRef="Gateway_0bsqjma" targetRef="Event_0pq5qbd" /> + <bpmn:sequenceFlow id="Flow_0fn66bz" sourceRef="Event_0qbztd3" targetRef="Event_1pwd0kq" /> + <bpmn:sequenceFlow id="Flow_1qeyly0" sourceRef="Event_0pq5qbd" targetRef="Event_1voo3le" /> + <bpmn:sequenceFlow id="Flow_1cwt97i" sourceRef="Event_1ndrm5j" targetRef="Gateway_0bsqjma" /> + <bpmn:sequenceFlow id="Flow_1bf7gvl" sourceRef="Gateway_0bsqjma" targetRef="Event_18u9tw6" /> + <bpmn:intermediateCatchEvent id="Event_0pq5qbd"> + <bpmn:incoming>Flow_1pre2mk</bpmn:incoming> + <bpmn:outgoing>Flow_1qeyly0</bpmn:outgoing> + <bpmn:messageEventDefinition id="MessageEventDefinition_0ivkvzp" /> + </bpmn:intermediateCatchEvent> + <bpmn:intermediateCatchEvent id="Event_18u9tw6"> + <bpmn:incoming>Flow_1bf7gvl</bpmn:incoming> + <bpmn:outgoing>Flow_0u7wl2h</bpmn:outgoing> + <bpmn:timerEventDefinition id="TimerEventDefinition_1697w25" /> + </bpmn:intermediateCatchEvent> + <bpmn:endEvent id="Event_1uh09e9" name="Failure"> + <bpmn:incoming>Flow_0u7wl2h</bpmn:incoming> + </bpmn:endEvent> + <bpmn:sequenceFlow id="Flow_0u7wl2h" sourceRef="Event_18u9tw6" targetRef="Event_1uh09e9" /> + <bpmn:startEvent id="StartEvent_1"> + <bpmn:outgoing>Flow_1vux1af</bpmn:outgoing> + <bpmn:messageEventDefinition id="MessageEventDefinition_19ffoug" /> + </bpmn:startEvent> + </bpmn:process> + <bpmn:process id="Process_0zdj0xt" isExecutable="false" /> + <bpmndi:BPMNDiagram id="BPMNDiagram_1"> + <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Collaboration_05uc86r"> + <bpmndi:BPMNShape id="Participant_1u3es88_di" bpmnElement="Participant_1u3es88" isHorizontal="true"> + <dc:Bounds x="129" y="100" width="660" height="360" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNEdge id="Flow_1vux1af_di" bpmnElement="Flow_1vux1af"> + <di:waypoint x="215" y="177" /> + <di:waypoint x="270" y="177" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge id="Flow_1i7hh0u_di" bpmnElement="Flow_1i7hh0u"> + <di:waypoint x="370" y="177" /> + <di:waypoint x="422" y="177" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge id="Flow_19hvbdm_di" bpmnElement="Flow_19hvbdm"> + <di:waypoint x="575" y="177" /> + <di:waypoint x="632" y="177" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge id="Flow_1pre2mk_di" bpmnElement="Flow_1pre2mk"> + <di:waypoint x="550" y="202" /> + <di:waypoint x="550" y="290" /> + <di:waypoint x="632" y="290" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge id="Flow_0fn66bz_di" bpmnElement="Flow_0fn66bz"> + <di:waypoint x="668" y="177" /> + <di:waypoint x="732" y="177" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge id="Flow_1qeyly0_di" bpmnElement="Flow_1qeyly0"> + <di:waypoint x="668" y="290" /> + <di:waypoint x="732" y="290" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge id="Flow_1cwt97i_di" bpmnElement="Flow_1cwt97i"> + <di:waypoint x="458" y="177" /> + <di:waypoint x="525" y="177" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge id="Flow_1bf7gvl_di" bpmnElement="Flow_1bf7gvl"> + <di:waypoint x="550" y="202" /> + <di:waypoint x="550" y="400" /> + <di:waypoint x="632" y="400" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge id="Flow_0u7wl2h_di" bpmnElement="Flow_0u7wl2h"> + <di:waypoint x="668" y="400" /> + <di:waypoint x="732" y="400" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNShape id="Activity_1qh9sf8_di" bpmnElement="Activity_1qh9sf8"> + <dc:Bounds x="270" y="137" width="100" height="80" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="Gateway_15df8vt_di" bpmnElement="Gateway_0bsqjma"> + <dc:Bounds x="525" y="152" width="50" height="50" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="Event_0qbztd3_di" bpmnElement="Event_0qbztd3"> + <dc:Bounds x="632" y="159" width="36" height="36" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="Event_1pwd0kq_di" bpmnElement="Event_1pwd0kq"> + <dc:Bounds x="732" y="159" width="36" height="36" /> + <bpmndi:BPMNLabel> + <dc:Bounds x="729" y="202" width="44" height="14" /> + </bpmndi:BPMNLabel> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="Event_1voo3le_di" bpmnElement="Event_1voo3le"> + <dc:Bounds x="732" y="272" width="36" height="36" /> + <bpmndi:BPMNLabel> + <dc:Bounds x="729" y="315" width="43" height="14" /> + </bpmndi:BPMNLabel> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="Event_0adyu75_di" bpmnElement="Event_1ndrm5j"> + <dc:Bounds x="422" y="159" width="36" height="36" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="Event_0wivlva_di" bpmnElement="Event_0pq5qbd"> + <dc:Bounds x="632" y="272" width="36" height="36" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="Event_1sevlq3_di" bpmnElement="Event_18u9tw6"> + <dc:Bounds x="632" y="382" width="36" height="36" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="Event_1uh09e9_di" bpmnElement="Event_1uh09e9"> + <dc:Bounds x="732" y="382" width="36" height="36" /> + <bpmndi:BPMNLabel> + <dc:Bounds x="733" y="425" width="34" height="14" /> + </bpmndi:BPMNLabel> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="Event_0zf8okn_di" bpmnElement="StartEvent_1"> + <dc:Bounds x="179" y="159" width="36" height="36" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="Participant_0h427kw_di" bpmnElement="Participant_0h427kw" isHorizontal="true"> + <dc:Bounds x="890" y="100" width="300" height="360" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNEdge id="Flow_0sswg90_di" bpmnElement="Flow_0sswg90"> + <di:waypoint x="440" y="159" /> + <di:waypoint x="440" y="130" /> + <di:waypoint x="890" y="130" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge id="Flow_1wjv8rh_di" bpmnElement="Flow_1wjv8rh"> + <di:waypoint x="890" y="230" /> + <di:waypoint x="650" y="230" /> + <di:waypoint x="650" y="195" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge id="Flow_0j7hwxl_di" bpmnElement="Flow_0j7hwxl"> + <di:waypoint x="890" y="340" /> + <di:waypoint x="650" y="340" /> + <di:waypoint x="650" y="308" /> + </bpmndi:BPMNEdge> + </bpmndi:BPMNPlane> + </bpmndi:BPMNDiagram> +</bpmn:definitions> diff --git a/docs/src/.vuepress/public/photos/developer-documentation/exercise5_event_based_gateway.svg b/docs/src/.vuepress/public/photos/developer-documentation/exercise5_event_based_gateway.svg new file mode 100644 index 000000000..e4c6a2552 --- /dev/null +++ b/docs/src/.vuepress/public/photos/developer-documentation/exercise5_event_based_gateway.svg @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- created with bpmn-js / http://bpmn.io --> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> +<svg xmlns="http://www.w3.org/2000/svg" width="1073" height="372" viewBox="123 94 1073 372" version="1.1"><defs><marker id="sequenceflow-end-white-black-att51rfxz5xb2bplwaj1r4xi8" viewBox="0 0 20 20" refX="11" refY="10" markerWidth="10" markerHeight="10" orient="auto"><path d="M 1 5 L 11 10 L 1 15 Z" style="fill: black; stroke-width: 1px; stroke-linecap: round; stroke-dasharray: 10000, 1; stroke: black;"/></marker><marker id="messageflow-end-white-black-att51rfxz5xb2bplwaj1r4xi8" viewBox="0 0 20 20" refX="8.5" refY="5" markerWidth="20" markerHeight="20" orient="auto"><path d="m 1 5 l 0 -3 l 7 3 l -7 3 z" style="fill: white; stroke-width: 1px; stroke-linecap: butt; stroke-dasharray: 10000, 1; stroke: black;"/></marker><marker id="messageflow-start-white-black-att51rfxz5xb2bplwaj1r4xi8" viewBox="0 0 20 20" refX="6" refY="6" markerWidth="20" markerHeight="20" orient="auto"><circle cx="6" cy="6" r="3.5" style="fill: white; stroke-width: 1px; stroke-linecap: round; stroke-dasharray: 10000, 1; stroke: black;"/></marker></defs><g class="djs-group"><g class="djs-element djs-shape" data-element-id="Participant_1u3es88" style="display: block;" transform="matrix(1 0 0 1 129 100)"><g class="djs-visual"><rect x="0" y="0" width="660" height="360" rx="0" ry="0" style="stroke: black; stroke-width: 2px; fill: white; fill-opacity: 0.95;"/><polyline points="30,0 30,360 " style="fill: none; stroke: black; stroke-width: 2px;"/><text lineHeight="1.2" class="djs-label" style="font-family: Arial, sans-serif; font-size: 12px; font-weight: normal; fill: black;" transform="matrix(-1.83697e-16 -1 1 -1.83697e-16 0 360)"><tspan x="140.9765625" y="18.6">Organization 1</tspan></text></g><rect x="-6" y="-6" width="672" height="372" class="djs-outline" style="fill: none;"/><rect class="djs-hit djs-hit-click-stroke" x="0" y="0" width="660" height="360" style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;"/><rect class="djs-hit djs-hit-all" x="0" y="0" width="30" height="360" style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;"/></g><g class="djs-children"><g class="djs-group"><g class="djs-element djs-connection" data-element-id="Flow_1vux1af" style="display: block;"><g class="djs-visual"><path d="m 215,177L270,177 " style="fill: none; stroke-width: 2px; stroke: black; stroke-linejoin: round; marker-end: url('#sequenceflow-end-white-black-att51rfxz5xb2bplwaj1r4xi8');"/></g><polyline points="215,177 270,177 " class="djs-hit djs-hit-stroke" style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;"/><rect x="209" y="171" width="67" height="12" class="djs-outline" style="fill: none;"/></g></g><g class="djs-group"><g class="djs-element djs-connection" data-element-id="Flow_1i7hh0u" style="display: block;"><g class="djs-visual"><path d="m 370,177L422,177 " style="fill: none; stroke-width: 2px; stroke: black; stroke-linejoin: round; marker-end: url('#sequenceflow-end-white-black-att51rfxz5xb2bplwaj1r4xi8');"/></g><polyline points="370,177 422,177 " class="djs-hit djs-hit-stroke" style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;"/><rect x="364" y="171" width="64" height="12" class="djs-outline" style="fill: none;"/></g></g><g class="djs-group"><g class="djs-element djs-connection" data-element-id="Flow_19hvbdm" style="display: block;"><g class="djs-visual"><path d="m 575,177L632,177 " style="fill: none; stroke-width: 2px; stroke: black; stroke-linejoin: round; marker-end: url('#sequenceflow-end-white-black-att51rfxz5xb2bplwaj1r4xi8');"/></g><polyline points="575,177 632,177 " class="djs-hit djs-hit-stroke" style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;"/><rect x="569" y="171" width="69" height="12" class="djs-outline" style="fill: none;"/></g></g><g class="djs-group"><g class="djs-element djs-connection" data-element-id="Flow_1pre2mk" style="display: block;"><g class="djs-visual"><path d="m 550,202L550,290 L632,290 " style="fill: none; stroke-width: 2px; stroke: black; stroke-linejoin: round; marker-end: url('#sequenceflow-end-white-black-att51rfxz5xb2bplwaj1r4xi8');"/></g><polyline points="550,202 550,290 632,290 " class="djs-hit djs-hit-stroke" style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;"/><rect x="544" y="196" width="94" height="100" class="djs-outline" style="fill: none;"/></g></g><g class="djs-group"><g class="djs-element djs-connection" data-element-id="Flow_0fn66bz" style="display: block;"><g class="djs-visual"><path d="m 668,177L732,177 " style="fill: none; stroke-width: 2px; stroke: black; stroke-linejoin: round; marker-end: url('#sequenceflow-end-white-black-att51rfxz5xb2bplwaj1r4xi8');"/></g><polyline points="668,177 732,177 " class="djs-hit djs-hit-stroke" style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;"/><rect x="662" y="171" width="76" height="12" class="djs-outline" style="fill: none;"/></g></g><g class="djs-group"><g class="djs-element djs-connection" data-element-id="Flow_1qeyly0" style="display: block;"><g class="djs-visual"><path d="m 668,290L732,290 " style="fill: none; stroke-width: 2px; stroke: black; stroke-linejoin: round; marker-end: url('#sequenceflow-end-white-black-att51rfxz5xb2bplwaj1r4xi8');"/></g><polyline points="668,290 732,290 " class="djs-hit djs-hit-stroke" style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;"/><rect x="662" y="284" width="76" height="12" class="djs-outline" style="fill: none;"/></g></g><g class="djs-group"><g class="djs-element djs-connection" data-element-id="Flow_1cwt97i" style="display: block;"><g class="djs-visual"><path d="m 458,177L525,177 " style="fill: none; stroke-width: 2px; stroke: black; stroke-linejoin: round; marker-end: url('#sequenceflow-end-white-black-att51rfxz5xb2bplwaj1r4xi8');"/></g><polyline points="458,177 525,177 " class="djs-hit djs-hit-stroke" style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;"/><rect x="452" y="171" width="79" height="12" class="djs-outline" style="fill: none;"/></g></g><g class="djs-group"><g class="djs-element djs-connection" data-element-id="Flow_1bf7gvl" style="display: block;"><g class="djs-visual"><path d="m 550,202L550,400 L632,400 " style="fill: none; stroke-width: 2px; stroke: black; stroke-linejoin: round; marker-end: url('#sequenceflow-end-white-black-att51rfxz5xb2bplwaj1r4xi8');"/></g><polyline points="550,202 550,400 632,400 " class="djs-hit djs-hit-stroke" style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;"/><rect x="544" y="196" width="94" height="210" class="djs-outline" style="fill: none;"/></g></g><g class="djs-group"><g class="djs-element djs-connection" data-element-id="Flow_0u7wl2h" style="display: block;"><g class="djs-visual"><path d="m 668,400L732,400 " style="fill: none; stroke-width: 2px; stroke: black; stroke-linejoin: round; marker-end: url('#sequenceflow-end-white-black-att51rfxz5xb2bplwaj1r4xi8');"/></g><polyline points="668,400 732,400 " class="djs-hit djs-hit-stroke" style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;"/><rect x="662" y="394" width="76" height="12" class="djs-outline" style="fill: none;"/></g></g><g class="djs-group"><g class="djs-element djs-shape" data-element-id="Activity_1qh9sf8" style="display: block;" transform="matrix(1 0 0 1 270 137)"><g class="djs-visual"><rect x="0" y="0" width="100" height="80" rx="10" ry="10" style="stroke: black; stroke-width: 2px; fill: white; fill-opacity: 0.95;"/><text lineHeight="1.2" class="djs-label" style="font-family: Arial, sans-serif; font-size: 12px; font-weight: normal; fill: black;"><tspan x="32.65625" y="43.599999999999994">Task 1</tspan></text></g><rect class="djs-hit djs-hit-all" x="0" y="0" width="100" height="80" style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;"/><rect x="-6" y="-6" width="112" height="92" class="djs-outline" style="fill: none;"/></g></g><g class="djs-group"><g class="djs-element djs-shape" data-element-id="Gateway_0bsqjma" style="display: block;" transform="matrix(1 0 0 1 525 152)"><g class="djs-visual"><polygon points="25,0 50,25 25,50 0,25" style="stroke: black; stroke-width: 2px; fill: white; fill-opacity: 0.95;"/><circle cx="25" cy="25" r="15" style="stroke: black; stroke-width: 1px; fill: none;"/><circle cx="25" cy="25" r="12" style="stroke: black; stroke-width: 1px; fill: none;"/><path d="m 18,22 7.363636363636364,-4.909090909090909 7.363636363636364,4.909090909090909 -2.4545454545454546,9.818181818181818 -9.818181818181818,0 z" style="fill: none; stroke-width: 2px; stroke: black;"/></g><rect class="djs-hit djs-hit-all" x="0" y="0" width="50" height="50" style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;"/><rect x="-6" y="-6" width="62" height="62" class="djs-outline" style="fill: none;"/></g></g><g class="djs-group"><g class="djs-element djs-shape" data-element-id="Event_0qbztd3" style="display: block;" transform="matrix(1 0 0 1 632 159)"><g class="djs-visual"><circle cx="18" cy="18" r="18" style="stroke: black; stroke-width: 1px; fill: white; fill-opacity: 0.95;"/><circle cx="18" cy="18" r="15" style="stroke: black; stroke-width: 1px; fill: none;"/><path d="m 8.459999999999999,11.34 l 0,12.6 l 18.900000000000002,0 l 0,-12.6 z l 9.450000000000001,5.4 l 9.450000000000001,-5.4" style="fill: white; stroke-width: 1px; stroke: black;"/></g><rect class="djs-hit djs-hit-all" x="0" y="0" width="36" height="36" style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;"/><rect x="-6" y="-6" width="48" height="48" class="djs-outline" style="fill: none;"/></g></g><g class="djs-group"><g class="djs-element djs-shape" data-element-id="Event_1pwd0kq" style="display: block;" transform="matrix(1 0 0 1 732 159)"><g class="djs-visual"><circle cx="18" cy="18" r="18" style="stroke: black; stroke-width: 4px; fill: white; fill-opacity: 0.95;"/></g><rect class="djs-hit djs-hit-all" x="0" y="0" width="36" height="36" style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;"/><rect x="-6" y="-6" width="48" height="48" class="djs-outline" style="fill: none;"/></g></g><g class="djs-group"><g class="djs-element djs-shape" data-element-id="Event_1voo3le" style="display: block;" transform="matrix(1 0 0 1 732 272)"><g class="djs-visual"><circle cx="18" cy="18" r="18" style="stroke: black; stroke-width: 4px; fill: white; fill-opacity: 0.95;"/></g><rect class="djs-hit djs-hit-all" x="0" y="0" width="36" height="36" style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;"/><rect x="-6" y="-6" width="48" height="48" class="djs-outline" style="fill: none;"/></g></g><g class="djs-group"><g class="djs-element djs-shape" data-element-id="Event_1ndrm5j" style="display: block;" transform="matrix(1 0 0 1 422 159)"><g class="djs-visual"><circle cx="18" cy="18" r="18" style="stroke: black; stroke-width: 1px; fill: white; fill-opacity: 0.95;"/><circle cx="18" cy="18" r="15" style="stroke: black; stroke-width: 1px; fill: none;"/><path d="m 8.459999999999999,11.34 l 0,12.6 l 18.900000000000002,0 l 0,-12.6 z l 9.450000000000001,5.4 l 9.450000000000001,-5.4" style="fill: black; stroke-width: 1px; stroke: white;"/></g><rect class="djs-hit djs-hit-all" x="0" y="0" width="36" height="36" style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;"/><rect x="-6" y="-6" width="48" height="48" class="djs-outline" style="fill: none;"/></g></g><g class="djs-group"><g class="djs-element djs-shape" data-element-id="Event_0pq5qbd" style="display: block;" transform="matrix(1 0 0 1 632 272)"><g class="djs-visual"><circle cx="18" cy="18" r="18" style="stroke: black; stroke-width: 1px; fill: white; fill-opacity: 0.95;"/><circle cx="18" cy="18" r="15" style="stroke: black; stroke-width: 1px; fill: none;"/><path d="m 8.459999999999999,11.34 l 0,12.6 l 18.900000000000002,0 l 0,-12.6 z l 9.450000000000001,5.4 l 9.450000000000001,-5.4" style="fill: white; stroke-width: 1px; stroke: black;"/></g><rect class="djs-hit djs-hit-all" x="0" y="0" width="36" height="36" style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;"/><rect x="-6" y="-6" width="48" height="48" class="djs-outline" style="fill: none;"/></g></g><g class="djs-group"><g class="djs-element djs-shape" data-element-id="Event_18u9tw6" style="display: block;" transform="matrix(1 0 0 1 632 382)"><g class="djs-visual"><circle cx="18" cy="18" r="18" style="stroke: black; stroke-width: 1px; fill: white; fill-opacity: 0.95;"/><circle cx="18" cy="18" r="15" style="stroke: black; stroke-width: 1px; fill: none;"/><circle cx="18" cy="18" r="11" style="stroke: black; stroke-width: 2px; fill: white;"/><path d="M 18,18 l 2.25,-7.5 m -2.25,7.5 l 5.25,1.5 " style="fill: none; stroke-width: 2px; stroke: black; stroke-linecap: square;"/><path d="M 18,18 m 0,7.5 l -0,2.25 " transform="rotate(0,18,18)" style="fill: none; stroke-width: 1px; stroke: black; stroke-linecap: square;"/><path d="M 18,18 m 0,7.5 l -0,2.25 " transform="rotate(30,18,18)" style="fill: none; stroke-width: 1px; stroke: black; stroke-linecap: square;"/><path d="M 18,18 m 0,7.5 l -0,2.25 " transform="rotate(60,18,18)" style="fill: none; stroke-width: 1px; stroke: black; stroke-linecap: square;"/><path d="M 18,18 m 0,7.5 l -0,2.25 " transform="rotate(90,18,18)" style="fill: none; stroke-width: 1px; stroke: black; stroke-linecap: square;"/><path d="M 18,18 m 0,7.5 l -0,2.25 " transform="rotate(120,18,18)" style="fill: none; stroke-width: 1px; stroke: black; stroke-linecap: square;"/><path d="M 18,18 m 0,7.5 l -0,2.25 " transform="rotate(150,18,18)" style="fill: none; stroke-width: 1px; stroke: black; stroke-linecap: square;"/><path d="M 18,18 m 0,7.5 l -0,2.25 " transform="rotate(180,18,18)" style="fill: none; stroke-width: 1px; stroke: black; stroke-linecap: square;"/><path d="M 18,18 m 0,7.5 l -0,2.25 " transform="rotate(210,18,18)" style="fill: none; stroke-width: 1px; stroke: black; stroke-linecap: square;"/><path d="M 18,18 m 0,7.5 l -0,2.25 " transform="rotate(240,18,18)" style="fill: none; stroke-width: 1px; stroke: black; stroke-linecap: square;"/><path d="M 18,18 m 0,7.5 l -0,2.25 " transform="rotate(270,18,18)" style="fill: none; stroke-width: 1px; stroke: black; stroke-linecap: square;"/><path d="M 18,18 m 0,7.5 l -0,2.25 " transform="rotate(300,18,18)" style="fill: none; stroke-width: 1px; stroke: black; stroke-linecap: square;"/><path d="M 18,18 m 0,7.5 l -0,2.25 " transform="rotate(330,18,18)" style="fill: none; stroke-width: 1px; stroke: black; stroke-linecap: square;"/></g><rect class="djs-hit djs-hit-all" x="0" y="0" width="36" height="36" style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;"/><rect x="-6" y="-6" width="48" height="48" class="djs-outline" style="fill: none;"/></g></g><g class="djs-group"><g class="djs-element djs-shape" data-element-id="Event_1uh09e9" style="display: block;" transform="matrix(1 0 0 1 732 382)"><g class="djs-visual"><circle cx="18" cy="18" r="18" style="stroke: black; stroke-width: 4px; fill: white; fill-opacity: 0.95;"/></g><rect class="djs-hit djs-hit-all" x="0" y="0" width="36" height="36" style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;"/><rect x="-6" y="-6" width="48" height="48" class="djs-outline" style="fill: none;"/></g></g><g class="djs-group"><g class="djs-element djs-shape" data-element-id="Event_1uh09e9_label" style="display: block;" transform="matrix(1 0 0 1 733 425)"><g class="djs-visual"><text lineHeight="1.2" class="djs-label" style="font-family: Arial, sans-serif; font-size: 11px; font-weight: normal; fill: black;"><tspan x="0" y="9.899999999999999">Failure</tspan></text></g><rect class="djs-hit djs-hit-all" x="0" y="0" width="34" height="14" style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;"/><rect x="-6" y="-6" width="46" height="26" class="djs-outline" style="fill: none;"/></g></g><g class="djs-group"><g class="djs-element djs-shape" data-element-id="StartEvent_1" style="display: block;" transform="matrix(1 0 0 1 179 159)"><g class="djs-visual"><circle cx="18" cy="18" r="18" style="stroke: black; stroke-width: 2px; fill: white; fill-opacity: 0.95;"/><path d="m 8.459999999999999,11.34 l 0,12.6 l 18.900000000000002,0 l 0,-12.6 z l 9.450000000000001,5.4 l 9.450000000000001,-5.4" style="fill: white; stroke-width: 1px; stroke: black;"/></g><rect class="djs-hit djs-hit-all" x="0" y="0" width="36" height="36" style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;"/><rect x="-6" y="-6" width="48" height="48" class="djs-outline" style="fill: none;"/></g></g></g></g><g class="djs-group"><g class="djs-element djs-shape" data-element-id="Event_1pwd0kq_label" style="display: block;" transform="matrix(1 0 0 1 729 202)"><g class="djs-visual"><text lineHeight="1.2" class="djs-label" style="font-family: Arial, sans-serif; font-size: 11px; font-weight: normal; fill: black;"><tspan x="0" y="9.899999999999999">Option A</tspan></text></g><rect class="djs-hit djs-hit-all" x="0" y="0" width="44" height="14" style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;"/><rect x="-6" y="-6" width="56" height="26" class="djs-outline" style="fill: none;"/></g></g><g class="djs-group"><g class="djs-element djs-shape" data-element-id="Event_1voo3le_label" style="display: block;" transform="matrix(1 0 0 1 729 315)"><g class="djs-visual"><text lineHeight="1.2" class="djs-label" style="font-family: Arial, sans-serif; font-size: 11px; font-weight: normal; fill: black;"><tspan x="0" y="9.899999999999999">Option B</tspan></text></g><rect class="djs-hit djs-hit-all" x="0" y="0" width="43" height="14" style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;"/><rect x="-6" y="-6" width="55" height="26" class="djs-outline" style="fill: none;"/></g></g><g class="djs-group"><g class="djs-element djs-shape" data-element-id="Participant_0h427kw" style="display: block;" transform="matrix(1 0 0 1 890 100)"><g class="djs-visual"><rect x="0" y="0" width="300" height="360" rx="0" ry="0" style="stroke: black; stroke-width: 2px; fill: white; fill-opacity: 0.95;"/><polyline points="30,0 30,360 " style="fill: none; stroke: black; stroke-width: 2px;"/><text lineHeight="1.2" class="djs-label" style="font-family: Arial, sans-serif; font-size: 12px; font-weight: normal; fill: black;" transform="matrix(-1.83697e-16 -1 1 -1.83697e-16 0 360)"><tspan x="140.9765625" y="18.6">Organization 2</tspan></text></g><rect x="-6" y="-6" width="312" height="372" class="djs-outline" style="fill: none;"/><rect class="djs-hit djs-hit-click-stroke" x="0" y="0" width="300" height="360" style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;"/><rect class="djs-hit djs-hit-all" x="0" y="0" width="30" height="360" style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;"/></g><g class="djs-children"/></g><g class="djs-group"><g class="djs-element djs-connection" data-element-id="Flow_0sswg90" style="display: block;"><g class="djs-visual"><path d="m 440,159L440,130 L890,130 " style="fill: none; stroke-width: 1.5px; stroke: black; marker-end: url('#messageflow-end-white-black-att51rfxz5xb2bplwaj1r4xi8'); marker-start: url('#messageflow-start-white-black-att51rfxz5xb2bplwaj1r4xi8'); stroke-dasharray: 10, 12; stroke-linecap: round; stroke-linejoin: round;"/></g><polyline points="440,159 440,130 890,130 " class="djs-hit djs-hit-stroke" style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;"/><rect x="434" y="124" width="462" height="41" class="djs-outline" style="fill: none;"/></g></g><g class="djs-group"><g class="djs-element djs-connection" data-element-id="Flow_1wjv8rh" style="display: block;"><g class="djs-visual"><path d="m 890,230L650,230 L650,195 " style="fill: none; stroke-width: 1.5px; stroke: black; marker-end: url('#messageflow-end-white-black-att51rfxz5xb2bplwaj1r4xi8'); marker-start: url('#messageflow-start-white-black-att51rfxz5xb2bplwaj1r4xi8'); stroke-dasharray: 10, 12; stroke-linecap: round; stroke-linejoin: round;"/></g><polyline points="890,230 650,230 650,195 " class="djs-hit djs-hit-stroke" style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;"/><rect x="644" y="189" width="252" height="47" class="djs-outline" style="fill: none;"/></g></g><g class="djs-group"><g class="djs-element djs-connection" data-element-id="Flow_0j7hwxl" style="display: block;"><g class="djs-visual"><path d="m 890,340L650,340 L650,308 " style="fill: none; stroke-width: 1.5px; stroke: black; marker-end: url('#messageflow-end-white-black-att51rfxz5xb2bplwaj1r4xi8'); marker-start: url('#messageflow-start-white-black-att51rfxz5xb2bplwaj1r4xi8'); stroke-dasharray: 10, 12; stroke-linecap: round; stroke-linejoin: round;"/></g><polyline points="890,340 650,340 650,308 " class="djs-hit djs-hit-stroke" style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;"/><rect x="644" y="302" width="252" height="44" class="djs-outline" style="fill: none;"/></g></g></svg> \ No newline at end of file diff --git a/docs/src/.vuepress/public/photos/developer-documentation/exercise5_event_based_gateway_inverted.svg b/docs/src/.vuepress/public/photos/developer-documentation/exercise5_event_based_gateway_inverted.svg new file mode 100644 index 000000000..e7ad511b9 --- /dev/null +++ b/docs/src/.vuepress/public/photos/developer-documentation/exercise5_event_based_gateway_inverted.svg @@ -0,0 +1,1320 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="1073" + height="372" + viewBox="123 94 1073 372" + version="1.1" + id="svg417" + sodipodi:docname="exercise5_event_based_gateway_inverted.svg" + inkscape:version="1.0.1 (3bc2e813f5, 2020-09-07)"> + <metadata + id="metadata421"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title></dc:title> + </cc:Work> + </rdf:RDF> + </metadata> + <sodipodi:namedview + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1" + objecttolerance="10" + gridtolerance="10" + guidetolerance="10" + inkscape:pageopacity="0" + inkscape:pageshadow="2" + inkscape:window-width="3840" + inkscape:window-height="2081" + id="namedview419" + showgrid="false" + inkscape:zoom="1.1239515" + inkscape:cx="536.5" + inkscape:cy="186" + inkscape:window-x="-9" + inkscape:window-y="-9" + inkscape:window-maximized="1" + inkscape:current-layer="svg417" /> + <defs + id="defs11"> + <marker + id="sequenceflow-end-white-black-att51rfxz5xb2bplwaj1r4xi8" + viewBox="0 0 20 20" + refX="11" + refY="10" + markerWidth="10" + markerHeight="10" + orient="auto"> + <path + d="M 1 5 L 11 10 L 1 15 Z" + style="fill: black; stroke-width: 1px; stroke-linecap: round; stroke-dasharray: 10000, 1; stroke: black;" + id="path2" /> + </marker> + <marker + id="messageflow-end-white-black-att51rfxz5xb2bplwaj1r4xi8" + viewBox="0 0 20 20" + refX="8.5" + refY="5" + markerWidth="20" + markerHeight="20" + orient="auto"> + <path + d="m 1 5 l 0 -3 l 7 3 l -7 3 z" + style="fill: white; stroke-width: 1px; stroke-linecap: butt; stroke-dasharray: 10000, 1; stroke: black;" + id="path5" /> + </marker> + <marker + id="messageflow-start-white-black-att51rfxz5xb2bplwaj1r4xi8" + viewBox="0 0 20 20" + refX="6" + refY="6" + markerWidth="20" + markerHeight="20" + orient="auto"> + <circle + cx="6" + cy="6" + r="3.5" + style="fill: white; stroke-width: 1px; stroke-linecap: round; stroke-dasharray: 10000, 1; stroke: black;" + id="circle8" /> + </marker> + <filter + style="color-interpolation-filters:sRGB;" + inkscape:label="Invert" + id="filter1604"> + <feColorMatrix + type="hueRotate" + values="180" + result="color1" + id="feColorMatrix1600" /> + <feColorMatrix + values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 -0.21 -0.72 -0.07 1.8 0 " + result="color2" + id="feColorMatrix1602" /> + </filter> + <filter + style="color-interpolation-filters:sRGB;" + inkscape:label="Invert" + id="filter1610"> + <feColorMatrix + type="hueRotate" + values="180" + result="color1" + id="feColorMatrix1606" /> + <feColorMatrix + values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 -0.21 -0.72 -0.07 1.8 0 " + result="color2" + id="feColorMatrix1608" /> + </filter> + <filter + style="color-interpolation-filters:sRGB;" + inkscape:label="Invert" + id="filter1616"> + <feColorMatrix + type="hueRotate" + values="180" + result="color1" + id="feColorMatrix1612" /> + <feColorMatrix + values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 -0.21 -0.72 -0.07 1.8 0 " + result="color2" + id="feColorMatrix1614" /> + </filter> + <filter + style="color-interpolation-filters:sRGB;" + inkscape:label="Invert" + id="filter1622"> + <feColorMatrix + type="hueRotate" + values="180" + result="color1" + id="feColorMatrix1618" /> + <feColorMatrix + values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 -0.21 -0.72 -0.07 1.8 0 " + result="color2" + id="feColorMatrix1620" /> + </filter> + <filter + style="color-interpolation-filters:sRGB;" + inkscape:label="Invert" + id="filter1628"> + <feColorMatrix + type="hueRotate" + values="180" + result="color1" + id="feColorMatrix1624" /> + <feColorMatrix + values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 -0.21 -0.72 -0.07 1.8 0 " + result="color2" + id="feColorMatrix1626" /> + </filter> + <filter + style="color-interpolation-filters:sRGB;" + inkscape:label="Invert" + id="filter1634"> + <feColorMatrix + type="hueRotate" + values="180" + result="color1" + id="feColorMatrix1630" /> + <feColorMatrix + values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 -0.21 -0.72 -0.07 1.8 0 " + result="color2" + id="feColorMatrix1632" /> + </filter> + <filter + style="color-interpolation-filters:sRGB;" + inkscape:label="Invert" + id="filter1640"> + <feColorMatrix + type="hueRotate" + values="180" + result="color1" + id="feColorMatrix1636" /> + <feColorMatrix + values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 -0.21 -0.72 -0.07 1.8 0 " + result="color2" + id="feColorMatrix1638" /> + </filter> + </defs> + <g + class="djs-group" + id="g329" + style="filter:url(#filter1640)"> + <g + class="djs-element djs-shape" + data-element-id="Participant_1u3es88" + style="display: block;" + transform="matrix(1 0 0 1 129 100)" + id="g29"> + <g + class="djs-visual" + id="g21"> + <rect + x="0" + y="0" + width="660" + height="360" + rx="0" + ry="0" + style="stroke: black; stroke-width: 2px; fill: white; fill-opacity: 0.95;" + id="rect13" /> + <polyline + points="30,0 30,360 " + style="fill: none; stroke: black; stroke-width: 2px;" + id="polyline15" /> + <text + lineHeight="1.2" + class="djs-label" + style="font-family: Arial, sans-serif; font-size: 12px; font-weight: normal; fill: black;" + transform="matrix(-1.83697e-16 -1 1 -1.83697e-16 0 360)" + id="text19"><tspan + x="140.9765625" + y="18.6" + id="tspan17">Organization 1</tspan></text> + </g> + <rect + x="-6" + y="-6" + width="672" + height="372" + class="djs-outline" + style="fill: none;" + id="rect23" /> + <rect + class="djs-hit djs-hit-click-stroke" + x="0" + y="0" + width="660" + height="360" + style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;" + id="rect25" /> + <rect + class="djs-hit djs-hit-all" + x="0" + y="0" + width="30" + height="360" + style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;" + id="rect27" /> + </g> + <g + class="djs-children" + id="g327"> + <g + class="djs-group" + id="g41"> + <g + class="djs-element djs-connection" + data-element-id="Flow_1vux1af" + style="display: block;" + id="g39"> + <g + class="djs-visual" + id="g33"> + <path + d="m 215,177L270,177 " + style="fill: none; stroke-width: 2px; stroke: black; stroke-linejoin: round; marker-end: url('#sequenceflow-end-white-black-att51rfxz5xb2bplwaj1r4xi8');" + id="path31" /> + </g> + <polyline + points="215,177 270,177 " + class="djs-hit djs-hit-stroke" + style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;" + id="polyline35" /> + <rect + x="209" + y="171" + width="67" + height="12" + class="djs-outline" + style="fill: none;" + id="rect37" /> + </g> + </g> + <g + class="djs-group" + id="g53"> + <g + class="djs-element djs-connection" + data-element-id="Flow_1i7hh0u" + style="display: block;" + id="g51"> + <g + class="djs-visual" + id="g45"> + <path + d="m 370,177L422,177 " + style="fill: none; stroke-width: 2px; stroke: black; stroke-linejoin: round; marker-end: url('#sequenceflow-end-white-black-att51rfxz5xb2bplwaj1r4xi8');" + id="path43" /> + </g> + <polyline + points="370,177 422,177 " + class="djs-hit djs-hit-stroke" + style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;" + id="polyline47" /> + <rect + x="364" + y="171" + width="64" + height="12" + class="djs-outline" + style="fill: none;" + id="rect49" /> + </g> + </g> + <g + class="djs-group" + id="g65"> + <g + class="djs-element djs-connection" + data-element-id="Flow_19hvbdm" + style="display: block;" + id="g63"> + <g + class="djs-visual" + id="g57"> + <path + d="m 575,177L632,177 " + style="fill: none; stroke-width: 2px; stroke: black; stroke-linejoin: round; marker-end: url('#sequenceflow-end-white-black-att51rfxz5xb2bplwaj1r4xi8');" + id="path55" /> + </g> + <polyline + points="575,177 632,177 " + class="djs-hit djs-hit-stroke" + style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;" + id="polyline59" /> + <rect + x="569" + y="171" + width="69" + height="12" + class="djs-outline" + style="fill: none;" + id="rect61" /> + </g> + </g> + <g + class="djs-group" + id="g77"> + <g + class="djs-element djs-connection" + data-element-id="Flow_1pre2mk" + style="display: block;" + id="g75"> + <g + class="djs-visual" + id="g69"> + <path + d="m 550,202L550,290 L632,290 " + style="fill: none; stroke-width: 2px; stroke: black; stroke-linejoin: round; marker-end: url('#sequenceflow-end-white-black-att51rfxz5xb2bplwaj1r4xi8');" + id="path67" /> + </g> + <polyline + points="550,202 550,290 632,290 " + class="djs-hit djs-hit-stroke" + style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;" + id="polyline71" /> + <rect + x="544" + y="196" + width="94" + height="100" + class="djs-outline" + style="fill: none;" + id="rect73" /> + </g> + </g> + <g + class="djs-group" + id="g89"> + <g + class="djs-element djs-connection" + data-element-id="Flow_0fn66bz" + style="display: block;" + id="g87"> + <g + class="djs-visual" + id="g81"> + <path + d="m 668,177L732,177 " + style="fill: none; stroke-width: 2px; stroke: black; stroke-linejoin: round; marker-end: url('#sequenceflow-end-white-black-att51rfxz5xb2bplwaj1r4xi8');" + id="path79" /> + </g> + <polyline + points="668,177 732,177 " + class="djs-hit djs-hit-stroke" + style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;" + id="polyline83" /> + <rect + x="662" + y="171" + width="76" + height="12" + class="djs-outline" + style="fill: none;" + id="rect85" /> + </g> + </g> + <g + class="djs-group" + id="g101"> + <g + class="djs-element djs-connection" + data-element-id="Flow_1qeyly0" + style="display: block;" + id="g99"> + <g + class="djs-visual" + id="g93"> + <path + d="m 668,290L732,290 " + style="fill: none; stroke-width: 2px; stroke: black; stroke-linejoin: round; marker-end: url('#sequenceflow-end-white-black-att51rfxz5xb2bplwaj1r4xi8');" + id="path91" /> + </g> + <polyline + points="668,290 732,290 " + class="djs-hit djs-hit-stroke" + style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;" + id="polyline95" /> + <rect + x="662" + y="284" + width="76" + height="12" + class="djs-outline" + style="fill: none;" + id="rect97" /> + </g> + </g> + <g + class="djs-group" + id="g113"> + <g + class="djs-element djs-connection" + data-element-id="Flow_1cwt97i" + style="display: block;" + id="g111"> + <g + class="djs-visual" + id="g105"> + <path + d="m 458,177L525,177 " + style="fill: none; stroke-width: 2px; stroke: black; stroke-linejoin: round; marker-end: url('#sequenceflow-end-white-black-att51rfxz5xb2bplwaj1r4xi8');" + id="path103" /> + </g> + <polyline + points="458,177 525,177 " + class="djs-hit djs-hit-stroke" + style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;" + id="polyline107" /> + <rect + x="452" + y="171" + width="79" + height="12" + class="djs-outline" + style="fill: none;" + id="rect109" /> + </g> + </g> + <g + class="djs-group" + id="g125"> + <g + class="djs-element djs-connection" + data-element-id="Flow_1bf7gvl" + style="display: block;" + id="g123"> + <g + class="djs-visual" + id="g117"> + <path + d="m 550,202L550,400 L632,400 " + style="fill: none; stroke-width: 2px; stroke: black; stroke-linejoin: round; marker-end: url('#sequenceflow-end-white-black-att51rfxz5xb2bplwaj1r4xi8');" + id="path115" /> + </g> + <polyline + points="550,202 550,400 632,400 " + class="djs-hit djs-hit-stroke" + style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;" + id="polyline119" /> + <rect + x="544" + y="196" + width="94" + height="210" + class="djs-outline" + style="fill: none;" + id="rect121" /> + </g> + </g> + <g + class="djs-group" + id="g137"> + <g + class="djs-element djs-connection" + data-element-id="Flow_0u7wl2h" + style="display: block;" + id="g135"> + <g + class="djs-visual" + id="g129"> + <path + d="m 668,400L732,400 " + style="fill: none; stroke-width: 2px; stroke: black; stroke-linejoin: round; marker-end: url('#sequenceflow-end-white-black-att51rfxz5xb2bplwaj1r4xi8');" + id="path127" /> + </g> + <polyline + points="668,400 732,400 " + class="djs-hit djs-hit-stroke" + style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;" + id="polyline131" /> + <rect + x="662" + y="394" + width="76" + height="12" + class="djs-outline" + style="fill: none;" + id="rect133" /> + </g> + </g> + <g + class="djs-group" + id="g153"> + <g + class="djs-element djs-shape" + data-element-id="Activity_1qh9sf8" + style="display: block;" + transform="matrix(1 0 0 1 270 137)" + id="g151"> + <g + class="djs-visual" + id="g145"> + <rect + x="0" + y="0" + width="100" + height="80" + rx="10" + ry="10" + style="stroke: black; stroke-width: 2px; fill: white; fill-opacity: 0.95;" + id="rect139" /> + <text + lineHeight="1.2" + class="djs-label" + style="font-family: Arial, sans-serif; font-size: 12px; font-weight: normal; fill: black;" + id="text143"><tspan + x="32.65625" + y="43.599999999999994" + id="tspan141">Task 1</tspan></text> + </g> + <rect + class="djs-hit djs-hit-all" + x="0" + y="0" + width="100" + height="80" + style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;" + id="rect147" /> + <rect + x="-6" + y="-6" + width="112" + height="92" + class="djs-outline" + style="fill: none;" + id="rect149" /> + </g> + </g> + <g + class="djs-group" + id="g171"> + <g + class="djs-element djs-shape" + data-element-id="Gateway_0bsqjma" + style="display: block;" + transform="matrix(1 0 0 1 525 152)" + id="g169"> + <g + class="djs-visual" + id="g163"> + <polygon + points="25,0 50,25 25,50 0,25" + style="stroke: black; stroke-width: 2px; fill: white; fill-opacity: 0.95;" + id="polygon155" /> + <circle + cx="25" + cy="25" + r="15" + style="stroke: black; stroke-width: 1px; fill: none;" + id="circle157" /> + <circle + cx="25" + cy="25" + r="12" + style="stroke: black; stroke-width: 1px; fill: none;" + id="circle159" /> + <path + d="m 18,22 7.363636363636364,-4.909090909090909 7.363636363636364,4.909090909090909 -2.4545454545454546,9.818181818181818 -9.818181818181818,0 z" + style="fill: none; stroke-width: 2px; stroke: black;" + id="path161" /> + </g> + <rect + class="djs-hit djs-hit-all" + x="0" + y="0" + width="50" + height="50" + style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;" + id="rect165" /> + <rect + x="-6" + y="-6" + width="62" + height="62" + class="djs-outline" + style="fill: none;" + id="rect167" /> + </g> + </g> + <g + class="djs-group" + id="g187"> + <g + class="djs-element djs-shape" + data-element-id="Event_0qbztd3" + style="display: block;" + transform="matrix(1 0 0 1 632 159)" + id="g185"> + <g + class="djs-visual" + id="g179"> + <circle + cx="18" + cy="18" + r="18" + style="stroke: black; stroke-width: 1px; fill: white; fill-opacity: 0.95;" + id="circle173" /> + <circle + cx="18" + cy="18" + r="15" + style="stroke: black; stroke-width: 1px; fill: none;" + id="circle175" /> + <path + d="m 8.459999999999999,11.34 l 0,12.6 l 18.900000000000002,0 l 0,-12.6 z l 9.450000000000001,5.4 l 9.450000000000001,-5.4" + style="fill: white; stroke-width: 1px; stroke: black;" + id="path177" /> + </g> + <rect + class="djs-hit djs-hit-all" + x="0" + y="0" + width="36" + height="36" + style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;" + id="rect181" /> + <rect + x="-6" + y="-6" + width="48" + height="48" + class="djs-outline" + style="fill: none;" + id="rect183" /> + </g> + </g> + <g + class="djs-group" + id="g199"> + <g + class="djs-element djs-shape" + data-element-id="Event_1pwd0kq" + style="display: block;" + transform="matrix(1 0 0 1 732 159)" + id="g197"> + <g + class="djs-visual" + id="g191"> + <circle + cx="18" + cy="18" + r="18" + style="stroke: black; stroke-width: 4px; fill: white; fill-opacity: 0.95;" + id="circle189" /> + </g> + <rect + class="djs-hit djs-hit-all" + x="0" + y="0" + width="36" + height="36" + style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;" + id="rect193" /> + <rect + x="-6" + y="-6" + width="48" + height="48" + class="djs-outline" + style="fill: none;" + id="rect195" /> + </g> + </g> + <g + class="djs-group" + id="g211"> + <g + class="djs-element djs-shape" + data-element-id="Event_1voo3le" + style="display: block;" + transform="matrix(1 0 0 1 732 272)" + id="g209"> + <g + class="djs-visual" + id="g203"> + <circle + cx="18" + cy="18" + r="18" + style="stroke: black; stroke-width: 4px; fill: white; fill-opacity: 0.95;" + id="circle201" /> + </g> + <rect + class="djs-hit djs-hit-all" + x="0" + y="0" + width="36" + height="36" + style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;" + id="rect205" /> + <rect + x="-6" + y="-6" + width="48" + height="48" + class="djs-outline" + style="fill: none;" + id="rect207" /> + </g> + </g> + <g + class="djs-group" + id="g227"> + <g + class="djs-element djs-shape" + data-element-id="Event_1ndrm5j" + style="display: block;" + transform="matrix(1 0 0 1 422 159)" + id="g225"> + <g + class="djs-visual" + id="g219"> + <circle + cx="18" + cy="18" + r="18" + style="stroke: black; stroke-width: 1px; fill: white; fill-opacity: 0.95;" + id="circle213" /> + <circle + cx="18" + cy="18" + r="15" + style="stroke: black; stroke-width: 1px; fill: none;" + id="circle215" /> + <path + d="m 8.459999999999999,11.34 l 0,12.6 l 18.900000000000002,0 l 0,-12.6 z l 9.450000000000001,5.4 l 9.450000000000001,-5.4" + style="fill: black; stroke-width: 1px; stroke: white;" + id="path217" /> + </g> + <rect + class="djs-hit djs-hit-all" + x="0" + y="0" + width="36" + height="36" + style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;" + id="rect221" /> + <rect + x="-6" + y="-6" + width="48" + height="48" + class="djs-outline" + style="fill: none;" + id="rect223" /> + </g> + </g> + <g + class="djs-group" + id="g243"> + <g + class="djs-element djs-shape" + data-element-id="Event_0pq5qbd" + style="display: block;" + transform="matrix(1 0 0 1 632 272)" + id="g241"> + <g + class="djs-visual" + id="g235"> + <circle + cx="18" + cy="18" + r="18" + style="stroke: black; stroke-width: 1px; fill: white; fill-opacity: 0.95;" + id="circle229" /> + <circle + cx="18" + cy="18" + r="15" + style="stroke: black; stroke-width: 1px; fill: none;" + id="circle231" /> + <path + d="m 8.459999999999999,11.34 l 0,12.6 l 18.900000000000002,0 l 0,-12.6 z l 9.450000000000001,5.4 l 9.450000000000001,-5.4" + style="fill: white; stroke-width: 1px; stroke: black;" + id="path233" /> + </g> + <rect + class="djs-hit djs-hit-all" + x="0" + y="0" + width="36" + height="36" + style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;" + id="rect237" /> + <rect + x="-6" + y="-6" + width="48" + height="48" + class="djs-outline" + style="fill: none;" + id="rect239" /> + </g> + </g> + <g + class="djs-group" + id="g285"> + <g + class="djs-element djs-shape" + data-element-id="Event_18u9tw6" + style="display: block;" + transform="matrix(1 0 0 1 632 382)" + id="g283"> + <g + class="djs-visual" + id="g277"> + <circle + cx="18" + cy="18" + r="18" + style="stroke: black; stroke-width: 1px; fill: white; fill-opacity: 0.95;" + id="circle245" /> + <circle + cx="18" + cy="18" + r="15" + style="stroke: black; stroke-width: 1px; fill: none;" + id="circle247" /> + <circle + cx="18" + cy="18" + r="11" + style="stroke: black; stroke-width: 2px; fill: white;" + id="circle249" /> + <path + d="M 18,18 l 2.25,-7.5 m -2.25,7.5 l 5.25,1.5 " + style="fill: none; stroke-width: 2px; stroke: black; stroke-linecap: square;" + id="path251" /> + <path + d="M 18,18 m 0,7.5 l -0,2.25 " + transform="rotate(0,18,18)" + style="fill: none; stroke-width: 1px; stroke: black; stroke-linecap: square;" + id="path253" /> + <path + d="M 18,18 m 0,7.5 l -0,2.25 " + transform="rotate(30,18,18)" + style="fill: none; stroke-width: 1px; stroke: black; stroke-linecap: square;" + id="path255" /> + <path + d="M 18,18 m 0,7.5 l -0,2.25 " + transform="rotate(60,18,18)" + style="fill: none; stroke-width: 1px; stroke: black; stroke-linecap: square;" + id="path257" /> + <path + d="M 18,18 m 0,7.5 l -0,2.25 " + transform="rotate(90,18,18)" + style="fill: none; stroke-width: 1px; stroke: black; stroke-linecap: square;" + id="path259" /> + <path + d="M 18,18 m 0,7.5 l -0,2.25 " + transform="rotate(120,18,18)" + style="fill: none; stroke-width: 1px; stroke: black; stroke-linecap: square;" + id="path261" /> + <path + d="M 18,18 m 0,7.5 l -0,2.25 " + transform="rotate(150,18,18)" + style="fill: none; stroke-width: 1px; stroke: black; stroke-linecap: square;" + id="path263" /> + <path + d="M 18,18 m 0,7.5 l -0,2.25 " + transform="rotate(180,18,18)" + style="fill: none; stroke-width: 1px; stroke: black; stroke-linecap: square;" + id="path265" /> + <path + d="M 18,18 m 0,7.5 l -0,2.25 " + transform="rotate(210,18,18)" + style="fill: none; stroke-width: 1px; stroke: black; stroke-linecap: square;" + id="path267" /> + <path + d="M 18,18 m 0,7.5 l -0,2.25 " + transform="rotate(240,18,18)" + style="fill: none; stroke-width: 1px; stroke: black; stroke-linecap: square;" + id="path269" /> + <path + d="M 18,18 m 0,7.5 l -0,2.25 " + transform="rotate(270,18,18)" + style="fill: none; stroke-width: 1px; stroke: black; stroke-linecap: square;" + id="path271" /> + <path + d="M 18,18 m 0,7.5 l -0,2.25 " + transform="rotate(300,18,18)" + style="fill: none; stroke-width: 1px; stroke: black; stroke-linecap: square;" + id="path273" /> + <path + d="M 18,18 m 0,7.5 l -0,2.25 " + transform="rotate(330,18,18)" + style="fill: none; stroke-width: 1px; stroke: black; stroke-linecap: square;" + id="path275" /> + </g> + <rect + class="djs-hit djs-hit-all" + x="0" + y="0" + width="36" + height="36" + style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;" + id="rect279" /> + <rect + x="-6" + y="-6" + width="48" + height="48" + class="djs-outline" + style="fill: none;" + id="rect281" /> + </g> + </g> + <g + class="djs-group" + id="g297"> + <g + class="djs-element djs-shape" + data-element-id="Event_1uh09e9" + style="display: block;" + transform="matrix(1 0 0 1 732 382)" + id="g295"> + <g + class="djs-visual" + id="g289"> + <circle + cx="18" + cy="18" + r="18" + style="stroke: black; stroke-width: 4px; fill: white; fill-opacity: 0.95;" + id="circle287" /> + </g> + <rect + class="djs-hit djs-hit-all" + x="0" + y="0" + width="36" + height="36" + style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;" + id="rect291" /> + <rect + x="-6" + y="-6" + width="48" + height="48" + class="djs-outline" + style="fill: none;" + id="rect293" /> + </g> + </g> + <g + class="djs-group" + id="g311"> + <g + class="djs-element djs-shape" + data-element-id="Event_1uh09e9_label" + style="display: block;" + transform="matrix(1 0 0 1 733 425)" + id="g309"> + <g + class="djs-visual" + id="g303"> + <text + lineHeight="1.2" + class="djs-label" + style="font-family: Arial, sans-serif; font-size: 11px; font-weight: normal; fill: black;" + id="text301"><tspan + x="0" + y="9.899999999999999" + id="tspan299">Failure</tspan></text> + </g> + <rect + class="djs-hit djs-hit-all" + x="0" + y="0" + width="34" + height="14" + style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;" + id="rect305" /> + <rect + x="-6" + y="-6" + width="46" + height="26" + class="djs-outline" + style="fill: none;" + id="rect307" /> + </g> + </g> + <g + class="djs-group" + id="g325"> + <g + class="djs-element djs-shape" + data-element-id="StartEvent_1" + style="display: block;" + transform="matrix(1 0 0 1 179 159)" + id="g323"> + <g + class="djs-visual" + id="g317"> + <circle + cx="18" + cy="18" + r="18" + style="stroke: black; stroke-width: 2px; fill: white; fill-opacity: 0.95;" + id="circle313" /> + <path + d="m 8.459999999999999,11.34 l 0,12.6 l 18.900000000000002,0 l 0,-12.6 z l 9.450000000000001,5.4 l 9.450000000000001,-5.4" + style="fill: white; stroke-width: 1px; stroke: black;" + id="path315" /> + </g> + <rect + class="djs-hit djs-hit-all" + x="0" + y="0" + width="36" + height="36" + style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;" + id="rect319" /> + <rect + x="-6" + y="-6" + width="48" + height="48" + class="djs-outline" + style="fill: none;" + id="rect321" /> + </g> + </g> + </g> + </g> + <g + class="djs-group" + id="g343" + style="filter:url(#filter1634)"> + <g + class="djs-element djs-shape" + data-element-id="Event_1pwd0kq_label" + style="display: block;" + transform="matrix(1 0 0 1 729 202)" + id="g341"> + <g + class="djs-visual" + id="g335"> + <text + lineHeight="1.2" + class="djs-label" + style="font-family: Arial, sans-serif; font-size: 11px; font-weight: normal; fill: black;" + id="text333"><tspan + x="0" + y="9.899999999999999" + id="tspan331">Option A</tspan></text> + </g> + <rect + class="djs-hit djs-hit-all" + x="0" + y="0" + width="44" + height="14" + style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;" + id="rect337" /> + <rect + x="-6" + y="-6" + width="56" + height="26" + class="djs-outline" + style="fill: none;" + id="rect339" /> + </g> + </g> + <g + class="djs-group" + id="g357" + style="filter:url(#filter1628)"> + <g + class="djs-element djs-shape" + data-element-id="Event_1voo3le_label" + style="display: block;" + transform="matrix(1 0 0 1 729 315)" + id="g355"> + <g + class="djs-visual" + id="g349"> + <text + lineHeight="1.2" + class="djs-label" + style="font-family: Arial, sans-serif; font-size: 11px; font-weight: normal; fill: black;" + id="text347"><tspan + x="0" + y="9.899999999999999" + id="tspan345">Option B</tspan></text> + </g> + <rect + class="djs-hit djs-hit-all" + x="0" + y="0" + width="43" + height="14" + style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;" + id="rect351" /> + <rect + x="-6" + y="-6" + width="55" + height="26" + class="djs-outline" + style="fill: none;" + id="rect353" /> + </g> + </g> + <g + class="djs-group" + id="g379" + style="filter:url(#filter1622)"> + <g + class="djs-element djs-shape" + data-element-id="Participant_0h427kw" + style="display: block;" + transform="matrix(1 0 0 1 890 100)" + id="g375"> + <g + class="djs-visual" + id="g367"> + <rect + x="0" + y="0" + width="300" + height="360" + rx="0" + ry="0" + style="stroke: black; stroke-width: 2px; fill: white; fill-opacity: 0.95;" + id="rect359" /> + <polyline + points="30,0 30,360 " + style="fill: none; stroke: black; stroke-width: 2px;" + id="polyline361" /> + <text + lineHeight="1.2" + class="djs-label" + style="font-family: Arial, sans-serif; font-size: 12px; font-weight: normal; fill: black;" + transform="matrix(-1.83697e-16 -1 1 -1.83697e-16 0 360)" + id="text365"><tspan + x="140.9765625" + y="18.6" + id="tspan363">Organization 2</tspan></text> + </g> + <rect + x="-6" + y="-6" + width="312" + height="372" + class="djs-outline" + style="fill: none;" + id="rect369" /> + <rect + class="djs-hit djs-hit-click-stroke" + x="0" + y="0" + width="300" + height="360" + style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;" + id="rect371" /> + <rect + class="djs-hit djs-hit-all" + x="0" + y="0" + width="30" + height="360" + style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;" + id="rect373" /> + </g> + <g + class="djs-children" + id="g377" /> + </g> + <g + class="djs-group" + id="g391" + style="filter:url(#filter1616)"> + <g + class="djs-element djs-connection" + data-element-id="Flow_0sswg90" + style="display: block;" + id="g389"> + <g + class="djs-visual" + id="g383"> + <path + d="m 440,159L440,130 L890,130 " + style="fill: none; stroke-width: 1.5px; stroke: black; marker-end: url('#messageflow-end-white-black-att51rfxz5xb2bplwaj1r4xi8'); marker-start: url('#messageflow-start-white-black-att51rfxz5xb2bplwaj1r4xi8'); stroke-dasharray: 10, 12; stroke-linecap: round; stroke-linejoin: round;" + id="path381" /> + </g> + <polyline + points="440,159 440,130 890,130 " + class="djs-hit djs-hit-stroke" + style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;" + id="polyline385" /> + <rect + x="434" + y="124" + width="462" + height="41" + class="djs-outline" + style="fill: none;" + id="rect387" /> + </g> + </g> + <g + class="djs-group" + id="g403" + style="filter:url(#filter1610)"> + <g + class="djs-element djs-connection" + data-element-id="Flow_1wjv8rh" + style="display: block;" + id="g401"> + <g + class="djs-visual" + id="g395"> + <path + d="m 890,230L650,230 L650,195 " + style="fill: none; stroke-width: 1.5px; stroke: black; marker-end: url('#messageflow-end-white-black-att51rfxz5xb2bplwaj1r4xi8'); marker-start: url('#messageflow-start-white-black-att51rfxz5xb2bplwaj1r4xi8'); stroke-dasharray: 10, 12; stroke-linecap: round; stroke-linejoin: round;" + id="path393" /> + </g> + <polyline + points="890,230 650,230 650,195 " + class="djs-hit djs-hit-stroke" + style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;" + id="polyline397" /> + <rect + x="644" + y="189" + width="252" + height="47" + class="djs-outline" + style="fill: none;" + id="rect399" /> + </g> + </g> + <g + class="djs-group" + id="g415" + style="filter:url(#filter1604)"> + <g + class="djs-element djs-connection" + data-element-id="Flow_0j7hwxl" + style="display: block;" + id="g413"> + <g + class="djs-visual" + id="g407"> + <path + d="m 890,340L650,340 L650,308 " + style="fill: none; stroke-width: 1.5px; stroke: black; marker-end: url('#messageflow-end-white-black-att51rfxz5xb2bplwaj1r4xi8'); marker-start: url('#messageflow-start-white-black-att51rfxz5xb2bplwaj1r4xi8'); stroke-dasharray: 10, 12; stroke-linecap: round; stroke-linejoin: round;" + id="path405" /> + </g> + <polyline + points="890,340 650,340 650,308 " + class="djs-hit djs-hit-stroke" + style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;" + id="polyline409" /> + <rect + x="644" + y="302" + width="252" + height="44" + class="djs-outline" + style="fill: none;" + id="rect411" /> + </g> + </g> +</svg> diff --git a/docs/src/.vuepress/public/photos/developer-documentation/forge_overview.png b/docs/src/.vuepress/public/photos/developer-documentation/forge_overview.png new file mode 100644 index 0000000000000000000000000000000000000000..f94299ec4d851ef8ebc073632c7a74acf33bd542 GIT binary patch literal 195635 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 h zEdYqyRTZ0L>xegjpKgaAA#zmy+m`_H?V-08tnTW2M7OB8;Lc!EhPXPluC7CdkPtXE zHHotWX6AHE>cuxqVWtz20q=X)Z%VSRTB4Cn3K_TaXc@`8`McguNZi@6y!ibatr>qJ zp#Yot3F!$^7?m^YBLVj2OBA_H?fAnS2*_skJ>9$VfvW~(HBie$N3mm4^7fVfl)?is zaOEGo?*4yH!Ni25jZNwQM1+I;|FRF>vg%fS8i=R--^hGFN_9Owue)PX=6}lSPH4k5 z<=^{?+5%X?@8)Hv2*UrI7<yA!U!UC8CMJyk&&EF%u6qXkx5y{E<)%0i6F-gr$P5BJ zJUrUE-T#v##y*XHDVhQODT_aS&4=OWwRzS4_hGwO3gIMpJ7W01jgn7!{;Ogn{8!+Z zBo%%6-#+B-aQ|UXe5LhA`@7EOQG~a_;mmZC`2R66{LnsGTK*3a2;UTyTx3&J{df4_ r*Jadqe+qOS#l-&|?Jo;>F+Ni}D9l`jMQeH@z+Xyos<KtmAHVz`hKWu_ literal 0 HcmV?d00001 diff --git a/docs/src/.vuepress/public/photos/developer-documentation/forge_requester_view.png b/docs/src/.vuepress/public/photos/developer-documentation/forge_requester_view.png new file mode 100644 index 0000000000000000000000000000000000000000..c9bff02b926fe03b1b8cbd21570f652740081f9a GIT binary patch literal 42843 zcmZU4Wl$Vl6fExU?(PyCLRg#xcXtWyEbi_O2`<6iU3PJY;O-8KLy)|Duj*O7A2ZiZ z&D5=#nmK*CJ6c6a79E8I1quoZU0zN~4GIc+;$Qy`3E|)Q)If~)Ujyx?CJTV7ohCc| zH-NL2P?UgzYDh$VGll;*Ms}9db%TPU7WnUg=GDpffr9!4k(ZLt02*E7!kgg9l16O1 zjSX$$QibhY)k=R2?|gg6=xl2)RVmP5{#^jC(6D!P75oJW8NB&Ga~$wG<A{MtH-K^~ zdYO`&z1h=}{q$;OWer4w#zP4Q6spuBZ{KA8YnkxI`3lVB|LZ7-sWg<R)P^;r1YWe9 z{}=Y(f<cTGVbYVJ$}O=8yO)$2Q`%o)4K`*xjEE?6;xTNV+cr2AC)n{`28>@z$x4MP z9}^p?J*JnQA{dlHF~uWA<lJA@`5m}EJ{l6R!sq3FuLs9aLT$^_eX$=+QI@|-f-yaZ zD%8H@_af>UfGVClK{AwLNd|B*7F`u|cK%5B!3a;q1)DX{N)@U&;y+!K(ZYvIKf9i3 z3j$A&2=gG2(C5eV(+%P9c_t0gpj)SC{9lN0wLyQ;8Xch~y@QUwTEH4zdU|C|>9?6q z&-4N4a6(7AfEct9m_s5?Jp(mWizJg-FYJ4`I8^Bh9e$ACxQTAx70G*y5}y@dza6~X zqd7-@gItT2`J&@?IB}=TG(UQVXKL(3^|%mqp_j#KI(vEozG{!59}{#<MHnZR7U=AS zREPnnT)^Ax8;gte#KhTx&XC#gL#au59X0}vsqGoU&s(1}@oAno&^~EeMv0MQ7N-Y1 z`W#a|>9r&S)5Moh=wlV()0Cj4B!Wgz>GrmL`_@_<V6(qPv^waSPb+WlCwBBXPv9ns z?XAE#ySNOGQ1&Qy%OlIglLa>v%L=JEqP6Z+aVUXg>%<co8Q;-zSC8a6D9|Pm(D^z4 zK$}zep!lYYlie(jIJWHFT{fI_i2l&`VHZzeY|R_`QGMpqrTx8<6|!+8_-zFzG4rXE zR(Zs8yi-IdIW3x+Re28x&)xswak26vDL9gUXt(S)%BO=<BV_$1?doa?KxsnN+$a;% z@WO$vXo~>3&$*&|9BqKU-gkVnaXvy@1s&sBnbN_obtQ9ftA$Oii(kA}{Fuo8Y+|=0 zrjt_tuZ=U|x+$yq-H~@|Zb<$<Q3nUcUFyUbxoJHwH!AIN-Y~M6ltFBl9vdOMQH-{6 zAS&**U!=ZOz^j-x`w+@ej&T4eLh&aza0lxCY!%cn(i6>c{V9(^oFet8y2Q+T#3bAm z_lBvDR!HtL%A8skz>S6#iIdyyUG-{(goz4TUg!gOI&!o+Y$F>}Qij1Hf+F8~@U#gD zA@F`mI);YP)_$Q}p1c{8*>Ntoc_W=-j7h25J8~VL;gMe<D<E91)5yN$oMiNt!leQS zq(wb39^0tQ{o`P4XcRKe^8QFfb(hAowQz!o<Vl_jb&?yEGJ>dpW?ntvSTbfW!iXO% ze*TqEA6rHzM;;AlZ`+}XTT`K29ond(6lV#f-XKh@hD+rzD^*X2hrsqk#?M!)FbkcL zUpTrwQU<v^*~BuU2JB``zAN$Z*q!n7+Y`|CZv2db_ttYqcaPN5jgIzJcdlJKSScci zXfT`J#q-P8i+1KD9Gw#WCiEl5<3$+F=?Yc|dwxu|$+TStn=K3AT)pjavDJn7{ggQC zeoU4~+>s3d<0P?uR%P<t{BuD56JrDhaa?}DGr{}oW4Ih0z+wVvB+o-V*#)O5FfX=U zP3+#=x}LKat)_S|Io}n*?n5`iWBsvEYN9|hRt4!<)Q07@-g1+LO}`D69^aO1y@f<% zFJ`X6|7*@hBVHfpD%^1a5}fzA3vk~IXA9%ns%H0?L)J2Yg}=@?K5)rF(#I5^rbthM z#Uv?{B(a56+vH)GTrgEN;s_e&joX?7BUe6DsZLf}l^TX-9VBT#nCvgoV6mz|_BkCc zTbT$(EH}x=oz!YZUtxM7CQjWqxe|w#=l7HGec+YqZ~dUgQ#wS$AJFnLUjA5+m!Rr# za+kjxy}h4p@K<pHIdvoUQq<h9m+)Z*4yDQL{Ok0Z61pd9W()m&W$pJHQU_`O>;#0h zUSn7~;@DqJ-Aq0gV&PKvQs~N;B^P^1wj+8o#{MSq{0rBN;p|dkL>d8P5>Z1*ve?_L z8mPJHlM_EU$fRl=4%;#fusLRsaFpiL%AXpUk3%`ItG3xM{bFTGY&DEevu%So_N)BU zsyy{+3<`ah12jQdCatoAL`fM8&2U7Y+5C+F^NKeC?ovq_&B_8UO)SQ`dMuZC1zg#9 z3zEAFjdy}__a52gXKj?K#fYpNH8v$y#_%$%nvK#8A?+obdiD;ez~uc4&T<)E0mAmL z&vI<l{o4m^0tZZm{IE6h+5NO?jqe5+M@OU(-EFyMSLzTYII2Rq=u%{Oom|b}-z>0t zz|Ma8QAtl#=H7%U*^H&QHy(Pk7SCpn%pD6O;*U7a{z4qSN?TiquNkw2n$RG=AK47s z@O+6`HT{TLT}MqD44@a^Zr=@Jtso=??paI!k*K+v?wl+_Jt`ko-AHo5zSu8G9VurR zI(8u7b)aFOqb9dH50Z=tC2kq9s;h|GIA?MdzeD|cgWvIVs)zc?iuHDMn?DccVyrSE z0=qaiG30=T)XZ(7;lu!X$&xv_iodY5jF<Uu5cq=T8|`b=Xm9qx=Sjw=2JmP>XdCW% zqwBR~xLiURjXzcWs`IC+I8jb*jf$4p*b-n%jX2$fWM5eKpqXDlCteRt2)CCCTz54> z^;A{F&n{AgXJJDoQoeKrKcZYrWlASD%1r`8uoc@(Wr!}-P$+gU<WnU?+X{csuV;4n z;mq^zI!lH<!}RDVz|#{WCiZKs9vT9yHS*nyhxKsJ>!aK2^z+$Q_lsEy35nn=zGFfq zHr<;y+cOJ6R=j`zCYgySf(Na!j8clh%<Yfhrs(5(>j}@_qd$v#+=#aVjwQhaC;hxy zW}D-hO!$%JCZyVayr*Js^%jIuYRuCVo554B<|+mFyU~aUrrRmT_0IdM?xaG{4lsu+ zx65QW2?GU@`9X=?@Yj7e2ul<*;Tkpr3FvmtwWD!H?BM5}hvkM~ogW-L(DS1cD>d4_ zU~=KGv~Dvl7;f)=qm%hAMo+e^VELvDSQ_NUeGIe3D;@VM5v)a*pEsBJcF9>eVeIRk zpbATIwDb9#7)$eVUG;NSo=hLk1B_1bE3EOgkQ>K=k#$n|@NhxkGm^}v0GaE{Az-@q zscN~FaoFrDNB#zrUm@J)E2iuS7yMG~CRCF?2t41XOBzQuPq@n1x&!pl+#gC=Va3%$ z985)85g#jM3L&a<M?vVTgqgXP1Lv{uVvDh2cbb)uz(u9-uBfVn@}#0W@^HW99NMt* z>^_hm*BgG1fb*<YVwQ@KkD~5Xn-u;LGDS~Pf~Rd}+yVU*>1%ei3pe?#Cc=QN|E5~a zo`rv>*V&6q@MrY)7+;Bot!e?UnNuxJq(TeP(j+0k0e@@78>7!kOOg)nOX(c#$~x{L zd^pfdnFOUKNWN?c;EL{8^6l(|WB3g>yBv!J^1Tg95Zm0_7r^k*#tF+TOe*Dxx>TCJ z<D5+aD>>$(5Obqzk3F4H(Lk+_T$sw6qoE-BwN;sRU0)G_jed{(E4atn21<_^?b*+Z z;PwKIB|58Gj#ZkNcE~?iZBpb%M4+o(l1`~?gOak8N_40tg6P^fVwt)dcPbH_1en&I znr5az1wMBu&fHrehi$naw@;umnjOd}jHu~JF<z;mlcNTsEg<j=VOz=8k2Z6?#>b(C z$+5IKwjUylyi-AD&a*iUUTk0neyH#(u!9Y_NN+G#pQ^_b2B;n7CdWa|VLUn1%Sly? z7|<_MhVU%zs5df9%($HRU$N)HucqE+Ly6E>N4Y-@b`J4ScM-*+ej-}p!2-eNm~z`R z{1ByW9kw*cS`R;45WRg1oT!$1r7{*>-5@uMg-4xdfojO=;@kot#6|&QEtH7x{T^O@ z-wm8o>$7zVodJG+Fpt;bz}1u_=Y%T$&UuB}*gK<!cpVZxaN`fiZ0PgBKIV=TO8nh> zD#?OpMN_BgIOPQQLkssxhYS8Kx)KqW1>EqaI8Lt;+N0w}&;lcd>0PkfiSXI?Nn;4( zQGf`t1P5RQyEc*>k-vsfD;v7!5Bl(mD(&p&-=R7ezAiKz$fw|<J9MOB-nyPp%fN4v z>ssWHv9dZ)A`wq-ve?an@;23EPDm-MSE24}Es==lr$0|uFdm*{7|EHCH>Z^iy`Aet zyPNTHj<zRie&&_R<%ghKYgbfqhcvQkmCx|N9!0I|R!8_2a(~b3)kse9d^pa!D&M0< z2f2&Ez9Os+ZIfz(?k-vi5I-Z$7Te$xEX`afF#SC0IMZeim-=QvvgQq&W_MRb2{|Mr z^u~u*n}5OFuZzoXnH5iDtd;v9`4RJG;5oy{hJnz`%ZFNlt;NA0ZZV;^M$csZ8Dlm* z-RyfIMJ}uu<O`~?JH3&j%y%Ir+(NOLcK)e`s}ByMYx?k%D6`gquo`CR9Ou3zS{%}= z>o^ZgPYH3a&l&Ut{Zz?j8g9mMC{GarGclUk3cs_^!FN2MO<fr4l)f4QF)ca*5M9dd zGB$aGr=PXo#s+a2>O?~wWRFn+AsFuKh}RGz`(}MMQb8W)aGT_sDd?F4$iHKzS*x*^ za4p+1l%_-t<etZ^^+P~JWpOUNP2R}Q?36a!EayK_9Ir)5CkT(2SbtlKL^OG5S9%s5 z42=>9r7#T!R)tdL_;*8IA^gwX>R1e69d09Ad8+YDH1pSOmHvo`t!RT60aGp&r@xk$ zO_;IGI+{oc;%JtEfwJ9XY@n?;KQIfYR_vn_wp?u)@0QcApfP)zVR=y1RUO#AY7wds zRGx~foIf=rQylMcz-eOM67t6BB4`c3rbJ1x{C2Qu5@>kEB29DyX&Uvftb%`Q&1`~( z{vZ<bp&L8MOCVBXNJbNniIOuh38Fpn;Ues2X#M(jUtzqrkSHz{5b$|e{Eg|6Qt&{| zL6F_|eyF^ce6F&CRKXS1L_^bLd9Cl}UHPt%W+@q9B5foOkFAM7ja?J{z!Iiy!qjk5 zx5=?LYp>?Is-mWYGW=`g=ACqmJ5bWK0~@7+sFuBRcP<&Wa4L4>d`2u(o8djqfF@77 zh=HI*%}LgC@B16iD`WLKC8B_`K>2T5np8HwdvZaz9+765SSn182sO$B=!!O+#9QAK zJB<WEm_$+aHrcVSF9;nqUXnlO56Oi6@Z65yqm{*9u*5pO+`#<YKtJ~zw_wEe#SlD* zS_7OPMQ92MEt{0wlO_Is)xHpuC7d(%t*XDK+b{f5TiR-H)>fu^+;_%XRg1%cTwwfS zf}UrdTu9{lb74&zZ(NBpf6DT%fjqud&gkGS3vRasP1^ZPEPW#In`<pIgMkE^MM}q% z1#|gaC^pL6^bEclG^Ss05^(cN@)k_$To}Fe9fTGeg?8OHJB{3`Dn5-m$I8VrYta$F zJ+{2X!>rdaHfo7F7m<T$_jdH114X{h#0d?<T@qCQTEU$Fh*MTn9LWnjXj?a!zsgqE z39)V)-Us0dMXBrVFdTu*s@R`(;SPEcL_{R02x)`PAI9_49o9<AE7P877$_0;RQ>10 z(6*$caCmPa&lzxj-Yk@>Rusz%E8ng-f5z8F&e;NlIy$Hiyg<?6{e;PO9@<HGYIzl$ zM#W_sDF2?aia;wtWbmBYOmJQ3?>VJP#^q@W>6(@hzVM!?VCV0pQDJZ^)`d+=TX4m5 zDCnyL(hNs%`7?w`jrl~Z2ZDcNbQ<eJytn;9LId}Yk2L3?_V$Q@UaRB7lx`?6uB9*3 znY#}iV_8AxueIcP=P(*q+zvi&gB*M;5#QbTy1#=BAVg=IC#`D38`L7XBmCt2sj1OD zw#1@~PkW2PuFT%Z_#79PEv_D?T4sv)S{g$0K*$3%aS-Q_x|8BSvgE6a#a|A4y$3>{ zPnclv*tY3@W#7$x6oz1jHD5vro*S|5x7(6%3$vv^$(=xeOy0M<EAs}I5eg~FwaDC` zTKloq5h4^sm}V)|%<)0*361xxDb^kdNCd6|h9j_B*IVg;u>cI7!>aGV=R(BUT1C<{ zZ4KwImg)P3ZvFnT@;p6b7Du+mj)+!<=#6f7rqo-A=517*jD(e_d#-K}xx9c%b>6pm zaWc_V=xwkCmAW-!cwZ0@70|s#i(>tEneayW0X!YqRgnABd;}F~hlL<HL^X)8tF5>G zvR78P7#5ohBPDYtkbd`DSaJ>R*{Uc}!_56qhqdoMgjNh<AVr>A%t0UqNl)pKlkll5 z_;H}_syzB`b=?)I0+lQk(l_imAauLlkmxn?LzP`f!UTTOzQF}%_*i~d2_@Y&75UT_ z_CkwyS_?ZdC5^Fgny~6)^-Q+*_dfEN&|M+-&*Z|n0fk2qFL|e_p6^3~)+P|2e10J7 z{7)qJO)+U*j*hqq6E>MQlH6b$F(IYQqmyIM5iDzKNoK+5;K=V?a)>=q2PejLy!76) zl&n+lpQkW7O7Eniil7`PWNw-ZaF<feoNI){DE%_9DQiq@ta`~!=37A-jL|{bG{I88 z+}7U(1@^cSGROTZwBD%@w#M9Hv&hUYGKzzZyUG?O?ll*g3hKepf~q#ur_U>+chxkB zza?pE@0!v@XfoKU358q_kQ&jP3S_-05LnV<&OiH|7A-Dm>2GXU7vX#Z9&xwx@MXOZ z{RG~mFW(GK;5In#%YSlO$M0GDLu<Nh4Ez(wxiiIiTzJ+!HcVKkSyl^PYc$=`rrbZx z+!~427@4&>fWPKGQ*EYIcKUcyhrCVH?GI%d4adElCsFpn&Lo@rKR%F=#ea?b&5k$l znIcKhyHKcs?rUn|PEDJ*Of(goa{P7hJ*ettexh!tRGV?H6!RBNrhiJ>uz3|63t>{` z;rx~homT@z>CA{%sY)X_?=x(?R-^|h|L!WG(O}ceGKaC^>z_eJ4U%{Q^|HYD`9`(s z?RspxWv7EZC%*N}nc=A9eQvu4mxG**V8r2sAyjpOFW2Qq-S|>r2z#jn9HSNG!y9fx z?R|z+e(;`?LU|!0Z46k-$7n}6%vHrZ$NK|Xy*3<Hkn<Zl(N=m2<s=8|Jmw?Oc-HTf zd-2IeIAn5DL$p6<k{tGL{`9h8MIH!4xN6mjghzooehj!zPH`aG1A#{^9f;iP7o=#W z?sj%)<)p(oMeBM#W7#mtFeOK`G;CA0C7tMCR?xX2tf{~m<j*wl3O7>sl;s{3vwwwa z3DixNtP;maBi7zJ?&X<31UjIo=ImafW>;Z=lk6_3!(`lBg(YTczj|4Q4@I|jgZNU| zec=(z&<~Rxdw>4)3(K`4E2<mW$zD8EJMjqMJ!byMNOK^cX6~iNVI-0^<n40o;;FV1 zuJkc$XFKX24}v`)IX))k`lZPg0k<LCutAa^y!DrC<bL50>F#dueLzW$D(^9rbb9A! ziGn-EJt*wRF-m!6qyT^9M#=qi*mNzhs{_@QmF4DsNzl)=5o-V(?Axg6aDBUnLhc$3 z^rYF-&2({*^#wJOyR4KJ)|30~;ZB>)^!n>Gxbl7IHk=K*LLjDlhG$%6D=M{wCX!s= z?Fw3B=34Xx+`n(e#ol4qMSkS!OVF86B?%TPX7&>CwF|txg>n^W%gRa72>K%K?;>7F zu4U75jfUL(20c+1S>pL^S~$Dh4bF1!&$amz<@5l!Oq>J5BE!v9{yG}K3MK-BOlyQq z-%d<z2=*d>RN8XEAnSRYCVFl8puexfOEP&#{46KHilzsfd&p*f4t3dvP$N-e#<#$4 zbi;DH-V?dokz=GP!N-o`_xL>R`3$I?4QQdCB*1b!K}P`hbQ?A6=~&yvB`7}DOLBU; zgzpScUi}Z>_lJLTm~(Qx|GDpgL`Q|`4A^6?$TEn69SDi%Le5d0d3Df9G;F`wEY|Y= z@pJ@f$|^YMK@4HIZN5-8BRMk=bVI!(-b=0%ND!hBC~6APZB5OUd11mOb*oa^BT}}^ z!FXv~qoF>8WlDuv<=NNC-Ht{fVaB2iNd`|FJP_vtom96Rfd%0Leup#~q?0>eOHRlS zf|0C|4K@w9H)f)V>S0oj!)#7ZLlA$w4jK<i#*fLM014xe?!rQV1T>A?QCMEUm}fdp zl$~ofP#BZ3RL9o>K3ysg*TEzeP8u0-l?WxnYeZLviAEIb##l$t1>xcTu*0(03a*&J z5LOb9_~mj-D()KfE+|$CN+6gxHiZ@IY(Jsa$Tcjr?_F%wD`7*OMozgEeMlrXWS4yx z7X*TVRSpXnps=}SX8Z}k+C2`|QUbVMtnDM*#0lz}4?HhP5Rsq4db!eBci_!nnNuf` z)j0%_{&{9qDQz0ejM58qb=<-c8Skh^MTh_<y*k1hv&lF$vd77cjy|;9sr5^<g@v%0 zQcMF&YdA~5`wuP|`wd90lw)E}*XIco2P<1wC}Bx=mhgQ2nh6OMu6u<ybF16rV(+<g z)cv@IxkL51n5)tppb2siS27VE3UwlI47`q~(2k*a0flf33I+6FpMm?TLov@U8&;wu zR3y4rw0dia068eo9h@kn4QO;cX#07wIii%9z|<!&1D2VE6xHVw96%oB&GXn@D~}%< zL*Mc+2>CL!dp1N=`}VQGH;VJ~B|*XxxWF_%9N)UpSz~JCxaX%xWew+XEyaNK>Mgz? zG3hzdBD#nk@_O!vr#ah9e`um8MyagRg$_4ro)i-E6V#gIm($~*WvMS@&}oXW2M7K) z0r^OWhdm0+Y5MVt7U26H@WSu02FGutVdJFQj%k_N)SyY(ut+rTp~L4L6$FK$>6H%^ z>ra`+h6URb^`RQw9iK_Yc$6=Q))Bns<Jg&521C~uxJ%6Gdd~<{tkcg8*)uLG7QKAz zIah}7!+KQ9b+(F`j-k{0mQjjl7^RrHpaD*|d$at;<GF=0HN(?1>^EQh=i)9U=8?=& zcy4xfMfdFQzL4?4wKGAK5;K6+9s0SN;ZHn&f9d?f*WAg0Cfb}tZM3^*>9Zb*=vi1{ zM*!!<z)DtkQW&mp&yEtN1qRP^Mtd70$gRUPas;V!%EE-ZKAD?|JTQ5v=n~6?`AK;T zg4CBjp?he>%qvu>f(VNv>-K7S5z2Mce(*0TeAxkP-FLYOenJU%b^0=t@*e}0=F@JT zpYV@>`Zrex_+NAX4=MF;t(4;5CH{+1!~Bnb`o~UHApSW;3U|#MoUS%8vBv9wX^?YY zeXb*kNAQ&8&rqOCO8Q51ZRq_-(^;$0CS*g87@1b~VnrcF2+y`|u=^|De8r2?vj!)$ z$DB6Y5CCGBe0%gAJ>Y?G5YJd_tjq!bZnkxJc=FtPZM|Y0r=)aLoKyH7n0DXJ#~Q4~ z4}4Kf_-+Yw_H+q8nMZ~`?|0;rC|wF>!~-qr4p<ehD>+8vSS!NBp}RS`O7^N=8U2XU z;o;|H;cW%k+P}SJumLJaMQLS18QVL!B_D>6fmc)4TsDKnM8Y<Lde2)uO?oO<j;?pN zg4Fj<Pa~wb#)no!rY;^XhezRJm?HUy#mb`bh*y-6WqE#NfL(Nq$l(=dn>(Dh4lBxg z8Pe__9^l_I+Y&)vH)TqswIjmCX9hlab?YU9D2nrjMP@b-Z}^6n?3wt|7o+A@xacO& z2Pbg}8_c}`1Q<l6S#z{mt+c9FM2bg-=J@$7uJjxd&bQxZ6#s%ENPDw7%s1E;OJB-w zqX$_N<BI|E9n6CO$(v09UKK5^VMT31JiIW1sh`FSX>2sfqpG}veJ+J`8rCB_Gw9Zk zF|WJ&fJ2(*ee3-;K3Vb#Z8!G?1-fiNz0C^>+xwv#-K9<#?rM6%Z&Jpda<bUF-wCtn z5bkbCI4iZnk`2?V6Tgf$+z6c^A4`^lJnST2siX%y$F0_gLBesWrv#Y9zz3{TVM~%< zelM`&cMFh*#J*zPWm9LqW3xY*>X27sR;-^Xkx`!Hs&1Z$41s+}*0_5vpBRv*ggwK5 zwxEdzh>^Q}7{p|OMZ;vI1}3Cq48QgbU6t_I8wrw%@Wv4>iQ&ldvw;ultj*sOLd%0$ z*Q60Z8aRoV;)ZBFpV7Aicu~)v!2MO;`e8mosj;oJyQ5a$etwXD7&Rb7OCz|SZ&3Id zQU_#lqc<IY#G4}%BRMP*Y_&OOxQ^$778Y<X*IS12Q3)g}G>Yspr?HSY0%cdn3pMSQ zT<$s>-SoGZ8oHJWzAPaqC!S1B*;DS=4i74p-R!hOdjNql)jC|5hLk{fa=<3F8c;IT z2k96sc!R74J#=91z~GzkkLZ`^Ar(|`y>{CE9WTA0X65i)w?gyn4S2VSS<uL|zeqhh zN)>gWif!PBEAOA@@dkbd;#aw~r7$wTz+X`Ed{+PHP{u9xf@K@XLm}Q|+=Q%sHiaxN ziYi-DQ7GvYYTB@5d=o-{e?;6$DAP{3+2aM}+_-*X9iy`J>`oc?^)lt$glwo&pniM- zMe)r5D`t`I%q!%$nsau`I82wfH(b4oJL~Dy{vMUbY$>FLOOKdn5nrckmrJJmp7?Ws z58U*XUc|N+;a-zd09e~eJUaE9fQrFz%zM;Y*<Ru^Zp5|q-?)*kj@?(vzc3=lfz#3G z&z=L0qAyn#Z!hc0M9Y0*C8F$B{(SJ?CU&z#uC?R7vk$~k5`YYRnbUlev}$O$3j&QV zR$53|7F$GXf0nhEpnVP=AY6ma6?+e^WU)DK6q>S4!_&pWIXR7j3W4=g)m1w~T1=EM z48PtVhYa_(>hL$RBlwQZ^6}tZx7`l*M?p<8y3}mK&633F<Y|WfeXtE}Tlem_=b`<o z{wj0+uLL_&4i4SaGacALIyfRUH-zqx1*_zFe8T4!;AA7-#OCBn-L>yPp+`V%qYR(d zDc9i-%E_V8p}VqK>=e2eM#o9K82VmH>eG4~tXCxqeC3$U6N^(HgP(2mUMUB}D}*=W z`Z_nyhJ7ZNEYz}_>$Ss7%MnXh_)e^HMg$iYNjn=I+*wH^(n<+<&3mVAJb?};T;p>a z-U=N_QddFf@TC%Nc0j1ni%-%b@5i&;|K`ZQ<ggYO!~wg@X?;AoFtD&m{JkO4<<nGz zgqYqJ$yQ9qZStZEqMYf<@*bjbv5}0L^#;2qif^y3Jl)+KF$*<d6RrXUhoHu0qJMRU zjTG&Yu+0*HmeN*ud+b+eGy>8X6jTl{vxk*N=D}|f#7pnS7J{rxeyL;4;_<;RbO*HB z4q*wq$$l2nEn_i&c#1`SghC1>XF~3B{vWD<R!!n>qm^@#meyFOy9k8P++SX3+@G-b z-A&QeP+98RQVv2@1g>;=1Tft_QVXIC%u`S2<T{E!Wn+By{7F2XhOY9AeLc>Hb|_yJ z?eg8ZWGPYQ45O|bvA?e<6jMLy?UOG<tK(K;FYR#9<+%xqB4`bF=wz{Q72ZygDtTae z1d+fJp_Q?U+tiuxWZbP@gdg=%za^-DPBDowsh@L}P}&-^5U>U#RumF-u7DC}C_;@C z6I8b_G>uoAXXK1;)9~GwN9G$5oTpJ>SM4PBRbq*M*Unrg<&Rg9<*P6Cnuq3#!JqC= zHf{%Ve)=U7g+`)*%rO&Oz$#bxo);VO+sE(00t~$o*q}&ZGtLpKCKudP@%#RF;86u5 zc|&}0cQ=f&|Fba9)Yi#*Z!3wWaYnG%cb_=Y*<^O6_Vzo7H$T}{3#_SOB-Lo~BX34p z76>cCbJ#0&E2ORtlh8{nAbvtJdMOB{F^8oxA~lv20gkCaLu<ELK4>?%mM)N6js~Gv z_bNdtuf@B#pc;qR^H%AVH7U&)p=J_Ytb4Umv$2MDV{9y8YDhTF?#QDMq-t+O9OhV? zwIzl|?r+d8h*COGZ?=k8udDcNwIltT$27EzI?hNMnB5{qY03dIcr`&$%<&0desTd* zeE4ATcf<s*GFPJLi?DhD-?9vs=de|sA#2<w7|qu~xUH5`bSf_Jfc{s(T7S4*Th*rX ze%&>%dM3rr67g{Vo7g4$Q5pKk7(vU51OHWBg4nRX6BoU~$t`4$xQ;iUb7exuR=`rO zaO`A!AxoChCqlkPD3G0SCf?P_h31Hk*Wy|3=$d{at7y;cS4l~j{`mMfao4_>88?aI zWIG}wSKxckLF4mqioYK{@9tqm-1K<F#bn;lHh2DeZ}8V9J+_wXUz@`^)h(PG#>R>k zR@G5QOP2)fybqUz+3YUi2JI3_ZeoG0^31xENi8>V8QqiI$loVvUwN|EHY_a(F2sl4 z+?SGHkh+u@xa-I!Xzlo|ZVGjds@h}L!oChJ{a~?LX|!Qb)%3;tIRx(Rdt|zEa1|o_ zr9$#G^>hd1V?F$XEUSgyg89$~u`w5qq!S6Ol;qt?cdqRP;XY@rcUU(?qj=&nh=yj> zZU^L&hqj0)7g32Lj$mF&d*WkW>LEy~r$i`PkKf#%d|-7v_h$sc#PX9%%d1kDB~lKr z!r-p8VMq>FY%-;`f`cAS4+z5`?&+p4+h3ECjl-J3Kznhb_<{`bf_hDp_ak7Ow=Eu? z#n;$h2Y`0ND8?oBoXC|pnuC&j&=&6ZlixK0c%67`Z`J||F{oI+dq_C0d?)k2h`rd; zd?UqtpY~^WY2}oZ1|s5rHaNb^ILd!h7>1ZiwkLdMX(6EuxMk*<=S|K@8NXa^Fh{&{ zGFJs6P(7W<*niH8xd894;Oj>n8wWstra@=uc_H`)eM!wM8q(Hh7@zn4hlXVXwu+GB zi=HVnhJ$WA%CRSKcUJ=a!yT-m8=hT;nygbXFgIu`*wx{-t+ZAxQ!S*8kUoSGXbs;O zt2;A~D@NWk(G<g)1Q4Cz9^jB0WeryVh^n=+hX6B<L9igves#^=<r0*%^Z1oCgDBob znNOJa07@suD?vO3a~rczocc{8M~G`JFH^95nbiH5#r>r++-zZ~XDmg-+}x<T?amcx z$d%zbNSY-?OE;*Pc(J`s+o4YC@pY!DtSDJk13f%a+{g18Mt~8!5hvlx`4#~=V58$w zr!t1e`Cfyj+K;(t%?nVaBCa#$L>V_N^><fnATL+i*IP$lGtPXjte_=&w$)8Q3c=T{ zFPn%o^!FeN)5iO3kFPb5#RjwA7u^$%vd8Ee$uLY=YJRAr^(=R)cLV9OrwAdzSGpu) zo=#<R?&PQQlVsdkE}r|d1=3z{ROnP#F=7Hu(ef9;(^#yZ6@b3HOR61irWs}F`_oT? zuMx${Po7CAq+95NGPTz#0rU#&XfSxL_bBe+VfcDx&%;M7$qon+VJ`*EMKAzsWvR|3 ztKRNL7Q7VE`4RnyW*quz9_?lq^PkFD6N8>z_zm9aqdaSK(<Au4a$9?m0-*Ke%s?N> z!cSog^cnvFkGvvVazBGZENo~FX67M%L^sIvEQgeZlj9EdcpxszznD_w!JRtTo0anB zpm&|HnsD!WNx?kZQ$=y;f(@+yAc;aM*s)2%vULEUAc&oh>2(^P==e{z_D@syKjDi_ zJluc6JEn*K4SW87h+~6DiE^lLL6X8tXHmGlzsZ{Qjlrfx4?<?nB>*3Gv4dM%n}Bt= z9T7tx?#f(={$+7HNDvS5f`!HB?kF?f7p+$lvc(bf#o&p_;E5)KgdXPYU5<Iv9WBV0 z_`fYgl5-KJ;8a2}Wy7shLYD=6=@)?dyI0MT)`hFZrs#(ZEMlO`NH2wynRzdNS^u{s zPtn~U4_`jirRX$+w%t>B@q)OsZBF_G99osiLK_=zE2XtZfDLKGARTn3$(hJ$1Cd%s za}`az!k`PgCSH>ZEj+>lNlC^G$N5jpGxLt7jGjFW6Q&LVy-~RxLATo>-JFXP!7-~A z=}5G!DWCJ9U~ZRlFoAC~4V$^v3mG-fA0zoY2M2J_e~S!7{7zK5?;c4LW&>j<Z%H)P z;7|6>(RS%Ev<>r0H*LYU#(l%tXqFCeiJ1Ab8ALpeFr6}gXzzA-x<7WGqR1W)dVl`G zA^H3!8mhUi2(C_Nycwvgn){j&oN4riL=l=d@>aJUX5jZQDJ=l=z;?~?53e=yI%rs4 zg)D09N0q-XsD$wd06+C%iUyBjy9p5#Q=H0IKoacHDTPC2af7?*G-HFuJ4!5iEQ*|i zS+VX#s2n6={u&*AH8sWF3b=-Se)+R^*|ycr^)pI}CAe+*GFvFr^g<=wYHvMTykN9c z>_{m9T?w7(jh%tqv-S-ZwUvHnih0}A#?DxFyar^UwVR!8?L0~cUW)80s(Kyr(<#&W z;gR)c9C#5`^<^1aa>uNuf9{0W8Ra^{_~RKqxZ8})s2QWsP}b!4j#AFR1{Vk6L_-Zw z=WSWxxtTKR2IMQSC%7CLbGRv;S`lH{GG{d>S&bAl*al0~6&~h+ZanGZ8fV8;tr}i& z{f3z+E>5g#TTGkc>SWGHamYiHCWXg|uRwu~u#5=pf{OF()g-H;LiG>qjBEBZ-s$*w zd%L={DKcGJvAw>0-S|6tr_*!C#N&2L#=Kkxx%e#l0fF=TvuP}t`2#xr<55F4CVU#$ zVaMyYAOKTiNV3I0mg>EK+9p2KOlei9AI55X>!xZ{96nSK*%V1S8J7-37rxMMA`9ev zBPGrjTIsxXV*6{&uCRE~9C*>wKqLO}N$aBrs%ptmx@Bv8sA(lSt3%K?sVyAypT<e@ z=idS2yG&XkG5mFH&Y=`~)@1csp+3HtMw|xE8$h)|53+T_<)CrkTkrz2bb|Z%rb24= zTehkFEUP;8lRb2{uiFWWT03EPAtan<w5PcC$6L18@SmYRla~zI@};xF1<j($PL!&Q zy8i4OmS($k5}Z7EeQmb>ZBpg_?f6LXV@_~%lQb7`Y`xi-E4T!&Nc!B<8K;4u2*2Wn zvB7Ul&3@AhO;08`N=4jObW1f#WvLp0#VQ%mPyQzzYno#s^p;aH;oeobm<fEN;d-l1 zr@asg3hG?3uYlwH@jCQ*H2GE+DYZjaF%Ks)e@bE=u{fUDz(ah*q+3~1t&0pVCMi$s z;{PQ)i&YABQa&&-j>fq3-=zAq6oHveIx92_zmDSyk+mh}wqRe$)`KZDh$~64EwN*d zx^)fjdfxMH$WK@S0&bBwF*2rC*aVwB=y_N#Y_@9<?JbY%zwaA;y5@zM`9>6d+a$v6 zy=GsYGsxX)j1=JWL~Acj5ZdJ8BIs$u`FOb+i&h#2%r#7MHNoHVzNF3hHYOtjK%1ts z2HEcyK9wUwe&>OH%k!!Z0!`if_;nzcWjaj{NR5qqE*Jd)7wbKU#EUd&XUpi}jQsm8 z(bu~=1}u#!W)0pG7*dq+GCEIlCo6*^E=MgZ=z4-8tmW3;nX?w66YKEiEnkXjgSYHy zsaa#(Pzo3CR6Tt#KXjfkV=6y!X<3`>Zfv{!sz=BJh-ua6#!3f%#9SY-4QIFGKAS(b zJ?~897tlruHaH*~0Y5D5<3C3>Kbt>4Z$|613zR;NFtt(cNjp<mzF=Cs<6uVND?C|8 zsq`u@UDsZ-($eS^h+vQ5GAc`yYKfRRiNQppZqZzy>MLVJmSfXP9v3F=wK*{sraSGU zp{346@r_BZq#44qx^Z{2*ZttL#!A(Vvt%C1@?j%apTR540#=Kt$JVnH!!Y=Q)^&;e znS1@uzjuGS;bkHga6j9?-?KYOL^l(?{b<v<c}hg`$fUWuM@~D{TxoYDX7SDg9-nVF z*uJ}>oe&+Z?2~Z$q51pa5O5j>Ed|if<;KXgR3fbNR|86o;xZZD!}v&-cMB<Y6Udpo zL^RmWgE=#H198QNgO;inkHeJ%p0RQBiDO;N5eKxgBWzN<d6g(7U9-tSk(j}$pn8v6 zr%=jcc5ov->Kxy<;8aEo>b7R6^URtcBZ`n+^O3z|7s&#XsP@`TFg`}wI+|oP{!+2V zH2rzzqbogq*$C>vO|O#Hb?x_@6%Ke-?b_kqcSNp-*qNQf(^I(@r~Z`-8+@Fo9!xKQ zS7PTY?r+4IF-poAqcG{fzri27IBb6cQ1~fC&*gf^q9=*5cMDbEB0<`0A)96)6$;^# zMI>_mgL56`f?%c3QD}8#ids7fTI7Q}7e|QVl$d)h`UOoysya!i*@^!Ws>BeLvycSC zA~F$`E6;z0SS-Lj$tRRuN0^IEH@wIMu*42wxT(L0&^&bhtd-3XZKT{;#1~5VNdnYK zKK#*1ZAnd|pmgxvo7EM`3cV7RF50ZnWAO%qPN7B(E#QUMr0>A7iGqH8fAOxgYr5DX z-1WSb{Mq`D<=amlVshbTuaZxiwT}d=wu{{C{&Qn9=oBfWH3<jQRMo_KUKbGwm$dyW z52I{sUL}S<QTrHnBpGN1D{7?ThrhvTMBX;C$eQ^>oLw}iDWm|@Y%;Lp=`37Yw2gOX z;+W%`5~;XfQ#+A5W9ZaoKXvys8jVhH;5NWlq(>RmV4mQvBEJhu?_DG-u6VuSb>5SQ zm4B@){DdD~KD$=PF(GAYijSvs<$QA=+yp?gzE<&Tvqvq$ydDY8C2jb4n)xE`+ZSIC zs942F3zQAJO>x5W2CKXHM*-8Ek{-IQ%^y?C%x>PR^Z#l4F`dbM6~0dVD=Q+DHqJK; z<$|iUsp|@mv}kthk2^x%U~J+9GDn`(pbz{g*!W4&2oQ$&7=9b*_9(c^09rekCvEL@ zAh^H$ZlMXP#o-$CnS@&%F6F8z^O`XKJYK+=dk|RpL7+eT9xK`lWt{!fy1+D`Nk(9X zma<@qPi4h%iu+L7wUWD)s9kyfmkz8(bEXVbGe`8&5c~Ba!6bKM$Huil+hKarn{ltn zG&tZ{KA*iOHr$%fc;DdzP3}#QSelYmCPB_A$Q+lRswtj0PTg-bMm~4uIc%TIF4|p? zp3n!I5-}rt7!ZxSKVTSoUoeb(-W{qF$6PL?JJ?sE+BN=4O5M#@YTuqUIi!82T#Pv~ zlv7Y(VIx2#;M7kj%lC&?7Jq{Icp7AVwjKV)@uAdc{$h_t&P~vyMJcOvp%h2ShcXi= zMClWG1Eh@_LUH%PFO;eooDiAWSy1=p;_qf|lxViyhTrUL4mHw^P)NrXyYfX_2>216 zY#2gyha|I1(KB0{&FPH@jyl^w-}Lp246BLu3hR0}f#Nofi`@Q$=G1#j=a)kSY`%ym zG=8V-e7JxYU_=g6Q+8)KuhEBd^>_LAKE_;$2}@8{*34Uj{@p6lfK8$g*=eWg$yg!@ zCh1SxFr@H(lmI45x~*)1;BaXUj6gr@rl~Ce=RF2b!zjCBi#Bfm)&k_aWw}2QyLE}9 z#Ddq?WQj-&AYsYRTWPe#cq{d@S->cK3KQ7H=O#*wkN%>Rf#cBiFtmaVyF-KT+GD4D zu^zK2yI0V3GuN$&7)Rt!IVei<A^)iqTW2C#yQAyz=UC(SAm&u5l*lQq9#@AnuWOT2 zd(4?L+Yv8NW<O(IM&it&7^4&YpWAP5e~xih{MYy1j~Tzv?NBpXp=Mku4(+^BN-}b? z2mG~TAMC^cNrHTh>f4`cvm*`VZAEV<V^5YQLD;_j<E&{}`3BJJ+>VhiBD*F5d^utU zH&!E1_Mg)eK*Bp67=<T$9O0|>{rTJ-qsQ`)fMu0uoSA#kr*UVmh+F%#EPSM!yD!pK zY`rhHyx@$^on_0|Ip*hE3h=$iL>H<s{{^}!ZFm++S?lD;Ph-vz+UqH>HfQ3|+x(r` z>835&Qe7T~uyuc5oM+&rP94R}V#0&oBR<vnx3Jr*7tt`+yA4*e>`o_a1|=h?==LS& z)>{kU#U&?X;~AQYf6P*)p}VWV%p2AweGKUHmMW)yH`jSAH~C_U0%K@fW$^DqXvq|a z$a1{slXSsG6EhIhA0Ku-U8y}D?=l0-;42j*#*HPZ!Nv(kT=O`C3v?2IoMTC`WOxy3 zusK0h>4vUkEzr3M7n)~sIHw!g|7khX6eM#)Pz$H@@wAifBK^BwuUU72M$?E9)NFof ztdJ^MtR*>v)ZaHT)X1%4J07j`2e;;*(L>-L%9?LBwZ_J-caUiA|302IWo6SsLc^vw zB8m_3c6RY_3uF4r|G%juy{~fr#{>2M(oKJn8!XDM&C1UI3qU!Pu~{ScBNAa7COJ{S zHCf68jj^Ke)X72M70Y~u{zG_<;)+^q4p!{$htV5hvz}FR*c1D|mQ5MGGrU{v)ix*p zBd=UvZCuU1w`H5E{F2a4MyqOA!}f(2r6{ST{ztSRM!P{FtIw5e_!FTal=J<lvZ_r{ zpm+8tHJ4On@=E!KShZ3~_=H|f=h8z>&+^fOM+gVU+Q@U>MN%K^Faxa?GtDO=E}d<+ z&?S9aJGu)q-==#V?2@#s238O$01$Q(tX%4%K>KUY15(4A*{t9sBp_Eg3l^?F9<#TC zlm{tNA<t=}yTXDQXjn0e`%XlVIj6r5T+kJ`LDYS>^bdhuO4MnB25~`)6}$V#YwR-R z?lSEi9ehBfD3apvpU)eLES;6G;fiITw|kT*OIOj&al|&;AV7~&tOs#A(%plUaUi@t zQc<~D_`5WV#%d5ZbzT%lH{E6f<zb&9u4@Gm1m0|P<EI2w#rBz1xY`~L*g+Z4lDteM zek1rf?@{cCeH(hSv`G|uCHuEmwQdyU5oe^Due2F$y)K`iuP_OzCuQgu%E@@s%|e^{ z4X7G^w30iR+YYjjdA)P^RAzd(rYIP2Fl%|5_DeSLYICmJo7eqp1v{2-YNV5owf(S^ zFwf22<=phRMijRPkyBh4V}CnGY0ImK;-Mb{$tdS%Ovknopl=t`WFebIcKo41zb31j z58*O%c*nVP0NWS4Mj_Nm$-?xz4E&jRtetx4yqU5qg;JVrhcm#4cuV9*usAMj|1_7D zkygYAKX^Ab%b<Fu8hq6}vA~R%!9bhAA4|d4f!HC$E=DUOA<;c#=W&3|`nF5Jk5o(T zZ(2Sb+<K8iTj~f9K_7~d4m3F$;p~6mpE}V<bI0No{h%Rm5FT9YWPYQ8TwaKCc}-hL zc`Fn$&wxI%fbDHpv5TYvdkby(U2M7Y_ee;Pkv85kH{8#hhL4zZX56A1o4W_@mlX$& z2wl>V#=rU!%Zxsd7#msInFmP#d%NhsgXA*EL`=^tsbc*qiIJ{l)4FN%s!5jvz5%~| z+}9!VS6(cA!*$wTeJQM^gv%&qF<5E_dJ{EOz7$2zI48n{&_ws)ubZ68Why#w>PQI> zz9f$eSPo;~PgoZ^ro~)mG7M(4J+-`kCg<WN0rO~t3_^Sc=?hTV{<xN-6q(YQF=zNn z?2#Dw76>ybuf%%&dJl1}V*TTu7}6t*`H#Ru-=2QKWyJXh7qcP&xkQOdK%$RYoSd~L zf(0wTQ18GxDKjN{z1HZEs!|xr-dBPn4l#@-YSQh%cXF-kgkWnRt6&ul<S0^{s!aji zQi3HRS2VPI$pP}J%v*ow4&Ui<JE(mf7{lA4Im?Rba{nw3L_{zfqZD^Jg^j!q0ho*g zKg2=~@2??Gl~be4n#G#yOFP;OyXl16;9n=-@EFO5bEe9;yNv~+!kh8h2~Da#iFjND zl}>0=iP7Tr_&kQG=!k%(YK9&83iT}eA=t3VuEHc*Pe(wjH<c*(<v{H;%fpS0jIBo) zx}yrNiw|TQa_5(gIFA9W!i{9LAi6ybB^&Z6D_3lsCKSkAq5GR(Es-S&u9DW-?rCMe zdh%y1ohcnp7TA1gYg1JPW)?-XwO2t}kvc5pi*FKY@yKO7sN63W9Mc*<X6LqveWO$Y ze(IsOq)YheqVu?ek+{D@<|_QMz&J>(6E^_{$d%Ek*{U@|(I~Vb7YKewa@U7dK|=*Y ziLz?k>11A#88}*bST#Kdf_@z6GuJax(OYpX){RL6QL|GM(OT>Ls#oJU3raky2+Twn z<icvlgVR)jQ@^xuoT{f~EQdXbsv395X3?*vBHaReXhr}`ZnBz7j^(HcAlr5s!~)j( zpYC#sUu9*qh{tw(Ci6aoj_NjLrP_oHE{6nv`rimvL~8BlDqGVSb4p%2I=HxlVEnku zvDxCtSF?%bqSh10=ZKLo@1);$FSBkYT#4ZGPL^uWSC*98f{^Y{*C}hwNE=5Vzh|%3 z-&p>uL9=d*BJf<Rq-+s>aO|O;YBg>Tr1$OSGWQK!kVRcNgf`e-c|BX6a%5d<StPrO zH#mtA)NCen4@PJvt6otIf(B<>zFLEGqaz1^9v+7^|6HQOS+aQpLA9#dQ#C-bwR@tl zkztI8{JW_Z7A?)R{Tj(^!GcdkxtTD>X|`Dx$9Em%v593n3kyRkf~>Ox(TS^!^IV)Q zDEzU+%;|b;@+<&qY&Om=?1||^6OROxfh|Xyb2VQhhi-$}b#08Q)i8@j|6k)$aoE=G z59Kx4(YLO{NmSZ9Del8o;7s4?y|!wS=6lcZM9oA@%(A^N4HQ;p2KDPx%A+H#Jmj}d zMZ^)VPj1>V^!YQ#Y-a$q`g}o`+eUivKB$0zUXO43ZXLiza*Jk5WT{VW*vjgNjQOpz zcq4@@{-l#@^9UYLm8j+}Jf38NsC`SJTy~EFS)v{!K5gxStZ#X_`l?nq{WI(2dZG9* zC&>g&nBbkGq)`xL_kcO;eoLwuNu%HsBQD@ClITajNqze82fK**9;))7tZJ87>;^kh zq9_l=v;}Np{SxqL@px|V$xM^XT+4j@k$e`CyK_t(sb?OfGB^?(8aXQT+o(+OAY>-s z1ySTkF&N<LD~dZ_6Um3NT)Q148JTEu)Lh}r_)=8i%F{<C?;}ESIZM`rC~N9jhs8uz zId#IPlWHWtWyifSBs%@&_u9ouhT%YIlRNSwC^57M;;1iP%RAe_A|@REYF_W<;5G?~ zq7ud49jeJ^r0FN!ht27DFtS+JUVq-5&mgd@z&S^`cTWFGwa3i`fs^_gFQ`%EX%7wO z<GpvH?$6ax<D`BD2j~dtdR+DK^)&@YnIa(}IfIijdAOj8W#WUny1HnO)Xw<B9T@oH zDn)6sNQmqj<#*k94dF*`+=Vsthy{KB;N0v<QYB%3eKLEjtY$hAojZ$BJ2=FrD$vAq zr_JbG<PO40<P64b=(kjZrvs#vMictGS;M*7^QPGr4fEs1+}^6{XvJ$?b{2U^QFXAk zn4RL!;)tz>0Seot!kN9qNCg}Q_UI=drz4a_hFz@*E5D)@tQi<MF`*sRI0Po7i%=Q3 z%$tjXy2tgJ@TEy;T@}CdQDHWF^kqGj0H}|#yA;B6bk;b5r2+}TMBSPPTt2s5LM*Vq z{ji_9wlXJ8*H@QGdk+M1#{l0uHx?t32pd*p;z_2b2(Hf0Lz8J``xh1#lK))yKS3f0 zZzj`TD&(eX0P@4gCDxk4YQa>0sUXtRC!a2mCylu%Q3GC~DSQ4>=ovcB8imWzgk}-- z|M<Z|G#O9&Lzxb*xFa7E`ztp^z>OiBUOQCa<OfOqH$Mu;#x=A_+Qd#rw-DDh*XL30 z$&VLp(SP0}Boq{Yk|Rgk0U@427x5l{q56^eYill3?GngwZhtn9JZgrmqv-ST5t4hx zm(iwucO!ZYI?R7&%8<D^-Kc9ii7Y87?LFPzHF_Ak5f5+(^wf=XCKkv08e|ttQVLf( zfM#~gkCOe9EVv}iJ(ZQq?TcMC={j`ZJ;sO|JExTmbZ*Xz_<*6YU4P8}`%~gjyG!xd zpP{qq&W?f1R_sume`(bI&<KKLt{2LTVmqaB&tKGWd%`EmzZ+8Sc2{wwO`iw)B_z2l zCe3wv`G%8y95%W^v#pj?x8`l8Z?wv^hh~@mgRHj>Yb)%!yo*!ZJ-9o?A-GGi;%>#= zT^fSB6ewPxK+)jt?zFhOI}|B4>GOW`%v|&ReeNXJIVZ`v_ugy$md1;`;bk{BM<Kdv zuUPO6!Y!!)5zU|&xWoFIj8yGhrna`OV8#w&bA<zZ+h*}O2QTlPICp{u+^mO$)?2sv z+aK45beofiB8I#-Cz?e2)4NzBwg`d@W+1*;h(7W)G;9<dU-P<GZxxey0lxa*yCVS4 zTMoS2#f}i0t_PxUXO(_P^i83=5h^+L^XjIY;pB!2?N-anQv5^s*4ci%_sU~_t45T% zz4>&I0uT9GIvA&KVjfBTocG&!KD+~IQPnA{-eix}jG(!FQge7WU5#*R8EN+-hwn&~ zd~{Cx7S3t}DdL5GX*4(FMV>4`QpjAs`fK**!0ScqT_*I%<3;>$s{*?xv_xWVjF#pw z&`yVdA2k85AIoYW+)RfOgHPndVtpV7E0A!NKZp^Jo|mvu5y)jV`>v`(BQq-&t^}ti zz17?_&q*M_MeJ0=nH_NK=CBfoWnQfoOS}lDZG_)=+L|$WZlaeFPs1?PV}lR?GDzHT zL``ZzS!o1>4AbD<qaVR6zrR}#Jv+4GTUfJ|X6^{gL(SyfTWo#e3_F(~;%{ak)cKSV z+fm{+UHC@%py06xIbi&<d?$T?9L%0Wcl5xX&Bj;wmRNvn>0dYpw?cX+@5SWC28@lm z1S9zh&e^fu5tNzYBF~JCy?;{FymWQ#jWp#qU*aBSsUCDqzR>+d72EHP>H_{D3(lbv zdT0}{u&F_1{%P0jQiC)i_lj~Y#n->DO{w5av%)y7Z8wzbCL#$q5-d&=FtnAn4_5WK zN&MdY{co*D<G6r<Zd4r!Dtv(GvR_N$!21C$#ZwmEg31KKR)J+1rjP0L{Hp-rXiQ<3 z)=p;7$!?!Ux^A>(ZlZq^wUYg%4=j89e{_Sb&>Ct)f_<cdWe<^*b8c7i6vsn?b;;}u zF9<+&AG?dlng5^Bo9MS6y15aC-wNnSwWaVE=7%RGw|7@yB$=LicpOtpplcNSY?jS^ z$?vih8*wrH%jyqE{uOd0Bf(PtBQ<P!Z?hr)A8y8RD0KGr@6-RUF`grIw6-S(XRxZJ zqvL8Zy<V4yV?c}7J<#x~aL&|(@o(}5JuJ+uVGG7FPY?EvJ<9rmx8!BS8_?bXz)ls0 zsSGbxV|-(3K6-g5I&6y|B!5wPj+Z(If+br>)yrlX+1Xp{)a`lV+3dJ7l}msAl>Gb| zze3yV$52eoQ2r{}-)|pm7Gcs!6|{W0SXX(>(3q7J$xc%J@%7P_YDnzK?D@mhMjHWY zN(pZEOEs?Cof+5oI&1VeM%gT`{g-Aw7dcJMo}iv?$CR`*^q7Is3Am>jqzkH_TC}%* zBDn$kg6%K+Cqx4IVoiY^oP3r=wBHr2<?6mBU3#Sn<5ZzrG*NR@6ZI5OVXd0otk}$M zHhuc+^W7fxf#392v5}-vS?_()$)5W@)9-lm^WHhNETT)WM*Rsd5oRnY1_J~j{Ps-7 z)&81syKNImk~Hy_dxzrFvEEx3_;UH@gd=}qtj;Ak!76?>D+F&T_D8h;e5&wJurcdW z&-_@*LSolJ3D9o!Z1Za1(v}+r*i(E{{)v%a)mD#q{b|#J5l<!K_Dar$I#{pYoXgN? zk%|;1M<t?}`wE#xa^L{<a>84z+mg>>-C4|CQpmEOas0uKIUJ3A*fH4Xl%Dn36(xRm zd9%bc(ZH$4n)}Chqi$ZIWKM#jT+#4g?dm?gVpM`RQS_>G<>&y0X`AxP=Y7^^pJ4v5 z+4bBLH#P{XXa`0L;lS3JPTrSdAta@Pmspjl$^PGc!aYUIa%o!e@1_PnW(P^IMl{NP zHe>H!FIWw`;z!3H3r6^N?+iY!E<)IQI^-jVz@+Vq$_+?maM~eStuZ%eM#Oxi=xSw} zYW9EPiC`h8ymq{rcIXxL%ll$+dDR@yIUH=tNGv$!HC&oCv?+Z7p}^AB%}uhaGZ2f6 zEVjG*9kk$uNz>9YtXB21kt@jGs=H6m77hu_gdKmj66$=s69&$z#6Ggz329WzntTmM z7`vyeHL@S}iL3qr#5C|Uw5UxSh(@imNWNJ}Zni5#@PpoBtJ;Mhoo-L4oYMloNV0<A zcVA`e?ZA^Svfoup<aZCWTz<HFD$sw3I#8xXv7Pb9a_7UfF1$Bi+6Yehv$~w~-YW*i zwgl5+U|VLf<&9RE&<d`eii3@~SP`H9WM(UeG$}U+B(*Ycwv>!N%-W_~>GVsJ+HV1o z)ubJs0rz)}^NnI^>CtMYH=HIbAad6@u{GQUVZ2f@%NvEG{SE)8{9wli!<4*`%#`&V z`agkt6ZfvI;zPbIZ40cuC)FL%gvObXm_Od)aVBzdcGKOwvB?R-Z9mb|Fz{oV;KEp} zFjUJ(m|=UJE`xgDki;pmT+rb(%64m+S5K0ZfwR+%YnvD2^U0Uf&cp94vz0;``5u{f zgB(W$KMqWjs|$$9xmz&lXm7;;u6!Imk>xJ>kg&Mf2}mrtv7=5UHV^UV_3V&t*YK6M zdLa!)pS?fw39ul`rM0CXo9si#qz~U;?`M5>9wP?UauIM`C`h%mY)M+oXcv~|zbkW% zaOGPFgMn*xL$ExK$`Kfi{=OC+_F{1PG}W~=y<|R&Ap88`&!_BRE!VCN>&K~#n+2<3 z!?ma_SLC6cUw}WFvZp33XiJK4uIpNhjaFO)FMs$^c+ebpZ8QE3EHEytm~m^Gp3f#g zj$BAqSMdZoU8#az9AQRh`JE!woB+_)9k*=ZNRpXd89KKB#2R1+i)69(E$!jy{$hGr zCptT$Qn!->*W|SwtDIm;CZ8QUE1u4zQEaaZ>4dA%@i*d9Kk1C!$=9miuC5P<DGD|l zRp`0F=X&h%XMdRJ*OTRGw|oDn8>_$P-=4^o+dqYo_{e*^09oia-$HMiU#XORc3}mu z_ed-X6(I46%@Tt;_5{-PA~!yuXZV^Bo@P&@Z+QLbYtK-&Ou|)|V(*>OlYIuZvNVd$ zBB+9glg<RXvcKSrk4^8ispmjWww!FnY`DaVw_dPE-EpqgbW*N<pNgrE+=nb$mC{`3 zVg2glU-$V#47}{WAtKreE9xiHW&REMY$9a*X3jjAK#_2;?uVo<v5=vbi|muWrMgu% zL_WCl=8urO?|`ROnn>aOuIz6A;ksOv^Y1It)%6MO#L?Zy>yNf%nyhd5K9}hBp!yX5 ztA%el)4DQ=Q3wK_#{v#+I<#a<pox`xT>Bh}=MhUobyS(h1c=Lwxip1XyzM83zTb7{ z7jT#qg5d;g-z<JHP)N{MvYF~ZQsw)xP)PUnYR`NF?tX_UVMjWB{yg^ikXb8|H~Pw4 zSPXf@85vCdz!E0USSG#UA|~CMctbC?&ODB)jzgWw%rcp(UFcrJ@r@<&KzXu(TOr29 zaQ*1J;$oD~(7ukTr>vlZ2GzC_3H#U3v%hAO&oUWJht9w?{&!vDdTMeUx=?3$pCDXl zM;AK^f=*mTIV*U5g0O%*-dGlh9q_Vt%ttFvj)__o7!R8i<}b?^E}>;h1)C*<laQwL zMgB(!p+6?0H^RSfSOuXkd3X-<xI_sRF6Y7T616lxc<1&jn2}98-3j`Pk9MhFzq-W$ zE4XFv?I-YQQ{Tudd@A)j2v)pL`*)`psA@ke$&JqaLuG&vZx4Q&O!YCGy!r3jR^6yd zUEX-e__~5=;BD-gsW9(ACyvb3XI_Z()IKVNs+rv`y;}j9{NoX^shYCe68dL+!_w)e z;<XFDT-FtQM2_02rRb~F$!(ig1WpZ6aUpVOVWpD*)1U0&llpQUDuBl%#|xfvdsEtj z?jGHOg@wILq0${9oEG>|ls#~u13f@lcG=jsNqpc}sDjZu$0fn*_$&YyKc+n~il(Bb z%`jJ#TCRvY0q^p%5KV_{0s-J@3#4F@pWX%FawU$mA%_9GQ|9_^$+X`ckNIpZF>tww zN32*aeL8pgo{-ng(KR*Dhbj7wg2EXO56?|WK_SW_Cg$Pk$$hLiX9X<Hy2PiXok}8k zV%(AF=_fWC+uvW8i46cmsN}SYE63{@YmCmha1sC%nc3eaZ)B621*!VYp`@l|X9?mg zbgS?LWM>^R7Dl<Wmb><`QM*Jl9H>tknGJ|1pjQ<3twC5JSLl;2h*gf)A+;LS5|+yN zXddmt!#R9G7||l&COl!buR)K1fSQ9Ffra1=l*pH}c{E$Y>~N6J7n!VOHd8yn$j&r) z^pfSe=@U-VU>4?ah$;0;v|`<rtXSr8vF<Z!@)%mY=4e-(DM}CIbt8;w-sU5@LlIUD zNqG;UV)I4C|41ACWpE_g#)11-%&TUjqM;jK9eT??aWS&7OJ?fDMhs#|o;K1w*!D1= zuKB;)<Ff{GngNCC?c-((vuZrnFvvuGu#hkYyG6d^ep$6`8wgG+oS6|w&j@>{vxeA? z&7&&0DWZg90^BkQTg>O|XtRYQIy?Mb=RmA}AQ+S28xd-1eM&~g#F#d6mGjpc!t8#I z;L3rmzKFy^*Is)LF&J<IEOZ8l6Kf_y#UdDgK+iFhxCPqWen6Ad$&4`?`oQHkt0qsX zj!umijZNQRab8At%2F|Sclv?o(Hsr^Ufjx+X+Mu;;I$paVXUe*v2ly&ygDRZGWv9t znpL^H8zx!1h%4!&-om3?Jj_?1pr#bBi@x@W2_jYk`+>naOxOeuIG-_%ouEqD@%*Ho z@&mR+HM_g#<tZu&2X(46C_~^XxW8|&;AcBBf$zKJrb{_31#EcoEgSsvz9`SVN0%5Z zkJDcy3Uc0NC-E<wERxe*28>0W>XB$(5@uF>0V`f|`KT0N@Bp&&3i>*`hIuwAdl(4z z3l{!)bl=K?#T!K6LAD;;L5qGCt`d?rhQAlH^p2tAZ&zsXs?cFRJp3JQVpb^rqP<y@ zUSeJfDoq$N>U&8iV;Fr|9*~R<=(+cUE-`rkENJV<aAm&7$s{oyDQ5)H+M5IZ(RY6B zT*CGmieEeQNDt874H-Hxx_d;9nX%bz^!D=d>Yx3tQBIXULb5s%0WnaMUl*$+M#eym zknAP+g{FApwz*4zA?Tap9`h56oWQ35sbbAaTHEVA_TJ@kr0n+@;zZ{f$?gN1RV|FD zkRe_@Jna*8sdjVBG9nn15paNMoql5Rhh7vfe<qzhlI^O^Z!D)?q$qZ1{Wlerqv&); z>HB&1f!4lF-2{UNQ%%fgl%m<4<iB4t;@&;drG*p?|Jcx5_x)#nN_|7~uG9VYv$n>j z$8R_=kgE0w%l%ehIU(@<l*sgj8z?h+uL~Am2?czex8+2j<Tagq`#@B*pIT#K^IdDm z$p(8{33xtMlnh-4|3Aw@@yC*DQ6ddj0bKXwMbn6dI_^20jNbpdW-(YTo3lH==s;Wf zt>-H9#ItwzfBab+djGE->tCS*t&L{k9P8RKPBkS?k;OdBtx>?gG-po!sM+%n$_BL( zn)xHwrJx~`2-tSVi4WAO5M_AcPk-(2F)s~U<;GDFb!^!>`!|1MQvdV`E=3$A2u{wo zl@wBHzqxY`yXDx9$oy5ulvh)tL^-sRI*s)236MIIVOO-0>OL|*mmVx>`=Q3%mS7}` z+XXYG_y^*86$*5?2<t_yZzO|*Hp-*>v7wIA5FOJTOaZMDDP7U4+%G*)_OyFcZVmOc z2DCj4!&enBoH>O2Q1|9tXv{}OWp~OQiEAkmP7ib$_KqrlJ`|h#MnKCdwVaOha<|VB z$v-i*X>$UWy9M(}`R@T>H{rz^Tkand8Sh(^F+wlDoAEh~+qA!(uf$JRhKFhwhQ{I9 zsi0^)7z)nn8zlk@`7<cfH+;Ck19qTwtAkTmssv1Mvuk*%ami3THQQkQWq1+QK>(8% zsaJ7&fmSJ|<Y%3F-z58$9OJM{aSCb1<7)NVC5LIfGgE6UTr4fMNN|%fmJ^|8Ofdq3 zm!qtoI=aDT&j1S%TsT@tn_=v?XQF_sGuZ&1GgNqgo`C(7+B#v*Kq-v<06}bP{;9s7 zmhU?Q-t^>U_&26*RU+xm(3Lh(X<e=zr?eX8kqi)6JTXD5ZRqdk7%IH_<t`-j%^GNw z3wW|cJNygWOH>Y5TWGXdjbd{Q_+7`Kwlz-&*BCPgfksDS<3LC1+`!k*?T?SFsWt8p zV_e~%qbLyP9qRVGkpwkj4i%?$7ou!7#vvpF)t%QrC0t%ctmMmh3DR0S`_M|IyoM5j zC+$p%Zoy@Cb!3RQ0O7WPnEqJ`*oEp|GVFUOo9c1$&Z39<NL4I&TH=vL+?sdKGZKE4 zE?5}o6QebT|COabeLcX$D<c}FqozI8i=OJzg9i;@wD>a)suD%KyO&kLmPJcI`Ru4i zwA@KJh;|mJ6n3pLLpzY%a1Iss0}4+1FpLe;T0l=H*j&jzF-ARvb1Lbcf<Sr0FI(#l z$Or1jEXnz7A6<%!P*EEb3E3O6RW=oEfuif{8GL)FL~->0pn3cV>B{sVX}2?`EvN8r z*}CIKp0E@F+=M4O?9yR$_+8Z^`|=$mpJYgW1Pa2f#OHz}{40ONoZzM#hcsave0MK* zIn9^`L{OZ>cZEym7jLisgfKC&_sKo|#>T=6;l=dmn;G&qpDS&&+4J(gbuO*afXd5j z!!@&w#3_^WFG}SuFL70O)|!mP_56T#tlG$*$&oK_;QLgVovI{$wU80<q{+u7NGV!T zvFF&Y+G*0zQDGe5e2SW0CWC~`P9VLCo@cieln+aIDd7K9bi)o7B6!^Uxg1AklL{6f z^(HwIlqqGFmojddPja)iO->Q3bANJNX@omJKX>u$2w3kbr<|{EJ*180Z81C`&y;g# z3|My4!gR>U+0<h61S`2X3p{y-siz@%ZoSXYe8gf25P+$~El0eu3Ib0cscc(1kR`j1 zCSlj%KgNoEmuzqTnK}FNX4;d>%HyrEeUjJIt4omJZ2b})*H%b%iy<eSkJMx|vjoa` z{p0;$KY(cYHFLVtk(O3cpXt&hBqy)-(-6jDyC<o+O3pUDH$jZEDhyehJ==AW<K^iv z`{s=dvKzO>*1iBx!0X-daUw@zYoSro`r*PnoPPp;(6x2eT!<~wZx@pTc_85t0(PF` z)OMc?z3X^=&!)Hr`wwYrGcygY?KDIvIW!dYBrY+aMT`k4CH}LSk*uI5BI>U{UO<8) zrFb~n&-mLZG?@>=#dvgx!a|SD;=|T8e>H_VV@C$Acg?riJ{%sOpcSk|{~0Mp_P{q? zzhWK#$SPYFDuF~{9XWjApui&A<|4+E5|dx~vo}5B6Bk24q;TGyXq6iBS%y0;g6LMk zLrtMr3sQg^061J^&L}VyC86(xEh?NW(Y`@V#x_GaJVzYlM#ZeCbhR{MuF0I1ft><6 zdt~Oh_X1bfH<Ad^i%@(@urd{Gd8JLm4}>!`<+tU!Q6sU+Vd{ox@KO&8`a~n>1^^Kb z>SY}ihX*ie*&2I8;ybHKtLP<zXfcP<?4$`bC62#~r;f>hV%RtwVX=LlmC8FO1ZsT& zl73>)jw5-zlYX3CiAyZWEMV{#UI3Rn#$SvU%pdKz8P7+UMTX4cvToFktOj2`xFWa8 zBJ^oyMpcVtg>fIr41bJa*xM9L)y4DixP4~{Fpd(Nr?<GwuM(&W6t#M5z@U5dmH(*N zeH}bclkbTM@6VFx9RT-3B@6Uit5}pP7(PKdPx<L29>&N(XtIu=Z3&sdt?MyeIWlO> zY=t$8L?|cz@$q0I)4B68G*j4HG$qdjO8z8io9o9L`j0=U!+|NzWZY&9hqzpCNYm=n zGTP#;-HudCqJD>Qp?5go&tIwW!QV25!-i>tz^h?*<#3HDqS2JhgIs^mNChAFo<dvZ z%zal+>XGBBmsiZ!%*R30@nwt5@u&tdZq=?EK#E)yRabsU)cQ5U&BKrwcY}e(HzBXK z9KG9n9IMlZh>Y7<G`Z6=vnBouu8qnl*D#_V^eo?qJ>LwJ%SNzW(MNw_aH_UnVt=x* zSvAo6q}l6X6co+m9mX*<Ilk!kB{NI=2$?&!C*Pc0-z!@|Q!i6b*dl{sk_o_smXen> z6|0-xeaOmZwU@*_ZXe;6VVIU{@EWCJZX7dtaIFkh9LpYNHQyhy<m@8=nC@F^b9)uW z`vxpwTUiuz-kFAhT%*QOpWKL2divXI{u0$SNe)?BA8>=_v&}x(*(Lb%wS^G33&k^) zt8=}i%W^a6*I8UBLEH~+Mn=r#GEC>Wrz(X8$r$-R(18)g^MkjEiW~UK7{&648~H-j zlm1*Z4sp6e`5ZJ#pMANwzpU0R{#<sKXJ)p@)pboCnOn}-@XE2I&*^*+o-3vs@5V17 zzQZ6O#N)nqy&p2p@_9cuH>aFA->*q@md<LopHm{sU9R$#(>INIf4IPLTnbZU(m|EU zy0#7{1ESj1Ps{RAS^t^bY86DmmHBu1W%2R_Gq4xT(DjG2?$TuvY(YQhU>4ra6URhz z62br01H4(kQ07{4x=D7<NbfWmOBHThsrRA3`Bj0gZ1$P{X7{ip6Sr7<h^u0Jxg{lo z-`cs;W&B3TRR-UJYr*r)8SrskM7>NiGDf&hYl06kOJ>S9fv=8$-V=t4nWQP$D00=n z)W)9pE_YJqdc@)~`WWoew0uloma>B2oYZjH4=XC)86i<9DX~us^&|6ke!Js+U3Noc z0|C`dP*I9)Yy2jJDpqRVf1(eLk0f9tgES%WGce803CTr15FoPkcN*J>cYP(5Jf!_n zHxX^_xrQF+7X#?Ij`>I}846z|N%}L2LDQn1N_uNo-t70JcM(L&9zxwIAEkiwspYdh z`29q77$XPUP*z)VP5JmcXK!nGVI^Jb(3Kd+q-(0&Jzq;4QU09toqRIcazHT&pcAO+ zzv?`xmEVw#>q89#RCrX&FK5x2&s9zQJ>U+OM-FyVje2#H;9AOip6X#B=XDKvkEXdx z(ubekg!*lQ56|xQ;Z^=ja6FRj%ea)pWUhz~xgp0<KJD%e73EM%X0j4(lEnFLthR{k zcgKAE_fVaGYD`T7jAzfffv{l2jV`N|8(;eDjPWQP`PP7O<EaS?6Q;csE4`cQE8Dkr z-SF`6eCG|(UA<M=`)8q=oI*B-A3K{C56#$-OC50j-*LHI7Q0a~#SK2e7Z3JV8Z;Ek zv;U@~?Zyp~fI*HvjDk8f;~#@(**~rOz<SFmA@6zBT3?8cKmOrg<qsgzxvY_;Xv-E! z_fen<KCxMAVf&>@(f1f6bTFAMqZz?x8uO?We4+hPue=rgv>LKu?w;RZ?5jo&yDLe? z(Y8qNv#Lx&P&Itt$<1d(T0p0`Wm@#>$N2_B!BM#o$#CO>S6yHu?$?BJBT<_R)$3H8 zD&yCT)i%LFaGTU%{In-IwO5N)!(#$|bB4JH?CR&{dhI2UF1o~|+cVekwreo)EY7<0 zv|I$^<=6<2vHEzoU#<oUFdikz04Qj8z#RFB>iZZv*AtWLeDrU>y>2vxq>v?5xdn*S zzkuC!Ie{oW{Y0h|%68zbFJyEn{v|H1gO8cQQJ;L-%3A49-5J)o6qE00sH74uu_)ve zU+QCG`*YLE^ZE3nei!sio*|hE1mlu~sO^Gk-XWeWob8bzeRM^^=<gTSxBz~vok%`I z#-_-7CnjbROT>kin@b*_Dnywnt)qfM@ieDhpmvN1aes%FW^372PEo6i{Vqx=kw%kH z5|562=<X2Bych**ofT>|Ul(XK$M}W7#(6a|lZfIotz&6%bPec-oulOEMlb)$7EwRP z3FQ4LyxQ@C-Q`YqN4J~bOo=3iaUQCV6KNGx6~B?sqZKccN4ZUuFkYd2x)%J-|L*MI zYkPYD8U^3(SJDuasdq&bh7m@tEyJpU@s308S6$FuUY>M>f^!F)ySRZo3dT;y#X`PZ zS7-lD1@9k^w3bEBiYv#jz->?IM}aL}KhdwBHNT77_m@f1y(+LuMmCYQKFLFP*paNY ztacg8x!xR@5M{w;iCws`GG5OLliUeDBqIo)7jtyr@KwVY^dEao*t?JG1m!idq9T7n z=o;WrbP!<SwON&zq~Zp`0sT@!RkMXsr5r+SC=k(Nc<b_d#@|`4lnq!<KZycn>xkRo z$H9DK^SLORc<E+(@hG45;o|pFsi%77NWBGx{t8hER>R*UE2@jft~dX(a}Y|$OiDp* zeHyLd<suv^j~%YowosRZk(7kJ(&gqq<gs&L<uR4CH>s(NTvqB$Vy9-MS_oEglvF7u zX{#%rVdzIC_{jV9vsOXsYIR2Y2e)-Ak2}x7vI^>c?c>Ccjj9|>L%p%gz=dLB{We8P zs=bxtRCC6tK+5!}E!Eh#o7puh+ny1?3B>LU(ZRTlBtoUwY?1rI)G}|r#x_mB?U)r2 zjU1!15q?OO(0n=rCNWvgxs>{T4%=zImN$CpwExRv4CKHR?LB{l##G;;Sztc1ysQQc zC=^bpkd=kJMb;bb@K^E;oze&UKDf3f8J`<dvXuw^uhoWe&9`=8KFImrQ4c!HtXaF> zUr%)-+PuzsHhbW<j`b5tv9M=#en=VkA!_gJb<`A9L9GcM5}%j%$NEz%y-bl9T+q*^ z-XH(rEE}t_pE8qwF))*__QK*M7=OBE)06>5D@>v7HkQe+gBGmFdI>4wrQGb;10-o? z%9RX;0UO_l=k^5LXi4@+P+|LMW;)zSho=@+)V{Gg@aB&g-ZS8RI65Qtn<-`P3k413 zhmr;Uy_3i<;Wp*o?mh=ao(jXG1X8K|STHr+P$6t*H~LJD!H~M$*(1{2TLpnOU;FVi zsid4~5cn`BjB=*AyU`uWrQ;MqFEVyE3QTiLQvh{xH>{`R!qRpWq|rYvG`U7P-dx|K zY=G0NDZ)q%`XCW7b1emC()r}!_602VRr%tS=45H5&BX~K3pPDCo#Fc~&|yUFyHX8m z{DDqiFQK_<DdF=X^T%?0VfWNSf^#@kH%aXnVmY_8BF-k<1dZs<9VB6P1T`~wsg zY}IQfdwnFKk!j&!I27!JCl3n>!Nz1f8g*m#!+tMv>Nbc)ExDFHC-o|vLwx54L#@KW zP;+#TT_K^TmV(L>ve>yVxW0--L=KmfurmzPaO=B<!5g@!Y0mFjlXMCfd-Kb?ko0|r z*=LQ53BS^`4n_xUt=pV?sIyk{GKS7sQm)&a2^s7w6eXihE!c31GpD$&SIpSZpTuKG z>4Ys^HGHJM#&Ca%Y2hIj#5n07MJI3)Zgk+)U;KHYuL}LG<QP_um?Pv(nVu!&iLX6# zwcpt|v!4My)V`4RD;m2rwsmYL^TqwG(es#2%K;f@N|LKMdMX>4Gr3)F4MwH;)^8f; z4{GH2lUxKoGOWMuGkDxqJ0_IkkM-$3-19WAcUpfeQ2WMNp=$?{yi!kXqWNLA+R(Sg z#n*qngwZgI+UexB%K#YKhg0ye|LYxj-ST`RD#X|W?M0%H(xtM(CgJ|mXmXpQWw#sP zQnjzTTl_YXdg`egkRKK?SPxOthj_gzw?8i#-jcuZEDML#5|~%7MJhn!A{a5g8DdM0 z>Qb2K(8^x)gnN=ER(toXq;xhbGG5?$G`9(vnQGv>^=&E`!WLAIQ^JxUgcjvG^PTim zl*=}(V{mXxp=v3R#p3Vb+xa}r2I>4uvWOe7;*&yv0g?!6Ql99M_)>3Ut+uTpPUzzY ztQpzzo^~OupvK-%E=`K?tL-U5U*Ih)TL^;)n!#@6->S=-Xg2D48=m+-ovw47|99g5 zzXLO-`Jl}<x2e7$+G=%{o}C$}m-f_46xjaUJax>-kNB_0<~CKRT~1kZAjw=SV9uES z{nzN`_RMu-kp9eU!CVcr(WTJ+F?0l-M=qU(@Yr<&I9pewcCKM(r#XFGm5aYVHvrDU z`{sr{Ux&xlf`vLYMdlXBGdDM_3%<Pf>ZF4U%@}t7sYbkYy!YPv>LYm)q_CzaI(3p7 z{%_lQ^3A7{T^Fx}qTIcYP&vFQZzAChJ=W-=g3IBeaH_%BU-YcYnUcJojVVm?s{u); z+tQ?eS^%<w6&TQVHczVF?jaWTc;Mw4*0??$&hH!SnI9tA0Fdd1B2gQ0jOrfc5_SL6 zTJIK1i!PUTI+U_x#j00>0?{L6kjGNYxx6mFx7fjSznro~4>GtEM67S0tdK_E9dC^D zxx1MldOT)%xJx6CUnK1_{uKUxN<}Js8R?`cD4HN0%`d1B>ND_ty_u_toroR1bu5)% zbCE)A<FIJ!IHMi9bLh7=35fgMk`_-i8XOAq@|0Xmq2Cz0xzA<P=7-SK{`?Cyp3O;Q zc@&m4`-S)Q{`R*|;4uehcAnR^P>t{5>}#Bl{kFZ&Zm_fIeTxRvUpwH?Kq*v*R{o16 zpJ$GD<{E#|Q630LFnZc4_yDI7MdW79fGqvN<9rE_AOb}0F-930#2fun;P@53Z4I`? znxz?x0WTaP#1e#Vv=~?&G3O8_TNtWeNSC>W*b!e*&MP3cz~+y}SHW8|WM;~9XxFDN z;?RGzpqXybSKFcs`OFc`Vn57fhsxn4#wJ)5PPTBI0h12VYYCha!gV0PZF1tA%gs|) zjaO=HSUl!<X7onN&CPwV8znT%8OXbNqyF3lICpYVGZZ>`W$U-nFdHnnFg+gy3|I3B zn4cUxd<FaL{JwB~HY8Y(oHr#B)|9^Gu^OTs*9r5qVj;9*>6+cGmZu%Mbv1%Kh2Ghm z{kn8j_Wi)$etY-(!R+tY!{0(VtRtH6@(7maH9D*mpts!{HmhMRZb_Z4MXH44tpclI zE9t@Y&lX@>%Gdb4x6|J1KTtG5ZWjmI&rwB)Z=WcuaUhW(;WmeyNv>*q2OQ~r$(OOM zqV~lWUw(p0k#M&(jIslb8oxi}&kX?_@eKGT8RLJc(SBK2wA?5SS9Y>y>uVawIM3T+ zyFbtpu&sgFkdpJeELH4BD?!o4a7p8EIO*?_>zs@{?LMl1_z?`m1|gzLbWzb<4LF}b zg3j@vqBYnJ*7YIB6n{GwSu{X2Q?Qft_RN{jQPlfGep4*O1V5q^jJ%#~4tn#GGRfo< z#jBZ{1k=H5DbAlU5T83s=#~xbB_e*%o?=Q`HjQ|>J%vcjN?=griLW#7jvX<11MoI0 zU9nt4&H=o``inspp3X2KLB}wj>L1!2@{T$qMO|Mz+?Ly_*VLvtl9wP?{0mZUAga<^ zMwDq&xK3fX^q*emV2+`>zGa@DT#^PxQR-vy=DR;=HL<2H0v<wh%G7YxGg@}=mN|su z6`qo(?T=hfnM->Ovdpi#=cO%6NjLR!BO+ZCAUHCo-)C`87DLdL8aIbF_-UF35z8gO zCRWw`u`Nhy$(gYuCam4jFH0^rnx-qYb3VIZy$AOt^5@$=>h_283;C+rd?5~ivubvz zYVc}^Ot5qRy;A)5Du%wvz2@U7t%sm3QO%Qz(n-bs@uN4>PafnBbi_W^*VN+%wWz_* z5X9<sE>zO(Q8NGBq3|7ljLob(Z7M!hsj9sIAM|9Ui5feWs|o9k?FNpoW>?Wh4-YAM zS0ncZX89uOPJ+-mFR9n5VF#9ycmMZ=hXc;DI`3(!RSM8xEGTwnrypW5jdg!L8--iS z6Ft+Wq%@u<g32X`*nWG?@UWRCw{>tF8<89EKIfZ191bQ><Vq^`1Rv~)8Z;Q&b+^+g zXVO1Zt=hd5Xs<A6GU8i)+P?rME-Oks10@B1PfT+`+ZZ=W=t+3NH0r|>XbnWbC^pQb zV)EwxpTv)3TxBoqrxgSfMwxq2IIPpPW)(V#B)|+WGg|UZodiGLU0}mvJ`Ji)V;-h3 zP^o+lv2rGiS5Qm3ea|$DaY-R$>Flh*p9fji1U$8o9UfXJ)@?z-I<#l><Kd9Y<J};- zL;S1-($(YXggk%i<{T7QD3vA^<{*|0>bu-a=h%L+_AB5KK{vRgw^-N@6iBk~-l+zH z)<~_lgZuPdQ+Q3HvP|BE-=RqOTG7{zHpoXRNI<mY(GKG;G2*%_E;a^Cx;kR2jY;9l zS`b(6X$9^ah)TT9hQuPGXNpb40-ok>h*sv1{JklpG<xO$eT@7__+u-G6d%gSB+ZEj z0b;TrqTdJld4`$zFre9<B&^Q*SmN*R^k3;dG+ji50zl1ocv%pfh=hS|T1?53Qme?* zWeN#$oDkiYj>wWls;~r_hy*N)rLYXCw#%vT7tU|7@=5|o4Si;}4)X}rowu~)#LI9{ zSoWDedhd-YFdW8+20A-a)Ae%)d}H+f3ayx<pw>{X&)3#2-qyk?FA=6bK4o&WjZncy zN4t{)3RCVXT;5awCh6DUD6uZ02qo*}&s$2_SED<Do8t>9?djoO9j)eu{9>BvX@%nU zauRmT#=d_@m0x!_W39NOqh^w`^w5%Yzle&gh%3K(ITOaVPR27N7jAS<Vr7-P?kdB? z4_J#I10s7wzR@sjv3BP15mKm_gaS&U%^JC;aV(m)78BErBwri0HX9v%j*BU3L|fkx zG>|Kvb%?|auOUM(=WsLOdLQ9MXCwg%Am}MbXg&Ly`)7p)@Ol@nCiTE<YTr{JQypy9 z7v3$k6_r4*I#{l{hH0dY*7>|E@?7u0zxaxuK99zY25E1guS${B9AZD5t0N@$-xmam z24PvomyF;dQ&FA(gDNXoXwB}h0{D`3cPj=|TAm<F4!Z3g#Q$Qs%2LD_);|}~6x()B z`gxaej5dxK>$QyHqF@~z_5T^(Gu|K#eOB`sQ>%9b#Fy@O>frmuu0<OmeNwl;=^4|C zzAe(s9<2z~r3WWIJ7pOMLIO`%$(96BpCSn#2Y!oCeT{BrdLFg&IE9G}ncvi>sI0f$ zAlX_sCtK~rWY~$B4kenXY?oQAF+<vpAqo)sOnuN0{pjgGrlD7fc7jGwHBr}oZ4RzR zUGW;j-3fN?3hUc_#<+OEZd(YBhe_h!=u3AK<p2AZR}d<Aw^7_SZQ?r>uKWwxF_fg% zzas}Lq=-sS5jYJ`jE1e-$=ytXX6TT0TikGe(ozvEcd?w(qfhRaa^67>xQ=oNHz%7Y zb9CdplJ(a1P`ba%`E3i<c9ESGN=CAc$cfi60<RY>i1-8EwR)bvBL<B8RB%1K#2$aL zfI-A0K`tB#t2>ya;$=f$S`suYNf%a-_{BAz%S*~om&U2Rw{_7{2eEp~6cQ@pAqzEx zb*93cLxhVb&^A*w#vh%!4`>UM)jsF@Hfu3-In=6Kf3$*R5-fl?_{(tIAP70&jeuxw zgm45>a@EIi!s*;&HJ;sosF;Q7_s0&kWg?_y<1I?TWU{XUzocrZWrU6r9tyLh;(lfQ z@Y9!Qu>@C|)&%v8?~qsV`SC>T;WlETlxyCT8;oqfgeLtB;<RNK0JIft9M~251#csk zPslaMru#IdJ)YTx-}Tyw*i{wpNi>*h@V=uEK4}~PH5}4=Vuxw)L#IXP#*6V1p57?6 zG(m49z?(xUqQ~Jec@3t^ekluVNmd=O4)QsLFcI%4O8wa!CP30KQuimsZT+5z+m9#r z#fAV6dyO+_TzpvC9F3TpfZQCe^JN!Z*~Aq`6)NTlZ@THv+Xx6Z>yz6a;qQ{PiyFLY zOZ_1!1IBT3s#<LS%tEjFh(ZzkS8zS>jb{9Dk6*Vk?r_r$Rlw5)H7KtO{t1IFpOP2G zJ;*4M*WkX_1Gl4`j+y~TxF@k52uFV&J=7|Rz6#%@LE;<fFo$L&!~>G_uvH(Ds$<02 zfFMZo0nAnCsoFj9a{bJS{$d=)=}?@aDXG)f{&esO9wqg8I}+v8WKPn`m)6Z<gcpDl z8H(-MZ5pELl|oMY82|R-jOOPZD_#>ZdqtW~nP`3+C^A!S<bF%M3Mb_so+wYA>-R?i z$WwzK>xUbjK>UTOgBlxuw^tjcz%gt8a8)$JCkyC7zDVILCI(;N1j{J-ZEKED*5%-w zo{*BU7GU-AAT;QSDIMfRrO4~$aW>mN$!s<{A%R3kS(9hBiUyQeqxefQmp07C3>p{| z-#P|QQ<@AV8lug=T@#BwdkTyGwdFD<o(q-cQu|8qy+Q*aoFgpVgz_0^CueI`Zme|e zrdGx!xsM%75L#73G&?-Ww!18tZMcd}cBty0#xhA)B0;I1uQkTW8E!{wO(1c897jOa zIjy}*-KLC$*~JO(yOukJ$=HOUjrFm=upNh-YjXFR#bDhDaO#~>W=mXyN^66=^d+V) zlSh7pRoYa5sVIuv@`ttfHg*^mg+{Y56o^BkYAemTG`Ln~HqfwUCFRvXE~J4X(>#*& zsgkCPMVwTXK~u9#-C>Vvb?v>A^y%VvX1TJ^aO98nstD2znNfuhnuq6wd=SnmP?Pn7 zQ)Yw#Vmn0cuvmlLcxk44H^c*vg_;Bf!wP7!R%7CiWkqQBt(!%2Z`U|IQ8hP`h2&WU z$b<iZY0qIwt)b=Qxi60$ufq?rNO+I#xYlXnqRY#I+`WnaP@Gn8YVwv28%P=@7O<sS zaKLq_3+o?Sxc*D3t)KY+2)F-#)YE_0{MUl~U-`s~N0?-blDf9`_nQ36pSJN!J#&41 zy<}9-Vv+&+Mm2|NtK$3o(eme>W1`{gih^JfhGcB$e`~l$8KD2$^@e5NkBJAjQJ#l~ zzlMA+e=iH9E(iN{00k=`^=eQW!<SyJbaSa1gNbQkWi<iejXT?haao$i&syChbLf2_ zI|j0RH7ABQUx=l(E~9YM7o#$C;a5I9auc)-uLLNtmN#Xa?Ac$)II{%>v-1Yss*`US zTj`PGyQcPb43mj#;qL&hBU~SU+``!IgBvP>ja-EcX!hVQ=+OD;=(qamZzR&-EHs9z zKSLZ=r+le|d!{?rVw}$Iz#p%TL_0zV0ve<Va}JUkw&>C0)M)nSFzSHOtZykG$Vwd+ z4o(Qb!r(Vk8DkS**-F6_LF0T5#mNjLFk`_T3`&=cW&!_FYi|es+ax58SpMTj<u8yz zqaB^I)Rrs#o?rh&_}sR5yRtUG3w5j~xdm#(JNAY}Q1n&M2^ai2Hf@O#WY_z3gTiHX zBgi`XlPdE!wl4x32vp-@=|6sis{&4Tlgl?h5@+;`SX`RIZuLD4M|r+|H1N4ST5zqB z|7cDG1x^6SvoC4+WJ`7~2lsq#8q%+(X;e4kRDaM2Rn~hADNXO?^s-EefeA&kP#YJ8 zD1uH_=r~hq)`|v}yY@FTOLBX0IohMZCwIN39W7s?-MqI>c0eO}fv~t&jk+A43TK2g zoJ7#BO#2F3&HkohVjVAC!ZZ;>NR1yhS%AP&N1Aezv&A4jQdQ^3fg0YD%jH+JB1=MZ zb7d|xT3(@&cL|P4(u!py98SQf2(OausYA>5b_Rf}@8<_Wc0$xoX{O_d0WBwJvd;3| zzkV<IK*`tSt9S_j84?wHy+SW7WfF2-Zxq!t`TlgI<d%(<jG=uclwvbzx&HC;bMB=p z_V)OZ%_$Xe2G;`R-)@*9d{S(j%`dy|)>Lko(h-f=@{3L6CKC_uKmQ%;&}^Id0)2ue zrhY}`+Y1m7<j(V{*JjP+#ZL*=M@;f&{E{>A@LHDu*>|~ah;<zmiLR^TZtrL>*h56| zmR?7M$FW|0>qjM;Zv()`J>>9-Anq)^FT~nhZYE}PbBn%|@W4<hV}oMCl&>S-%SPel z04+@uc8_S~bi{PzeY~<+bargKxL)O%<rEuW=wlFEY1xaTGm_9iu_(MMcv_}<PUyhT zu-VL-+rJB!)NprP4Ge|WW7x#GAe=7)XnZB<lvT>$UY2W8u$u^!d%*WV1azPT7I{fi zh=%|Cf|sqrBK>6iGELu)i7BeoK5Evnd2obb&A@eCo2;%;?0#w>HaJS=u;h+Kt;6xq zI@-N+Gi=^pwZ>pt@L4>i$EnGp$0V2ry1C%~@ey1nxh3Cn&$UuHy+|w&1&+M-=&OHC zIwU#-6B;y2$^W7W1YSv`oBCugnC2qqp<l$ZSrl$+$*q;^G7b&}E^n@gvP~OPNf+x! zprpJPu4OjGiR5y35e^V*=3RF<+FArj+Cu*jooRv`|K=OjFu38WY<6Gi;@O5BirHX| zgG;Vnm8MLO^GKssHe=L+DKr?DP0LEE@fT!|b@_>B)riMAN&d)xRFSnxB5_>y6vxsD zlnosF5i(&lbdApf@t-md;N3%oM?e(P_=Y&~1@2PaKr9kXD8Pjh+oCaBDtGc2s(E1m zqe;QyyQD-(IP{fo-uSqrAyeVK-&8cT;3Lc!7OCLW>%ong{sorjRDH)`y8|>u0fV8% zzmyi@tPDes?$Ug>0i5b-)C`=kc=dR<35&M`*($k|zf1wA2>Fa4$t{@>xoYewVphw! z7h_Z}u?jVp!!dPgxw5<<DQ0DrmzzOZ3Te9$UgGfD)z+<^Zk?Op>w_)5sNWy1NYYOc zvMu&Yb>1BNuUr&;;TRGh<4|UXR9%!DPHiW5+EWh8Q6T;c#;IlKH3sMct-+W$?qklQ ztiMSne3~s#Prps$tHKLWm1uw;6me-aU}$MO25nl$Lw1wiNDNHhKL)@nf@?@)1=N3l z=1K=bHPUF({&PbV5b;Jt6t*n3I-BrDMJU~_oi3^OJ0b0Nj;F$QXn0<5zdpFl*l(JK zwZ&}VEaFhH16kjWxL4oC<>c9`+7=2H%LNfVY{HM*xqU2e83XR8B#`?Z5b&`z5?p{U z{ZeW~*H^t3nBOnD3y9wOR|GzlZvA4q7qyEEw=V}m6Lzhp9{=?A1_h4<skkvLwLj~$ z-_1WgxWBwFl5-w9ac+-M5Mu-Pxb1w;(b9}HE4P?-HUfG<*<s^-=#C;qmu_AXEY?($ zcz9;;3M`yLUd=E*=3L|sgvh}K09^0>f}vx0X`MNeY$)gw`n<+kJf6r39qPLCwt;Rp z+xQ$Mz)1;CAi3`!6G<N>SduLgsQ4=3*@Qj79jpj?yaBPK!m!^ebWdX@Bu~!aW-7Hz zD`mPah*&>3-=1Sd2O=f(iO`}HB6@_r^Rmnl24~b|)?7&=+s|Q$2+2w)f6S+c$>N>Z zZ?zYq#hJfv70H+_UTk)xfX^-PvGFmfQdQS-g7q4-EL_MhKu$fX`TRr$-*6E}uHMri zjExiTKsWe}7$mnEft3&gVl+gp)Q-vV<t?q{x=f6m5$nelt<|^SY?6+8!ACsj&U}J3 zg3vU5>97IL{fZFIv(rMK-?zouJdT~|XIab84z~;6E%*v^xognuf<8ip*>DxXJ;HEs z&Eir!7;CB{h{Ns9Nh1@tMANo&wEwXLJ;Tkv;9m>+8_%Q6o`9O8Oi={dqjXqF|Gw1W zc03!Vmvm{E{@2uSiGMJC9^38TZkG=|WSY9CSg7#OxQe)i)-ZGVcL4f?UoQXAmHvoZ zi&q38$ZE_&a>7<=sfT4|3yXOEBLe-8o|Cs4s>u8Y-2d+u<zHtTx<&fG-Eh}JoP4PK zrSAatY0x9DE7R*Wo;{0Z6(iurXR?aF%)>zaZYZS$T0;yW{(HAa4vB$ljp51~qVfW! zXsGaAn&)O44H*`KySolmb4Gs=*L+hm{<qRrNDboAJ^5Uq^Fv(cD{|Y!Ze#~Z!8jaB zo>!u;%opz*m|3ROtm66#G#QzJ_-UE;jt(pwLt%QBtiY*UrLZ}D`$Ysq`0lBxbOWf_ z@1G$LKBj<VZpk02BNa414jlres2T_$c_5g$JR#Qao1QK<IT0%w3T>8c0mzcjcXo3< zhY1_IK_H>&!6W~~34_M14oopwQ`2`v>1f%aezSo-Cvgico@t74#N1s2cR6iXWO$Jb z<iU8*5Hk35FN?**oLr2CnfOGjiLHV}q3vpP1GrDRy7AqcAwmb4?c}~`Bu+#^1YV4- z@~RB-B(7M6jfn2JsXq1Y-0;IBuV1-k0ain4=8_AX@KMzw*wD-ca_BkCms^5047|RU z2hr)3@fBd`x_VsOW42f;x!pftMP`#RHNDrs0xY-VC@x_5*r*B1S@tb{xJM<!y&YQM zz$`TP#r&>aezipSDSz(ha;b!(XR2x50(!j@6*;1bgpC%UaToCs<joXQz&}MacZjCr zx*x2C?n+KJnHmap*}4gTGZZ%D#aMt?Oe=;X#p35q_^2DDqq~B$5Or*6)_K~{>%4M$ ztqO^--LUKJ0K$FTL1bj$ceZ`-%9R>h7pcs^874gAI3m29nK{$bznbHI^`!b5kRqNC zdcE*ku$+WM0gXo>Q5JC;@rv1uPA{7SrJ>Z{*`=h2oN%RM0>r6du2mDQSFS^rWI)+M z2p*z-N74)Sp@;tAE#e}_Z!<($5V?LO2EodJFU+4JmwH^%@E3ctheN?<m{?L5b;dJo zZV!DnCh0#lMnU4x8K%=Q4Jc}I$-8=I8yewl5~T7fWN|muB_Wkt4)wV!Gdj~1M<GGD z2f~lIy9N{Ltjx$DNN>83sU$z%zrXOFJ8ei|v%nJ3F=tP4pai59u-R**7gT0J^NeQ4 zs!+bAvG~5K!HUI$U`6I8ZPzhp4kKm`5k1P=)wAcuNRk~_5i|geOPi8!Y(wKyb+zS7 zb|!PhQ-s4-rV^OXLX$1THfVB+P^OPaPcNalBf+BjjW^U=G#a6202`%5nf)S!ji~`& z4*9mrK`QO$+#HS(GG2!etEDH+nBcO_>~&4GVv;>|p{Ts4;Inmh5lKm~bD$??G4L&J zxC%Spe@GiExjo0n66wd(1LD|%<3Q(5l+Ao6YWwHzQx382f>cS?7e|8Y&4lER;4N_o zw_oG?FO5JXck8!ElYNfC@QD>yAQy$BkS9Gs2iDJIp7BQ~`k<#13bN>UsUTx=X$b&V zk&?R;hWKa)^c<w_os1yP8$thqrKQ5rw)cJ7@fzK1=DvB_to_6n^02vxbObVZSAl;O zi;$B|e+~1wbo*d2vo8=!p&C@@l`@7U_+-AB|BCFzYvJudFPlJuQdWcQOd@!(qer*t z@0TADfd-q*gu*ha)-Pa@Pe^f-P+|^cJ@XZ(<*%}f>zE**xT9P;c!)+r6M>}^>HHp$ zFGu3hJkW0<%BREon0y~jbqNScQWIYk&F~avW>PGf2jgE9S{|Nl=)abvQ#VM)@HF7x zH=%}=<SYC|OEpkV2~^@CVe`6J2aS)j$|=9-df=B%E@5i*xXK$!Z7#W?t@a`I6%HUT zvI%Maa0dO@<+(boT7x-MWOkn_(8r7K`uYM2-VX$4_pv~=6?n_v;h%4Z^ntfM_quff zRD+EKJ9+3&Q49+0Qq=u|dqU&J?Kl@74<}k<II--BViDe+xk&MyjB0N4(k#0k4_PPs znu49EKZjx~1!ck6KZsZ8cfh*;Pzj5q$}QOeGTyUS_4lEnpzH$KSgvBL!iFpkeo?9r zDs&N#j;6WX-?)dpYl&fanA7U7bC;eC)nxAE4JX2$yjFx}xU<^q(e<=GIP`O)RQNX| zeMPg4-;q8{wjW>h8j(Jvrv7Fz)a-SMdsV<-OdBPuBJsXcp`zzNO4$6KX6?$o`dx)U zTBvjbdNEz`15+6Z1^Q740MoNa*M!)E-?xkLjqO{#Lh%A=jl~dqQHiyHImx>bPbjBc z)5-y)V1x|m#pIP1x4*{d8$?%|7NG4X1@L~S&;=Qsui^9w!*3}|VtkkyD3CqGaGbPt zSZN{Tm1U{L*)}s37QXC1T=pkgrPZk~K8(RmQ3JilOxR}i=~N4MO%RLy5~j<@qJ))W zF$ltp4T;3dbxTmYy;w!5=iOhop5*AFViH6!34BCYT{Q$i2+c&48oz0{q>$sV3<kX7 z4{gRQzB)8v3ln6^_eC~9e1cR-^m#A`b|lPC$JBeK6k>DqJ}>InhKE@95z}ESNrptA zhDR8$#gph5M%_&W%uF`SV`ALh$Y3%ca%t)J6KGQjETZO!6d9U;awh^el}e7j^L(Ly zYa~LGRbeGvNr(b;3{^0NPS}O$>8MaUjic<n4@-<@|H|j3LG(WA%TfhFshwS7T3VcP zttR(5k*|r^u&x$<<mRrv+z^#l4SXBXWNi!%<0fi%)0HVi-wZb@zq$ThbM0o~>ZcmV zi>|3B+!AwDi_zUFY@Gj9*I5O{6?I=e!Ce{%?ry=|9fC`M;BG+z!7V`J?%o6oF2QLa zXyYyk?(R*nCfM}%pPBDrs;28!^?5k=zTE2Sz4uw`w>-|-UX4S!@QY$oKPaKiR94Yo z-bKXC;JX`d?KUJ%{)BdW8*;buNgh$4p^qY<(5>w|an5CsH6G1KLWs5NTA1nZ|HjCS z)S5+tKx;XZCOC#E#OS{H_!f;zH1AA<X%~`9`6HQ3a~pr_avJdu_l7=$Z@(da_M*}# z&vHK<$_>o_z^bTc!x9*l+qbw%Oi<v5f7x}5vXKh|P>~Cv6`y+LWj)f(4TqR2eHMGy zV0x!HoG+{V$l}}C(LZbykv0l8Av69F_?{62AM*^Ht^6W}=eEbnAfgtQmLf&rP;Y0Z zH8kYE$%jXMq(2&0*6gjEx~2b-2%tH=3D(PwE_Z6%f?WxFo-L6AcG~na4MNVj1`Kal zm<v{F<!Om%M?Q`DrOL1NrbXlJGbxnz2uYs&MxajHpPVW>x(IqsRCjqc{lcUfL#Cwe z)$$>MUji4j2AZ8vk8BQOs{l{yk(6duCEIuKAZGvFELHJ_HW+e5CrQQ4%-~^BONO7y z_^L;@l~pV6gdcubGHb9pd_%%E-+o>vzoS-TktMBk<m3#YHw8129h|70EeGHk3%W(t z+-h~fq@~*Z9%OR7DdP0q6eg}5&NhAUn7~qWK=Ci0(}L}-7fCp@7kez;43w*JPK$qz zR*OjK`Xw6tw@uC@{Q*%pRK1m0L~s@*5t2WcUb?RDdk<%COgj=qOpKCi3gEpZ$Px8> zKsuz<X7Av@y#<$tS<}>TY-}8!vi1!P31MMj!D8hmXXe;*go`C)!$LZ13PhpgKmm8Y zaUW6)tl1iWd0Mh$$hzjaYAN4#{<zb$Xco>>!)(Ji>w6JrOClbKXF?&N<@F!A+u4B_ z%tSs!8JSvjr?H{wC(7g3G51pGg!c??*&o@Q^^Bl;rMQMtv(ADRx<&$u%^338<pfpZ zW6<kmfIRU>OC>u}x;#{C*>?88_53gIdyp`7;brwtKxKvzT<S}*nCT5I;*V!~0R1ql zAD%54p6&F}q)WdILLKcj1Yx>-5}#Nx!i9?KENZbJbQJQsT<=?r?GB7~dY$_=q*kvc zPg%2xMWMSrg?>L&53Oq_!DGi;ZX{g{9_?RpVVM{W*Rc*ut47U@K=E+2jac65MDAP7 zdBy{UR@LB<g^GoBIVo&b)WY*mXlulI`t#aC;?4qZ0l<^Fz&-rx<w+qtGb@Q$>?sFQ z`Qhdt{8)EQrE4{64jkg)Z4T(fcL7RPEbnaWdKsG;^Up+W@Nqed6-FZ7qB*~#oa0rU z5v@{ik*BZFa<t4)-sbw%QI~a_I<LpH6kSPt#sO?IL5f?BCrltZ7vIl+>%i>C@=GV_ zo!OMhhGq0H$h>wJMf6KntVq(Fd#*`~w<x{}JuLbrnZ8^n>Y)35y9D))RxX*k4#%=8 zZ<-n-*k&Q^pT#Q6CtTfnwTRz_kD$d2tI^=ktolg3IgptAK&{O$K8J%I8>!#%Xb42C z{s)3sKg)1Ry>vG^gvN-eNfXvzPk#?ad(7f$e;VganMfmV?kyP%GQnMrjK>_OABNr+ znNh;Kj<wU7?Tfll1#@jNXh{F}$Mo=8Z`;8nc+<i13ZKLLA6Hs4Im!P|wew#j|9?0C zcLw|KSQ*iBIPceueuFM4dV~S)tOES8>1FVvP!x+6BloQ>+NYP{z@-t<ad^DM6@07; z_QKfr?#0P2NYfRIoA}}D?@L3svm;#NZodQGru>9}hyVvJKx%ba(v6kU^1b#HE5}_e zqNc2WjcgUtxSCBoqvCi(kcfSK{z(g@G+t*qGn#-wT^4+s6>Q#63SRaMZ3I1D-33tZ z+#Cz%CyD`&cA48FG&e@;Ohv!0R_L)kHCYh_e}812f-uw2aKGWCr)zH}@3Yd{g%n8$ zd(u$}#;`w$o1TCghDvp5X=zDaC4<+VQW9t-+X(ZntK2)(5}H16meTQbaj9Wx3BmPp z*Ert?h|4jy4o<={-zSi-{PiBdxeI3KL6Mx|bsducj>hvn5G{SwN(jf`3`d|9VhP;6 zSV-tIoP;?)k~%QFci8{4gg-(;!s+eN-BRmyyzJ+DDvz!x@4Krw#LIW$wUk>g!;TB4 zKiCM1-Dh-OZ>5aOdVh$NVhTu0ooQ7kj~=ul%u2V|KM|;?(DL|--s(!}^*ES192H_y z`A++MOM{nqzb69DxQLBa6$ZK-#MeX5<~4WvP+vAT{6dsI?R|Ud{AJg4oS-GATyn2W zAg|>deF(yy-q1?d^(Vq}jEbf?WL1|(hDe3+zh$+ep+zsf-)K5sJ^gmDjvdbQwhz_g z+OI(U4&=9)<7aOlY-_jSL#6P2<5&ARm_?_O5Qu^Ufxi=;msuq!WOo;Q?S|4>iBo-` zG3=(`jnwf8dK<~9rKDKWH2u4+{i|W_7tc$L8k1YMCp_I)blilF2F{K%L1!^gqO~ZM zC|h_%P37<yL?;~8j~<3gXeXnBE;%Y-Js`J^fBZfInsgWPJl<e!>?|4!!@#;Sz#A|E z3f(i)mu+BCN07kV8)E>5HalJkSLNcWna9o>sETpSjlsaL{UK;=uWaxp7_|{^WrNy@ zE*MGPv5L?`-gm^+wE=TF^!aMJA{8)L+wo`ypQPV6ad2>iMWL?aHr_ffH6yS3JcU%9 zI1whFCMY6Ok=?(ks;c7oJQe8Lemc2mCesrfRJ2I`WwRo{)WD29NKOErWvp%X5iw>C zWH_ZktHcRAJEH)Yq5d$!=5dVHPs0%r5n-vVh*U0$RO2Xgp$zWshFFzP&L_t11nv=K z_OqoIH*~#82FuCLO^l9&L)2sDo+t>jJ{SJIac)Ry24ZrtRKC%y3YYyr#DzXS874=k zq+%wBg}|uiY@aTMQHAz+e+vA1m=>M&z#h3qfbFxRBEUYD8Q61;YSkN2WH4P&mrTwq z<xSnK-n=vaV}7Q`?Hepdr(xe0nF`!?|1qMYp_Sy-hlR9c7)#bpaa8@%ewnpYf=L0% z!Xd!TA@)P^xt4|Rn{}h<&>bVrzhvqV*F8Cz74WC>;gm3^{6(>u0pn1b2qXl$aQ0KL z5m)Y1s(xVX4fzL47lLp)+E`^WbsWhBhBYT%+FJc2HXyQ73>w0mQjI==2U$(BXpM6H ze95eH6!S6Wq>rq`a=sBIMxGi&P%(G=jY<LblsIQ;QWb;j#S>Ek%ICQ}Zh;O020?;% zRO+FkEF_<mBI!i65{~X9+lO_-iOS*J$0MLc1X|^9^)Cch$sbFAVd*MrW2Ll?_NmRs zFAGd`pKrwR2}@m%FO(iiIpCLn9wL>FefLLfqa)>IvKD_2F2x;e4CSCJuzyq9Uq5!n zFUbL#O!sDWe5P=F!zUUh^z@W}<Bt5re{A4ZQ!Fa*AuN{cOs!raqz!{NwT-y;+YS+G z`(F6ElT2&1*^!`=YpI#TrwMu2gJWmBRSxBPA!&QBOx<2$I<14=e>T_`xK}9P{mxjy zN)Gi>?X&exY7a1inOQ+?YxD6>0~wjOf<d>)W`V(ULy2H&rV@0%!->ITK6~!3E2zG= z8CmVL+@f52yXWT}f61~1U>@iGPyPoKfL#sC!v;MpvNdWQIog9s8ppDO9TO{ri4%>Z zgWcY_2<jaNXWqHgG;QmT#Xi~8e<nakE;HQW_}lJJonD4_gWfj#L|e{JmrLyzm@IUc z3hhF;arWv1MN9mp%-;vxqI`CxO?V=4DA6i=6HUoq5~kazW%Lz!z0X%rUq{}e-2p7t z&wLu#nJ`uCtu50Y=^9lFtGD9CkaN@`;d;ewSWKF*=Mi@#E;Yunt=P%TG4L`bg&3bI zvOvPWUDho>JE*hp{ydK78FXF5TSRJpnK)cRpt$XX2%?K%z98kr!}z?<x%`x)B!AI& z#tVbNEJBh90|1RbMZo|^0d<&QC6Z);6Iz15^C*kbhhH%ygM#4?{xp&jxN*Cx$=c-u zZKH!BaG<vY#L(x4La@|e*V&fd*$TZQ_3>db#WTNhZd*?VIZ;2Chr=)-_C!bRg^?J1 zYXnIbviK_d_KcU&-+%Ot9KkyZ^?{@aY~^}KNK7MB{OMUtHeu@FGN3e7{F@qU<i|2; z!mD;G-dOEAXfJ&qn;t=l&!<GHais{E^<pzUHe@IEDm-g^Yb5Rb%X6tHlGKZsSVfj~ zLI)1c!5dvaWfyLm(DZ9ek4wcAGT;+~a87O%7azZ{`FeEiAto(-q<45H(&kG+d{P>l zwn_P5B>?+Rxn9vXF*g|6xuN$F1;<7Kl$#W4`+*do5|ls2HIPe)T`UIc(=v_8uvbk{ zK6yAyrz_2iASpZ8jZ4>|sCEb&v;#&ri)aQRnu+R0633YErfpijugn4tCMZ|B_TH<M z;xLrrj9g~tn1{3W?9+cwXDsWYdQIR8OC|A3abit}kO&u;h2uc9pydHSHWZqdm6SXo z2+#Y(#Wal`!j^MJM}LgpzJ0s5i<^;$(R9d36U&S9)o!Zy>$Kz~h#n9FM+^)Fy~;s0 zd=Gw)!W^~(1Dh>GyVwEACWgSqd_o(CARf0XtEYg$VUopidZ#$PWIe0CX1}<ffy+w1 z{?1YcbQ<xw&dy6g@9H&}7dedMAKau+sTJai*yK26{jmq0BKH0z5zA(MB_p-Ht<Vrl zq}KS%Z9l7I2o8ixDk|8!SMK;4l3AHX!ulJwc7OPK-28apxuAfPfe&pl!eytd+bKlL zHQ?Hro8Iq5-9=O%rsGO@tSS)#T@a%YJ&a?xs+cf}@aA#K3iU4{dZH?{%|As<f<-4t z@MBu;eTEmf1q2y0=w~)jFBM@lY`vIqisAj!Msd^gPCT~qgd$uRs;DpvX6<YvBcf7C z8#5}Hjhc`6=5GSy7{CoSMn75Vh5@cZpT2I){BOlNtRIS~R2QUSno3HR8g6c9lhvW2 zzOI{0dnNkY5x2NEz4j%Y*89mC+=7A@0^0ob*hRK+{rxX8OCX~}lqT#-h+N!XFIQpn z5+S*&WLjkp@Y_DQ@F=7V0mWnv3!yyxl_}g;O7e)=g1{Ov^F(_TB?}3afaPdz&ousV zE~?@IG0VXUG>#r23hM9<YhoUh+!TDj+n1kcHRR+meL4h*>7Pw`G{T;`emd(h=qDaw zNbPuaOBV8>_{QJ^&XO1z>N6N7BW7iULFN(umE?AcZAv~72z-%>JC*MX>h$uT%&jD= zeoz@I)IG*89F`*@LVqut=m8KTb*un8)Io9$kqgVs+&)iwT8JG;>dN9!JVxpVqr<S~ z&KSXJ4pz8fRX6+iIHxXIUz+f9(@e@}DT#mwlHFu>EIPqZNvfxXC}h>h`G6_^#f$6R zL>^FRBPVg56xm@WXPcBFM#~TRV9GT9yCz&$iYDhHwPWg^3*8QjSaPR9K>+*#sJm17 z7MRXfS4;VDTpx$b6uyfKwvmiJBSP-zmaV!8%hJJ+IPPKuA6L{?LlUu1p;wJWFxI*^ z5z8XnUx?B1f0q#N2?=NQ!A=WH7*79u>r+SO$QB~UpzC@c)oLK-*rw<BLRz8hR_R8G zBZj2I$b)10whbB8Q@)q%MzK^Vn@5lzPtr>A?+Lk<%*thAy6l8hMuG&9D8p}oKK~q< z!dZtDb^a-{o!QxI!F@s5c^i3&-=UC@qy6%*cyEj-bjRODgn&y&cQwI-;q<~a3&jt> z0##<n03|-;x~Ta+J<P4S->!u=)3<0q)L-WKFP1HYuWCl1IGzNr$0qBGUoglZieV?? zWI`Wq*wq4;86BBarHo)6{(DfJHKLU7)}oIh)MZetr}5Ds5z5Kc`kZCS%_=mh&5%_X zmDOaD-c=>aAyp77bjM`nZiMYLNxZL}okYIS%ykVpVjwPB@f3*I>!sZx%2E}FdSv4g z7gxIVm(9bawwoe>UpkP;nm`MD#9r7OBQyMf`n9aJ>ZVC#AE+X8G0rtPC{|)^8ryUY z#9JeA706lYny-SfMW0sKH{*|bpiwlbs#3*$JmXXiN2v8x94<}Fzrw_rBp<Qb=&lO3 z>A?!pwQw#8<x-$9IRUf!paJ;{(EVA|W7{>D))0325w`l1`|0UBBh1r)15!mZVgABu z7GOgIxT_ghYmw@AED>=}uG`(36;U&wr+=+o;Bbjd&ztJupBKO3!23(9jaqEJ*}Z1J zbfm=dx?a9@7L34R<FhIM_=>T>{phr72LUAvhk={G;L}x=NAC?5P7ZI%w_YEKw7f9F zA6+s4;#j9UNu$6HOBHIanz%_BY{$iB)=mPqj{15rl!s1h-z@1sz<LTx?Kp<qf8udg zpGQP)y6`CxxxXpf!)8%5{)IqVQky<4cwOsx9L`Rk&RUWXZ<%!MoxImD*>t>wTO5rP z=NzaAt?)Yn#O6s?W^un`orlqY@tkxD>~8l}{{qOdqU$^LOhujTc4nPsK`cU5`hI(M z`*q?D-Z(3(#x^R4oUERpfqwI**&lLZHROw^-?1D}RpL&z+Kyf)@4txb+h!~!{}@hx z0nz+8T;ec%Hbx;Ma^j$#$IMgok`1|DkO~<g`+J`nF)gU0tm6<`y_NOx6DGxsacw&} zwRTVK`j!Tbco(_Q^t^xdW3j!Tz?o-jSB68?813zOJWepxj15R8(2kVYwXU9_0E8t+ z?Taui&iiIL=lCZn`K<EVukL|i%N^Jw{AenmC{3#iVRb+!Gdg<@p^90X<Qs|o+y|3} zMJC~5YDkBZuh;n`r!pDUI_kQtn0o@q-M;CvS0=FOT<qq2p8S|JXQ}O#=3d0(W>Iy8 zC4rADo`scFLBaM1`^^w~5>-qr1gOktmcL#+Q1D#NZ3DGHqZBM194@MwMeCFSrj_eT zQ<NBM_#Wbru<}?sny`unRBrzy*}AOkUwYq7LUfimQZ4RLc&Asw$HQ)`BQlhHeQ~)Z zBTlx1ZN9M{)AoB>DN!7h!=gu>T88Uiv42$9)!Hz^9P8~YCgPnItnX4>R*kp}NxRjp zDhx+w`!SJG&fG7dyd2$lQudC%XG+Ai*28Dm7*q;7vO$>w;AX6}`df9?GZwf+_9AL} zfj!<9o9v;u9bJ8u!EWO&uQCDB+fHrkHT@1Vih3h~xK6wCsiFSo0f5w9;!IH@bCAf= zvpz9eM}#rtx0O;#UnGl^PkTxgOr-i9kqMRp8trtV(Zz-_9VA3rz`Km7Xzr*cYyOzX zL8}6<t~)WmWi|On3(d&+#eAlV{wJOBGUGO_crt;%RdNR3AUS;QYhkgO)c^AH(*CH% z1i)4CT}Lzp|AzSt8^lN{J3Y4!GGiMFphK#!5CTofh)EtV-;1l+iZS*6<~H*|f^Xl* zRD+d=tGVK%@}ER`bMiZh!REs7VJeMaus9`wvcGu&ha9t&f)IVyJTidTQS#1VlRT|} zBK#vCv-`s@=tY$B*!-76WtEj?@pv(Uf4o@##4nd&NX{?*rxCb8GLe%%I8MpQe!>C3 zTgS(t=?nb%!Vl!c!F;~0m%v5p(*%Vy^PzD2P3d25-=3`1%nkF{e)^qbJY{~0=_=i9 za6VtG5NJ-G6Mt)ynnzxg9D_uRCDg4IZjb6MV`nKcSJc0t%*7$$fn(h^yyF(2`=#tp zWq8Fl`&YkswhWB4M<lD=%Szwm{QISgYvmeuoZ1f&VXET!J=kZl($<tim+^zy=kA6n zdN_v;=Yuya#EGM?0i99BJxlS#KHnMlqX+)vlPRyS@njs3rVZ^sj9h$;t}G)U50r1Y zmiK6gtkCfXzac=8-*S6P$03p%9?&C};2w~weUfas55<GEX9DLwc26oRe-HdD&3vXh z(GL`}YG7%>p_Q-v$}3$rq)WM%{q!I5W7>x*Qv}?sk2Gc1%bXW2`#h!}HK#>$&EgS1 zqBv_#^a-clwS(;4rL7@NDKCZryvVrE$<bt}xFC~_PQ!}cB@5QFv!sEJX0}vnY7B$5 zBT10^_fG8kWd9<s2fw1Xe5gL5vF&-B->5&plShV7^bAYoKbcb)bsIaRxk2G9CSmV0 z2E{~*Db9EY&Uw43p+rz8O|dnS0Si7V$2)d7zNcT}^p6qTcXXr3Cl4S+5+pdI6JbC= z#X>=>5fnqBL*LV3b5JH>6~f-d984Z($Zu>SY5AF^$nM?}m?opip(fUF-kg1VKo}2d zAiGzB;Z4h;7Rd*1=QNEcffkpeTR8Ug4d*N{MWWa>$IXV?tqV=(0~16%I*!Uoo0esb zlA6eMcgy$r`xACUQkvy3-GMe9$l-Mjf@x-`-Fom}zF4zA0gtpXnLUm}o~Kra>9gO2 zRR4#S(hL?x$2cB|UpYAQ=<P}@YNgXTBehp5t{z!4Q3HvJal8HWbc9WVDD;(F7vjZ% z4v%F+kr8Zv-#O0v8B$)ARa9l+(Z1gf??F_zBfqN2{RJ9NRO#?E%lN0|Y1roHuqZp` zN^?Q2Zb}Ofz2+xvI9t@iIwMNdej%2yBmi&7&lMexjr?i}6kL$L(3Z8)h%3Z&jI$V= z10Lc5@FVOyS-^ra<FdLsu@5u3=WF!j-g(&m#YeeOmBv)_qI+pK$dKy!*8C3IXr$&~ z2T<B(D248z3(Yb6$glaGnWyHxY{@X$c_)TL(;A=Qh*JoI*~!>r?B-!V5AG&DBE9(m zko4D6zPk^;i_WK&=>CSZNcR$1pb^y8cB*LZ^K7}MTQeqx2jz3b3~Dd#cN!|Yfc6+? zWpOYrst3%l)0u27r_q}Gf+Y3>+t2F$Na6q#S+5dY0sz=cyonI<H>5l~X`$F7P}h0r zA8H4Ebe>IDKxK9P@S(~_UolZapKTV70HHHe;Cej0RB+OOd*x5z@FT!7Dz4ODnia4< zl!qi<@Xb~KluedZfHvY$*euS)2XU%*(RDuC<ZdfuYM*%FX*WQ3N)zA&{JYPByAD}5 z^M6(*sAU|a|5>%;{C8J&qYXEF|E?&v?WhHOHRNS6mI}X#B>uEFo$)`nlPre*N)PF4 zmt*B*moqc#K0TuItgf4xsjH($0bUu*c&9Uhv771uIFI|Qqs=%Sav_G>O5G-}&vAlj zIC(uA;YU$Sbn-?(F2Tz|Yp$LM>A{5V&ITOgKWDuXni5g(H+T(5fZH~g-Os+4=DPT6 zb(CxH<H4fdqen%nxxD($L{|Yp!o9r^SDVc`Ii(6BfB~$fD5$QchU~4(OI8=wlQ({r zZY*In+H}-IV-e4gxniDnCOm{Z_lDY1;15{V6$?&M+t}XiBQ|-ZjDJ^)Qm>I4?j!kx z+n;f3*keo0)CFY=Tj#n6n-OJ${zFW=8q3O?5sGG29s1$WBFgdPfX<&wHt}67PB*uW zD2mir$~eq??xg75s#a~5#YHg~?Ygs~f~(I`K|_Zl80IcCMTptpelFXt`r7rciiLH! zn~91k@^N?U-bD;*Y{$cUuG2+wF@7H3XYoYTEHa=*Bu*l^odo3S`pre+(`&;oT`$!8 zr@uSdA7%Hqfq8o&%ef$Cn?m-6#a`=MI@-M@<w-YJ%=cu$oTm_1FVpe;Z7e>rn>D7N zlfn-F%2a*K?3>loKOoy_<YBmRadDV6rmwC&c<bbNP&}rp8#eD**O>hx+m$^td|k&k zILkO<pMx%Eb#4<7qM^5G&#O!S1FQpLUBzq}H(dnDd8^6Y3r$W}V#mPGnHio;^bc;0 z*WAJkXwzQT+k}k7N*cwh)9$MdrhmXk`Ud=KYIJIQkCO>vJR~k!pLC|RXv#97wap@w z!U4`gW`4)EYJtZBYUWVVT$5i@6_b4d)0#4&nHR+$W4QD=`!Tt?;=gtCqoeL%<X;gm z@1BA-w_6O%`uL_LlKeimnz9<z_@BY1F~nb|v!G9LT)WQ^-%F-!hVQ>mK>l88c4{D` z;(P;ER=2hj@|4u>Uexu+A5%-S;932v5pi&E_%gWWuR{R9rx1D5=OlVFHZa0-Pj_lU z=Q(x6o{Z`_oN7yLwFWH^5_&rMY3UQl#B`B3yxTctW$S?q@KC+7)Iqko9^-MJ_Je%P zyK+$jynD_}7!BCrc~v7#ESMfT^X<qepcI>8upYWnn^^valk|)iM~q_|V$!c|^bvS} z$F!xLdiNPs2YRRJ4ioPjA|16@qj4VTA>t>3SS_DWU+t`EHhf)G?0WjbMYu22VMRG3 z;3N_!_;~Y{Vm!lQx77vaJ>Y~DTR32cqeoO$T%nPWVBFKUc$!u8Z{hu!@W;KbF4BTG zK|^Yg`_-Po*4Mfanrj9tT~!{d8@#9BFI@5YgU$n^1oktX)6#bX&$w_><JSK9pkJ<R z2hW2`abp!(!P}QQ`qcU{%%^`wJ2_y4x)9Wy&uM@2WHz;;ZjWyb|9+98@NJYbJ1JCr zow+ldTcw^g1wsdQgSdN@-mqT@PXEc{{_HHpK}w<Q$+51s<XF3Mrq8gD1D!hBfIT#9 zXbCP@*~?Ix8iq_;HO_*+22ccg(CBXxgm?gv{ZEQ{Nrc{}foo|_1F>wh<#@XCh|3o` zZYjf{QwA3pm+Mp1L#c+&E3KIO{#4>b8huP&xc$~iNpIJGnjWv?>=ujB32*}AI^Wzz z-zqFYAIh^O-B_oH(~GL$*=bOGG=6*fx}WF=v3mKO1iRfb>n6lJD{$x&<+wqetc(op z!E_FGgzR=K_;#iX_B1Y!pt+PQ;3gCy%_b+7f_-X@`9;Gzr2Mhv@H_zZq43w!$&Qnj zm=u!A1D@(2$q{>`qCK#?6}^W%+*foW>ePp=MMyEA;g>n7kmjmxCJyS={`<UkSeoGk zlXAviRgNR}aEv~oK&(ISzax`tJ6-l%3*HSLx^E+dqUoqy?@&`s2vUWIsn&BzJQ9?B z>p~A*kJ>uF-x!*yxHD;2-VVJQ=>Gz9-~edkhnP>(qUo<ktj6=XlALJ6LA@xI$H&=H zK7vor&n7%=sOGpr4s7pnbWg}nX&6zq&YfHVl?c^Cx6<hgk%LNU(9s7r*Ox0N-<bLz zN507zT<>dk!9&1W`76w5;yUNq$#56V6`mK_6_e}PMVsOxC=!L>B4m)Wx852lc6zv^ zGzMo|SSvLpWTKeK-UgF{i5{Wjc6gO~Vu(*}Wm{SeL#WMxUw_xL_}WjzT8`8zb!>){ zBV5e2jD`#K0un$eR*L(yFKr8Nauh>0N`{LV?5Mp#9|lKe?;E#6Uh#up{G?ig+9>6U zOHxvDVxCcP-M_>0Ufs>MYMHENr1v1N7zr`idES^B!wiK6mmA5+g67q;Uv#l?s^9+h zTFf2nl8NS_`N(oL{bJhCWln>0px^88)xV7??p$+noIL|DGT{&TBf1|VQ?B3vN_m{J zSi^Ery!h)Y9-R>kX(aTZG(9`OjbW?!O?|QQIbH}^X&o3vN0EK^@|Z1gFXy}#1Tfo> zFELeIiIK<_3=$Nvm%M`*(02F`8uSIy*`_AB4AzKTb9)`gE{P`e!el5x#9;WpIdR!n zDXW9C2g834`g+Un-!I-{V913V^UO`ikdPgmW7sx(!4M?-J0f-#E_s&zO|}tBMkP^f z>nChDJq<+eY=4m~Q+pw{n<$72a#R%O3r2G8U<(vJMn03wiwX+|`u>|lW^sJFW^Zh1 z@$!9?<}HKImt&jRurThz!`i>eNV;-o8Cd>lP_tRsTnqY3#HNOR-#bTt$n&5~X7_zU zq3B#Nftl}x*}@I#$mngQZU4hw#*Ls*SD9EZYp+C3nFJEZ-k9n!Qxt#{o~dYKcQ7EG zUSh7Lg!EWxxnQ@mj~>SpFiw^|<{{H8+#hYgT13G5lU9tD=w&^iSA9>~RDsq*^>k~s zj$VGn2^u8UH?0l<wYg3ibKm7gvl0}8|8kSGA$I-_U#sEZH-a6laAL7lhP0=76T;8v zOTG&4wKCZd|EA?=9*7|Nso(VOc-i)diu44_fe~ki^6(G8jJ20E<2%|l)$QDqFYqoF zeb5fIze|rBP(Q<<Lu0tze4f|rPiTZ3t)r?nUmB6g3^#tAGq>MlN4GYLrY4RizWG78 z2@=O`ORn>!Uq}<n>TAc(ZtR-mXCFrvYbzWVC^&zipJ1Y|YWg-DK<zTzKP@REq}i$* z+UI~xYU>5P(UN7|E2^j<)Sc3^8U+T;=uRFykqY7Dy>y&MZ(UyQ{|nxwSm_|U47|ZE z0Nrqf^D2y5Gy_oQFvp=o8}j0<>{M{%1h=0di9g(T)vl6l|9@+<g8y5Rv8w*>+79vm ft?giPA+M;)*vz0zmrk-b@Q;duhJ2l@McDrW<(&k& literal 0 HcmV?d00001 diff --git a/docs/src/.vuepress/public/photos/developer-documentation/forge_slice_message_name.png b/docs/src/.vuepress/public/photos/developer-documentation/forge_slice_message_name.png new file mode 100644 index 0000000000000000000000000000000000000000..720749418e650a737f306b5034815fa5909d36fd GIT binary patch literal 42421 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 DF|YO+ literal 0 HcmV?d00001 diff --git a/docs/src/.vuepress/public/photos/developer-documentation/keycloak_realm_dropdown.png b/docs/src/.vuepress/public/photos/developer-documentation/keycloak_realm_dropdown.png new file mode 100644 index 0000000000000000000000000000000000000000..493fd025ff9b9da228b320987f0a2c12a0139392 GIT binary patch literal 27715 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 U#v%uZ>(5Y!+z(d#eCoIV0@(u{fB*mh literal 0 HcmV?d00001 diff --git a/docs/src/.vuepress/public/photos/developer-documentation/remote_debugging_eclipse.png b/docs/src/.vuepress/public/photos/developer-documentation/remote_debugging_eclipse.png new file mode 100644 index 0000000000000000000000000000000000000000..9b1399cf4dbcef4723119cce44ec4d86a60cf143 GIT binary patch literal 42092 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 literal 0 HcmV?d00001 diff --git a/docs/src/.vuepress/public/photos/developer-documentation/remote_debugging_intellij.png b/docs/src/.vuepress/public/photos/developer-documentation/remote_debugging_intellij.png new file mode 100644 index 0000000000000000000000000000000000000000..5873982bb1c0e1f8eb58581b0acf77ac4df4e855 GIT binary patch literal 75066 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 Zx*@NRtGYj2hH%*d3@pa`7{etj^ADHL7U2K@ literal 0 HcmV?d00001 diff --git a/docs/src/.vuepress/theme.ts b/docs/src/.vuepress/theme.ts index b43967aa5..3f5eece31 100644 --- a/docs/src/.vuepress/theme.ts +++ b/docs/src/.vuepress/theme.ts @@ -34,6 +34,11 @@ export default hopeTheme({ text: "Security", icon: "safe", link: "/security/", + }, + { + text: "Developer Documentation", + icon: "info", + link: "/developer-documentation/" } ] }, @@ -88,7 +93,7 @@ export default hopeTheme({ icon: "info", prefix: "intro/", link: "intro/", - children: ["info/introduction.md", "info/basics", "info/architecture", "info/security", "info/allowList", "info/process-plugins"], + children: ["info/introduction.md", "info/basics", "info/architecture", "info/security", "info/allowList", "info/process-plugins", ""], }, { text: "Security", @@ -762,7 +767,48 @@ export default hopeTheme({ icon: "guide", children: ["introduction", "generalinformation/", "code/", "build/", "releases/", "tutorial/"], }, - ] + ], + "/developer-documentation/": [ + { + text: "Developer Documentation", + icon: "info", + link: "/developer-documentation/", + children: [{ + text: "Concepts", + icon: "info", + prefix: "concepts/", + link: "concepts/", + children: [{ + text: "BPMN", + icon: "info", + prefix: "bpmn/", + link: "bpmn/", + children: ["intro.md", "sequence-flow.md", "service-tasks.md", "gateways.md", "conditions.md", "messaging.md", "timer-intermediate-catching-events.md"], + }, + { + text: "FHIR", + icon: "info", + prefix: "fhir/", + link: "fhir/", + children: ["introduction.md", "task.md", "activitydefinition.md", "codesystem.md", "valueset.md"], + }, + { + text: "DSF", + icon: "info", + prefix: "dsf/", + link: "dsf/", + children: ["about-version-placeholders-and-urls.md", "bpmn-process-execution.md", "bpmn-process-variables.md", "certificates.md", "draft-task-resources.md", "environment-variables.md", "examples-for-requester-and-recipient-elements.md", "message-correlation.md", "message-delegates.md", "organization-identifiers.md", "process-api.md", "read-access-tag.md", "service-delegates.md", "spring-integration.md", "the-process-plugin-definition.md"], + }] + }, + { + text: "Guides", + icon: "info", + prefix: "guides/", + link: "guides/", + children: ["accessing-bpmn-process-variables.md", "accessing-task-resources-during-execution.md", "adding-task-input-parameters-to-task-profiles.md", "configuring-the-read-access-tag.md", "creating-an-activity-definition.md", "creating-codesystems-for-dsf-processes.md", "creating-task-resources-based-on-a-definition.md", "creating-valuesets-for-dsf-processes.md", "managing-mutiple-incoming-messages-and-missing-messages.md", "setting-targets-for-message-events.md", "starting-a-process-via-task-resources.md"] + }] + } + ], }, footer: "<a href='https://www.hs-heilbronn.de/impressum'>Imprint</a> • <a href='https://www.hs-heilbronn.de/de/datenschutz'>Data Privacy</a>", diff --git a/docs/src/developer-documentation/concepts/bpmn/bpmn-model.md b/docs/src/developer-documentation/concepts/bpmn/bpmn-model.md deleted file mode 100644 index 66e2e5314..000000000 --- a/docs/src/developer-documentation/concepts/bpmn/bpmn-model.md +++ /dev/null @@ -1,4 +0,0 @@ -## BPMN Model - -The DSF expects BPMN 2.0 for its process execution. This write-up covers the BPMN elements -most commonly used in DSF process plugins. \ No newline at end of file diff --git a/docs/src/developer-documentation/concepts/bpmn/conditions.md b/docs/src/developer-documentation/concepts/bpmn/conditions.md index c523ee82c..631c2817d 100644 --- a/docs/src/developer-documentation/concepts/bpmn/conditions.md +++ b/docs/src/developer-documentation/concepts/bpmn/conditions.md @@ -1,3 +1,8 @@ +--- +title: Conditions +icon: creative +--- + ### Conditions [Conditions](https://docs.camunda.org/manual/7.20/user-guide/process-engine/expression-language/#conditions) diff --git a/docs/src/developer-documentation/concepts/bpmn/gateways.md b/docs/src/developer-documentation/concepts/bpmn/gateways.md index 6732c17f7..8c9834215 100644 --- a/docs/src/developer-documentation/concepts/bpmn/gateways.md +++ b/docs/src/developer-documentation/concepts/bpmn/gateways.md @@ -1,3 +1,8 @@ +--- +title: Gateways +icon: creative +--- + ### Gateways [Gateways](https://docs.camunda.org/manual/7.20/reference/bpmn20/gateways/) allow you to control the [Sequence Flow](../../concepts/bpmn/sequence-flow.md). Different diff --git a/docs/src/developer-documentation/concepts/bpmn/intro.md b/docs/src/developer-documentation/concepts/bpmn/intro.md new file mode 100644 index 000000000..de7f59511 --- /dev/null +++ b/docs/src/developer-documentation/concepts/bpmn/intro.md @@ -0,0 +1,15 @@ +--- +title: Introduction +icon: creative +--- + +The DSF uses BPMN 2.0 to model processes. Specifically, the [Camunda 7](https://docs.camunda.org/manual/7.20/) dialect from the [Camunda Modeler](https://camunda.com/de/download/modeler/). +Modeling processes for the DSF requires this modeler or any other modeler which is able to produce the correct Camunda dialect. + +### Common BPMN Components +- Sequence Flow +- Service Tasks +- User Tasks +- Message Events +- Timer Events +- \ No newline at end of file diff --git a/docs/src/developer-documentation/concepts/bpmn/messaging.md b/docs/src/developer-documentation/concepts/bpmn/messaging.md index d9bb2b812..a7bf57612 100644 --- a/docs/src/developer-documentation/concepts/bpmn/messaging.md +++ b/docs/src/developer-documentation/concepts/bpmn/messaging.md @@ -1,3 +1,9 @@ +--- +title: Messaging +icon: creative +--- + + ### Messaging In order to enable communication with other lanes, pools or even entirely separate processes you need to be able @@ -7,9 +13,9 @@ uses Message Flow. Message Flow is typically represented by a dashed line arrow The following BPMN collaboration diagram shows message exchange between two processes. <picture> - <source media="(prefers-color-scheme: dark)" srcset="figures/exercise3_message_flow_inverted.svg"> - <source media="(prefers-color-scheme: light)" srcset="figures/exercise3_message_flow.svg"> - <img alt="BPMN collaboration diagram with two processes using message flow to exchange information between two organizations" src="figures/exercise3_message_flow.svg"> + <source media="(prefers-color-scheme: dark)" srcset="/photos/developer-documentation/exercise3_message_flow_inverted.svg"> + <source media="(prefers-color-scheme: light)" srcset="/photos/developer-documentation/exercise3_message_flow.svg"> + <img alt="BPMN collaboration diagram with two processes using message flow to exchange information between two organizations" src="/photos/developer-documentation/exercise3_message_flow.svg"> </picture> #### Message Start Event diff --git a/docs/src/developer-documentation/concepts/bpmn/sequence-flow.md b/docs/src/developer-documentation/concepts/bpmn/sequence-flow.md index ab4c470e9..715e8de49 100644 --- a/docs/src/developer-documentation/concepts/bpmn/sequence-flow.md +++ b/docs/src/developer-documentation/concepts/bpmn/sequence-flow.md @@ -1,3 +1,8 @@ +--- +title: Sequence Flow +icon: creative +--- + ### Sequence Flow BPMN 2.0 calls the continuous arrows connecting the BPMN elements in BPMN models, Sequence Flow. Sequence Flow exits one BPMN element and points at the next BPMN element to be processed. diff --git a/docs/src/developer-documentation/concepts/bpmn/service-tasks.md b/docs/src/developer-documentation/concepts/bpmn/service-tasks.md index 6e7c9d528..e690669df 100644 --- a/docs/src/developer-documentation/concepts/bpmn/service-tasks.md +++ b/docs/src/developer-documentation/concepts/bpmn/service-tasks.md @@ -1,3 +1,8 @@ +--- +title: Service Tasks +icon: creative +--- + ### Service Tasks You will primarily use [Service Tasks](https://docs.camunda.org/manual/7.20/reference/bpmn20/tasks/service-task/) diff --git a/docs/src/developer-documentation/concepts/bpmn/timer-intermediate-catching-events.md b/docs/src/developer-documentation/concepts/bpmn/timer-intermediate-catching-events.md index 6651f52cb..bd467ca2d 100644 --- a/docs/src/developer-documentation/concepts/bpmn/timer-intermediate-catching-events.md +++ b/docs/src/developer-documentation/concepts/bpmn/timer-intermediate-catching-events.md @@ -1,3 +1,8 @@ +--- +title: Timer Intermediate Catching Events +icon: creative +--- + ### Timer Intermediate Catching Events A [Timer Intermediate Catching Event](https://docs.camunda.org/manual/7.17/reference/bpmn20/events/timer-events/#timer-intermediate-catching-event) diff --git a/docs/src/developer-documentation/concepts/dsf/about-version-placeholders-and-urls.md b/docs/src/developer-documentation/concepts/dsf/about-version-placeholders-and-urls.md index 218bb9cea..0fddea685 100644 --- a/docs/src/developer-documentation/concepts/dsf/about-version-placeholders-and-urls.md +++ b/docs/src/developer-documentation/concepts/dsf/about-version-placeholders-and-urls.md @@ -1,3 +1,8 @@ +--- +title: About Versions, Placeholders und URLs +icon: creative +--- + ### About Versions, Placeholders and URLs #### Version Pattern diff --git a/docs/src/developer-documentation/concepts/dsf/bpmn-process-execution.md b/docs/src/developer-documentation/concepts/dsf/bpmn-process-execution.md index 18e331962..29c7c3b0d 100644 --- a/docs/src/developer-documentation/concepts/dsf/bpmn-process-execution.md +++ b/docs/src/developer-documentation/concepts/dsf/bpmn-process-execution.md @@ -1,3 +1,9 @@ +--- +title: BPMN Process Execution +icon: creative +--- + + ### BPMN Process Execution The BPMN process execution is the in-memory representation of a running BPMN process. BPMN processes have their diff --git a/docs/src/developer-documentation/concepts/dsf/bpmn-process-variables.md b/docs/src/developer-documentation/concepts/dsf/bpmn-process-variables.md index 3a63ae94d..802de45c0 100644 --- a/docs/src/developer-documentation/concepts/dsf/bpmn-process-variables.md +++ b/docs/src/developer-documentation/concepts/dsf/bpmn-process-variables.md @@ -1,3 +1,8 @@ +--- +title: BPMN Process Variables +icon: creative +--- + ### BPMN Process Variables BPMN process variables hold additional information which has to be available during BPMN process execution. diff --git a/docs/src/developer-documentation/concepts/dsf/certificates.md b/docs/src/developer-documentation/concepts/dsf/certificates.md index 28591b8a2..89cf5f958 100644 --- a/docs/src/developer-documentation/concepts/dsf/certificates.md +++ b/docs/src/developer-documentation/concepts/dsf/certificates.md @@ -1,3 +1,8 @@ +--- +title: Certificates +icon: creative +--- + ### Certificates There is a number of certificates that need to be generated in order for DSF instances to communicate with each other securely. diff --git a/docs/src/developer-documentation/concepts/dsf/draft-task-resources.md b/docs/src/developer-documentation/concepts/dsf/draft-task-resources.md index 6c412ddd5..66e38dff6 100644 --- a/docs/src/developer-documentation/concepts/dsf/draft-task-resources.md +++ b/docs/src/developer-documentation/concepts/dsf/draft-task-resources.md @@ -1,3 +1,8 @@ +--- +title: Draft Task Resources +icon: creative +--- + ### Draft Task Resources [Task](../../concepts/fhir/task.md) resources with status `draft` are used to create the DSF FHIR server's functionality diff --git a/docs/src/developer-documentation/concepts/dsf/environment-variables.md b/docs/src/developer-documentation/concepts/dsf/environment-variables.md index a5208920a..e6a28648a 100644 --- a/docs/src/developer-documentation/concepts/dsf/environment-variables.md +++ b/docs/src/developer-documentation/concepts/dsf/environment-variables.md @@ -1,3 +1,8 @@ +--- +title: Environment Variables +icon: creative +--- + ### Environment Variables Environment variables offer a way to make configuration data available at the start of a [BPMN process execution](../../concepts/dsf/bpmn-process-execution.md). diff --git a/docs/src/developer-documentation/concepts/dsf/examples-for-requester-and-recipient-elements.md b/docs/src/developer-documentation/concepts/dsf/examples-for-requester-and-recipient-elements.md index 51dbdff1b..8b145aa43 100644 --- a/docs/src/developer-documentation/concepts/dsf/examples-for-requester-and-recipient-elements.md +++ b/docs/src/developer-documentation/concepts/dsf/examples-for-requester-and-recipient-elements.md @@ -1,3 +1,8 @@ +--- +title: Examples for Requester and Recipient Elements +icon: creative +--- + ### Examples for Requester and Recipient Elements Below you will find a set of examples for each Coding used by `requester` and `recipient` elements from diff --git a/docs/src/developer-documentation/concepts/dsf/message-correlation.md b/docs/src/developer-documentation/concepts/dsf/message-correlation.md index 45610c5f2..51836aecf 100644 --- a/docs/src/developer-documentation/concepts/dsf/message-correlation.md +++ b/docs/src/developer-documentation/concepts/dsf/message-correlation.md @@ -1,3 +1,8 @@ +--- +title: Message Correlation +icon: creative +--- + ### Message Correlation In order for messages to be able to be sent back and forth between organizations with potentially multiple of the diff --git a/docs/src/developer-documentation/concepts/dsf/message-delegates.md b/docs/src/developer-documentation/concepts/dsf/message-delegates.md index 621f3d688..c1d21e01b 100644 --- a/docs/src/developer-documentation/concepts/dsf/message-delegates.md +++ b/docs/src/developer-documentation/concepts/dsf/message-delegates.md @@ -1,3 +1,8 @@ +--- +title: Message Delegates +icon: creative +--- + ### Message Delegates Message Delegates are the Java representation of the [Message Events](../../concepts/bpmn/messaging.md) in your BPMN model. diff --git a/docs/src/developer-documentation/concepts/dsf/organization-identifiers.md b/docs/src/developer-documentation/concepts/dsf/organization-identifiers.md index 6576882d6..f632ca7b8 100644 --- a/docs/src/developer-documentation/concepts/dsf/organization-identifiers.md +++ b/docs/src/developer-documentation/concepts/dsf/organization-identifiers.md @@ -1,3 +1,8 @@ +--- +title: Organization Identifiers +icon: creative +--- + ### Organization Identifiers DSF FHIR server instances always have something called an `organization identifer`. It uniquely identifies the organization the DSF FHIR server instance belongs to for its [Allow-List mechanism](https://dsf.dev/intro/info/allowList.html). diff --git a/docs/src/developer-documentation/concepts/dsf/process-api.md b/docs/src/developer-documentation/concepts/dsf/process-api.md index bc50946f4..a18dfdd0d 100644 --- a/docs/src/developer-documentation/concepts/dsf/process-api.md +++ b/docs/src/developer-documentation/concepts/dsf/process-api.md @@ -1,3 +1,8 @@ +--- +title: DSF Process API Package +icon: creative +--- + ### DSF Process API Package The [DSF Process API package](https://mvnrepository.com/artifact/dev.dsf/dsf-bpe-process-api-v1) consists of a set of utility classes designed to provide easy access to solutions for process plugin use cases. diff --git a/docs/src/developer-documentation/concepts/dsf/read-access-tag.md b/docs/src/developer-documentation/concepts/dsf/read-access-tag.md index 9cc75a2f7..0c4131790 100644 --- a/docs/src/developer-documentation/concepts/dsf/read-access-tag.md +++ b/docs/src/developer-documentation/concepts/dsf/read-access-tag.md @@ -1,3 +1,8 @@ +--- +title: Read Access Tag +icon: creative +--- + ### Read Access Tag Axiomatically, nobody is allowed to write FHIR resources (except [Task](../../concepts/fhir/task.md)) to the DSF FHIR server diff --git a/docs/src/developer-documentation/concepts/dsf/service-delegates.md b/docs/src/developer-documentation/concepts/dsf/service-delegates.md index 4eb2645fb..c393d1e13 100644 --- a/docs/src/developer-documentation/concepts/dsf/service-delegates.md +++ b/docs/src/developer-documentation/concepts/dsf/service-delegates.md @@ -1,3 +1,8 @@ +--- +title: Service Delegates +icon: creative +--- + ### Service Delegates Service Delegates are the Java representation of the [Service Tasks](../../concepts/bpmn/service-tasks.md) in your BPMN model. diff --git a/docs/src/developer-documentation/concepts/dsf/spring-integration.md b/docs/src/developer-documentation/concepts/dsf/spring-integration.md index 8aacf65ab..c49e9973f 100644 --- a/docs/src/developer-documentation/concepts/dsf/spring-integration.md +++ b/docs/src/developer-documentation/concepts/dsf/spring-integration.md @@ -1,3 +1,8 @@ +--- +title: Spring Integration +icon: creative +--- + ### Spring Integration Since the DSF also employs the use of the [Spring Framework](https://spring.io/projects/spring-framework) you will also diff --git a/docs/src/developer-documentation/concepts/dsf/the-process-plugin-definition.md b/docs/src/developer-documentation/concepts/dsf/the-process-plugin-definition.md index d3e05595a..ac7810b5e 100644 --- a/docs/src/developer-documentation/concepts/dsf/the-process-plugin-definition.md +++ b/docs/src/developer-documentation/concepts/dsf/the-process-plugin-definition.md @@ -1,3 +1,8 @@ +--- +title: The Process Plugin Definition +icon: creative +--- + ### The Process Plugin Definition In order for the DSF BPE server to load your plugin you need to provide it with the following information: diff --git a/docs/src/developer-documentation/concepts/fhir/activitydefinition.md b/docs/src/developer-documentation/concepts/fhir/activitydefinition.md index 1ebc78282..b51904c0a 100644 --- a/docs/src/developer-documentation/concepts/fhir/activitydefinition.md +++ b/docs/src/developer-documentation/concepts/fhir/activitydefinition.md @@ -1,3 +1,8 @@ +--- +title: ActivityDefinition +icon: creative +--- + ### ActivityDefinition [ActivityDefinitions](http://hl7.org/fhir/R4/activitydefinition.html) are used by the DSF to advertise which processes are diff --git a/docs/src/developer-documentation/concepts/fhir/codesystem.md b/docs/src/developer-documentation/concepts/fhir/codesystem.md index f9418e37f..6e2bcc8cc 100644 --- a/docs/src/developer-documentation/concepts/fhir/codesystem.md +++ b/docs/src/developer-documentation/concepts/fhir/codesystem.md @@ -1,3 +1,8 @@ +--- +title: CodeSystem +icon: creative +--- + ### CodeSystem [CodeSystems](https://www.hl7.org/fhir/R4/codesystem.html) usually represent a set of concepts which diff --git a/docs/src/developer-documentation/concepts/fhir/info.md b/docs/src/developer-documentation/concepts/fhir/introduction.md similarity index 91% rename from docs/src/developer-documentation/concepts/fhir/info.md rename to docs/src/developer-documentation/concepts/fhir/introduction.md index de33a5d62..16614fb74 100644 --- a/docs/src/developer-documentation/concepts/fhir/info.md +++ b/docs/src/developer-documentation/concepts/fhir/introduction.md @@ -1,4 +1,9 @@ -## FHIR +--- +title: Introduction +icon: creative +--- + +## FHIR Introduction The DSF uses a variety of [FHIR resources](https://dsf.dev/intro/info/basics.html#why-are-we-using-fhir-and-bpmn). The DSF uses XML as the format for FHIR resources. The most important resources for plugin development are [ActivityDefinitions](../../concepts/fhir/activitydefinition.md), [Tasks](../../concepts/fhir/task.md), diff --git a/docs/src/developer-documentation/concepts/fhir/task.md b/docs/src/developer-documentation/concepts/fhir/task.md index 484b46ba2..573cb9028 100644 --- a/docs/src/developer-documentation/concepts/fhir/task.md +++ b/docs/src/developer-documentation/concepts/fhir/task.md @@ -1,3 +1,8 @@ +--- +title: Task +icon: creative +--- + ### Task The [FHIR Task](https://www.hl7.org/fhir/R4/task.html) resource enables the DSF's distributed communication. diff --git a/docs/src/developer-documentation/concepts/fhir/valueset.md b/docs/src/developer-documentation/concepts/fhir/valueset.md index 807de4324..d53f19990 100644 --- a/docs/src/developer-documentation/concepts/fhir/valueset.md +++ b/docs/src/developer-documentation/concepts/fhir/valueset.md @@ -1,3 +1,8 @@ +--- +title: ValueSet +icon: creative +--- + ### ValueSet [ValueSets](https://www.hl7.org/fhir/R4/valueset.html) bind codes from [CodeSystems](../../concepts/fhir/codesystem.md) to coded elements like diff --git a/docs/src/developer-documentation/guides/accessing-bpmn-process-variables.md b/docs/src/developer-documentation/guides/accessing-bpmn-process-variables.md index 0177613ee..1a4410686 100644 --- a/docs/src/developer-documentation/guides/accessing-bpmn-process-variables.md +++ b/docs/src/developer-documentation/guides/accessing-bpmn-process-variables.md @@ -1,3 +1,8 @@ +--- +title: Accessing BPMN Process Variables +icon: creative +--- + ### Accessing BPMN Process Variables After creating a [Service Delegate](../concepts/dsf/service-delegates.md) or [Message Delegate](../concepts/dsf/message-delegates.md), you might want to diff --git a/docs/src/developer-documentation/guides/accessing-task-resources-during-execution.md b/docs/src/developer-documentation/guides/accessing-task-resources-during-execution.md index 1b1bf4ce6..b40b2c31a 100644 --- a/docs/src/developer-documentation/guides/accessing-task-resources-during-execution.md +++ b/docs/src/developer-documentation/guides/accessing-task-resources-during-execution.md @@ -1,3 +1,8 @@ +--- +title: Accessing Task Resources During Execution +icon: creative +--- + ### Accessing Task Resources During Execution If you want access to the [Task](../concepts/fhir/task.md) resources in your [Service](../concepts/dsf/service-delegates.md) / [Message](../concepts/dsf/message-delegates.md) Delegates, the `Variables` class will diff --git a/docs/src/developer-documentation/guides/adding-task-input-parameters-to-task-profiles.md b/docs/src/developer-documentation/guides/adding-task-input-parameters-to-task-profiles.md index 8c64cc47b..c3bbf0a21 100644 --- a/docs/src/developer-documentation/guides/adding-task-input-parameters-to-task-profiles.md +++ b/docs/src/developer-documentation/guides/adding-task-input-parameters-to-task-profiles.md @@ -1,3 +1,8 @@ +--- +title: Adding Task Input Parameters to Task Profiles +icon: creative +--- + ### Adding Task Input Parameters to Task Profiles When adding a new [Input Parameter](../concepts/fhir/task.md#task-input-parameters) to a [Task](../concepts/fhir/task.md) diff --git a/docs/src/developer-documentation/guides/configuring-the-read-access-tag.md b/docs/src/developer-documentation/guides/configuring-the-read-access-tag.md index f8a6dfb59..320e12b31 100644 --- a/docs/src/developer-documentation/guides/configuring-the-read-access-tag.md +++ b/docs/src/developer-documentation/guides/configuring-the-read-access-tag.md @@ -1,3 +1,8 @@ +--- +title: Configuring the Read Access Tag +icon: creative +--- + ### Configuring the Read Access Tag To start off, you want to take a look at the [CodeSystem](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/CodeSystem/dsf-read-access-tag-1.0.0.xml) defined for the [Read Access Tag](../concepts/dsf/read-access-tag.md) diff --git a/docs/src/developer-documentation/guides/creating-an-activity-definition.md b/docs/src/developer-documentation/guides/creating-an-activity-definition.md index c0e2295a9..be8a6ed68 100644 --- a/docs/src/developer-documentation/guides/creating-an-activity-definition.md +++ b/docs/src/developer-documentation/guides/creating-an-activity-definition.md @@ -1,3 +1,8 @@ +--- +title: Creating an ActivityDefinition +icon: creative +--- + ### Creating an ActivityDefinition This guide will teach you how to create an ActivityDefinition based on the [dsf-activity-definition](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-activity-definition-1.0.0.xml) profile for your process plugin. diff --git a/docs/src/developer-documentation/guides/creating-codesystems-for-dsf-processes.md b/docs/src/developer-documentation/guides/creating-codesystems-for-dsf-processes.md index 5c65e3078..20b240875 100644 --- a/docs/src/developer-documentation/guides/creating-codesystems-for-dsf-processes.md +++ b/docs/src/developer-documentation/guides/creating-codesystems-for-dsf-processes.md @@ -1,3 +1,8 @@ +--- +title: Creating CodeSystems for DSF Processes +icon: creative +--- + ### Creating CodeSystems for DSF Processes You might find yourself in a situation where you need to create a [CodeSystem](../concepts/fhir/codesystem.md). diff --git a/docs/src/developer-documentation/guides/creating-task-resources-based-on-a-definition.md b/docs/src/developer-documentation/guides/creating-task-resources-based-on-a-definition.md index d6da6bff4..16ccbddd1 100644 --- a/docs/src/developer-documentation/guides/creating-task-resources-based-on-a-definition.md +++ b/docs/src/developer-documentation/guides/creating-task-resources-based-on-a-definition.md @@ -1,3 +1,8 @@ +--- +title: Creating Task Resources Based on a Definition +icon: creative +--- + ### Creating Task Resources Based on a Definition This short guide should help you understand how you can create [Task](../concepts/fhir/task.md) @@ -24,7 +29,7 @@ element, we are done with this chain. In forge, you should now be able to open the `StructureDefinition` folder and select the `task-start-dic-process.xml` profile. It should look something like this: -![Forge overview](../../exercises/figures/forge_overview.png) +![Forge overview](/photos/developer-documentation/forge_overview.png) #### 3rd Step: Building the Task Resource We will now go through each element one by one and include it into our [Task](../concepts/fhir/task.md) @@ -83,7 +88,7 @@ By now your [Task](../concepts/fhir/task.md) resources should look something lik Let us look at a more complex element like the `requester` element: -![Forge requester view](../../exercises/figures/forge_requester_view.png) +![Forge requester view](/photos/developer-documentation/forge_requester_view.png) We will start the same way we started with primitive elements, by adding the `requester` element: ```xml @@ -180,7 +185,7 @@ resource should look something like this: [Slicings](https://www.hl7.org/fhir/R4/profiling.html#slicing) are a bit different from regular elements. Let us look at the slice `message-name`: -![Forge slice message name](../../exercises/figures/forge_slice_message_name.png) +![Forge slice message name](/photos/developer-documentation/forge_slice_message_name.png) If we were to continue including slices to the [Task](../concepts/fhir/task.md) resource like we did so far, we would add a `message-name` element to our XML like this: diff --git a/docs/src/developer-documentation/guides/creating-valuesets-for-dsf-processes.md b/docs/src/developer-documentation/guides/creating-valuesets-for-dsf-processes.md index c4ca9e21a..b22e0e018 100644 --- a/docs/src/developer-documentation/guides/creating-valuesets-for-dsf-processes.md +++ b/docs/src/developer-documentation/guides/creating-valuesets-for-dsf-processes.md @@ -1,3 +1,8 @@ +--- +title: Creating ValueSets for DSF Processes +icon: creative +--- + ### Creating ValueSets for DSF Processes You might find yourself in the situation where you need to create a [ValueSet](../concepts/fhir/valueset.md). diff --git a/docs/src/developer-documentation/guides/managing-mutiple-incoming-messages-and-missing-messages.md b/docs/src/developer-documentation/guides/managing-mutiple-incoming-messages-and-missing-messages.md index cdc5de09c..6a6c089ab 100644 --- a/docs/src/developer-documentation/guides/managing-mutiple-incoming-messages-and-missing-messages.md +++ b/docs/src/developer-documentation/guides/managing-mutiple-incoming-messages-and-missing-messages.md @@ -1,3 +1,8 @@ +--- +title: Managing Multiple Incoming Messages and Missing Messages +icon: creative +--- + ### Managing Multiple Incoming Messages and Missing Messages If an already running process instance is waiting for a message from another organization, the corresponding FHIR [Task](../concepts/fhir/task.md) may never arrive. @@ -13,7 +18,7 @@ The following BPMN collaboration diagram shows how the process at the first orga or missing messages: <picture> - <source media="(prefers-color-scheme: dark)" srcset="../../exercises/figures/exercise5_event_based_gateway_inverted.svg"> - <source media="(prefers-color-scheme: light)" srcset="../../exercises/figures/exercise5_event_based_gateway.svg"> - <img alt="BPMN collaboration diagram with an Event Based Gateway" src="../../exercises/figures/exercise5_event_based_gateway.svg"> + <source media="(prefers-color-scheme: dark)" srcset="/photos/developer-documentation/exercise5_event_based_gateway_inverted.svg"> + <source media="(prefers-color-scheme: light)" srcset="/photos/developer-documentation/exercise5_event_based_gateway.svg"> + <img alt="BPMN collaboration diagram with an Event Based Gateway" src="/photos/developer-documentation/exercise5_event_based_gateway.svg"> </picture> diff --git a/docs/src/developer-documentation/guides/setting-targets-for-message-events.md b/docs/src/developer-documentation/guides/setting-targets-for-message-events.md index 6cb427fbd..7b6490a42 100644 --- a/docs/src/developer-documentation/guides/setting-targets-for-message-events.md +++ b/docs/src/developer-documentation/guides/setting-targets-for-message-events.md @@ -1,3 +1,8 @@ +--- +title: Setting Targets for Message Events +icon: creative +--- + ### Setting Targets for Message Events Setting a target for a message event requires a `Target` object. To create one, you require a target's organization identifier, endpoint identifier and endpoint address. diff --git a/docs/src/developer-documentation/guides/starting-a-process-via-task-resources.md b/docs/src/developer-documentation/guides/starting-a-process-via-task-resources.md index ec6275622..6bcd9db67 100644 --- a/docs/src/developer-documentation/guides/starting-a-process-via-task-resources.md +++ b/docs/src/developer-documentation/guides/starting-a-process-via-task-resources.md @@ -1,3 +1,8 @@ +--- +title: Starting a Process via Task Resources +icon: creative +--- + ### Starting a Process via Task Resources To start a BPMN process, you need to create new a [Task](../concepts/fhir/task.md) resource in the DSF FHIR server From 34f8849bb07fb823166d8538072aadf6cc9547f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20B=C3=B6hringer?= <jan.boehringer@hs-heilbronn.de> Date: Fri, 12 Apr 2024 11:19:23 +0200 Subject: [PATCH 03/14] Fixed newlines from tutorial .md files rendering ugly. Moved explenation of certificates to tutorial because it was too specific --- docs/src/.vuepress/theme.ts | 2 +- .../concepts/bpmn/conditions.md | 11 +-- .../concepts/bpmn/gateways.md | 15 +-- .../concepts/bpmn/intro.md | 11 +-- .../concepts/bpmn/messaging.md | 29 ++---- .../concepts/bpmn/sequence-flow.md | 3 +- .../concepts/bpmn/service-tasks.md | 6 +- .../timer-intermediate-catching-events.md | 6 +- .../about-version-placeholders-and-urls.md | 33 ++----- .../concepts/dsf/bpmn-process-execution.md | 9 +- .../concepts/dsf/bpmn-process-variables.md | 6 +- .../concepts/dsf/certificates.md | 24 ----- .../concepts/dsf/draft-task-resources.md | 16 +--- .../concepts/dsf/environment-variables.md | 13 +-- ...es-for-requester-and-recipient-elements.md | 4 +- .../concepts/dsf/message-correlation.md | 12 +-- .../concepts/dsf/message-delegates.md | 20 +--- .../concepts/dsf/organization-identifiers.md | 14 +-- .../concepts/dsf/process-api.md | 6 +- .../concepts/dsf/read-access-tag.md | 15 +-- .../concepts/dsf/service-delegates.md | 11 +-- .../concepts/dsf/spring-integration.md | 10 +- .../dsf/the-process-plugin-definition.md | 6 +- .../concepts/fhir/activitydefinition.md | 17 +--- .../concepts/fhir/codesystem.md | 4 +- .../concepts/fhir/introduction.md | 6 +- .../concepts/fhir/task.md | 12 +-- .../concepts/fhir/valueset.md | 6 +- .../accessing-bpmn-process-variables.md | 8 +- ...cessing-task-resources-during-execution.md | 22 +---- ...-task-input-parameters-to-task-profiles.md | 61 +++--------- .../guides/configuring-the-read-access-tag.md | 35 ++----- .../guides/creating-an-activity-definition.md | 94 +++++-------------- .../creating-codesystems-for-dsf-processes.md | 11 +-- ...ng-task-resources-based-on-a-definition.md | 66 +++---------- .../creating-valuesets-for-dsf-processes.md | 19 +--- ...-incoming-messages-and-missing-messages.md | 10 +- .../setting-targets-for-message-events.md | 11 +-- .../starting-a-process-via-task-resources.md | 42 ++------- 39 files changed, 139 insertions(+), 567 deletions(-) delete mode 100644 docs/src/developer-documentation/concepts/dsf/certificates.md diff --git a/docs/src/.vuepress/theme.ts b/docs/src/.vuepress/theme.ts index 3f5eece31..7fcbca535 100644 --- a/docs/src/.vuepress/theme.ts +++ b/docs/src/.vuepress/theme.ts @@ -797,7 +797,7 @@ export default hopeTheme({ icon: "info", prefix: "dsf/", link: "dsf/", - children: ["about-version-placeholders-and-urls.md", "bpmn-process-execution.md", "bpmn-process-variables.md", "certificates.md", "draft-task-resources.md", "environment-variables.md", "examples-for-requester-and-recipient-elements.md", "message-correlation.md", "message-delegates.md", "organization-identifiers.md", "process-api.md", "read-access-tag.md", "service-delegates.md", "spring-integration.md", "the-process-plugin-definition.md"], + children: ["about-version-placeholders-and-urls.md", "bpmn-process-execution.md", "bpmn-process-variables.md", "draft-task-resources.md", "environment-variables.md", "examples-for-requester-and-recipient-elements.md", "message-correlation.md", "message-delegates.md", "organization-identifiers.md", "process-api.md", "read-access-tag.md", "service-delegates.md", "spring-integration.md", "the-process-plugin-definition.md"], }] }, { diff --git a/docs/src/developer-documentation/concepts/bpmn/conditions.md b/docs/src/developer-documentation/concepts/bpmn/conditions.md index 631c2817d..5aa85f5e2 100644 --- a/docs/src/developer-documentation/concepts/bpmn/conditions.md +++ b/docs/src/developer-documentation/concepts/bpmn/conditions.md @@ -5,13 +5,4 @@ icon: creative ### Conditions -[Conditions](https://docs.camunda.org/manual/7.20/user-guide/process-engine/expression-language/#conditions) -allow you to change the behaviour of BPMN processes during execution. There are two ways you -are able to add decision logic to Conditions. The [Camunda Modeler](https://camunda.com/download/modeler/) refers to them as `Type`. You can find them in the ``Condition`` tab of -certain BPMN elements. The first one is `Script`. This allows you to add arbitrary complexity -to your decisions logic and is rarely used for process plugins. The more common Type is `Expression`. -Expressions have the following syntax: `${expression}`. For this tutorial, _expression_ will -use a boolean condition like `var == true`. You can learn more advanced features of Expressions [here](https://docs.camunda.org/manual/7.20/user-guide/process-engine/expression-language/). -For this to work during BPMN process execution, the variable you want to use for the boolean -condition must be available in the BPMN process variables before [Sequence Flow](../../concepts/bpmn/sequence-flow.md) -reaches the evaluation of the expression. \ No newline at end of file +[Conditions](https://docs.camunda.org/manual/7.20/user-guide/process-engine/expression-language/#conditions) allow you to change the behaviour of BPMN processes during execution. There are two ways you are able to add decision logic to Conditions. The [Camunda Modeler](https://camunda.com/download/modeler/) refers to them as `Type`. You can find them in the ``Condition`` tab of certain BPMN elements. The first one is `Script`. This allows you to add arbitrary complexity to your decisions logic and is rarely used for process plugins. The more common Type is `Expression`. Expressions have the following syntax: `${expression}`. An example of a simple expression would be a boolean condition like `var == true`. For this to work during BPMN process execution, the variable you want to use for the boolean condition must be available in the BPMN process variables before [Sequence Flow](../../concepts/bpmn/sequence-flow.md) reaches the evaluation of the expression. You can learn more advanced features of Expressions [here](https://docs.camunda.org/manual/7.20/user-guide/process-engine/expression-language/). \ No newline at end of file diff --git a/docs/src/developer-documentation/concepts/bpmn/gateways.md b/docs/src/developer-documentation/concepts/bpmn/gateways.md index 8c9834215..083fbbb26 100644 --- a/docs/src/developer-documentation/concepts/bpmn/gateways.md +++ b/docs/src/developer-documentation/concepts/bpmn/gateways.md @@ -5,21 +5,12 @@ icon: creative ### Gateways -[Gateways](https://docs.camunda.org/manual/7.20/reference/bpmn20/gateways/) allow you to control the [Sequence Flow](../../concepts/bpmn/sequence-flow.md). Different -types of gateways will be useful for different scenarios. +[Gateways](https://docs.camunda.org/manual/7.20/reference/bpmn20/gateways/) allow you to control the [Sequence Flow](../../concepts/bpmn/sequence-flow.md). Different types of gateways will be useful for different scenarios. #### Exclusive Gateways -[Exclusive Gateways](https://docs.camunda.org/manual/7.20/reference/bpmn20/gateways/exclusive-gateway/) -allow you to decide which [Sequence Flow](../../concepts/bpmn/sequence-flow.md) should be followed based on [conditions](https://docs.camunda.org/manual/7.20/user-guide/process-engine/expression-language/#conditions). -[Conditions](https://docs.camunda.org/manual/7.20/user-guide/process-engine/expression-language/#conditions) are not part of the -[Exclusive Gateways](https://docs.camunda.org/manual/7.20/reference/bpmn20/gateways/exclusive-gateway/) themselves. You set them -through the sequence Flow Exiting the [Exclusive Gateway](https://docs.camunda.org/manual/7.20/reference/bpmn20/gateways/exclusive-gateway/). -In the [Camunda Modeler](https://camunda.com/download/modeler/), you can add conditions to [Sequence Flow](../../concepts/bpmn/sequence-flow.md) by selecting -a [Sequence Flow](../../concepts/bpmn/sequence-flow.md) and opening the `Condition` tab. You can find more information on how to -use Conditions [here](../../concepts/bpmn/conditions.md). +[Exclusive Gateways](https://docs.camunda.org/manual/7.20/reference/bpmn20/gateways/exclusive-gateway/) allow you to decide which [Sequence Flow](../../concepts/bpmn/sequence-flow.md) should be followed based on [conditions](https://docs.camunda.org/manual/7.20/user-guide/process-engine/expression-language/#conditions). [Conditions](https://docs.camunda.org/manual/7.20/user-guide/process-engine/expression-language/#conditions) are not part of the [Exclusive Gateways](https://docs.camunda.org/manual/7.20/reference/bpmn20/gateways/exclusive-gateway/) themselves. You set them through the sequence Flow Exiting the [Exclusive Gateway](https://docs.camunda.org/manual/7.20/reference/bpmn20/gateways/exclusive-gateway/). In the [Camunda Modeler](https://camunda.com/download/modeler/), you can add conditions to [Sequence Flow](../../concepts/bpmn/sequence-flow.md) by selecting a [Sequence Flow](../../concepts/bpmn/sequence-flow.md) and opening the `Condition` tab. You can find more information on how to use Conditions [here](../../concepts/bpmn/conditions.md). #### Event-based Gateway -The [Event-based Gateway](https://docs.camunda.org/manual/7.20/reference/bpmn20/gateways/event-based-gateway/) -allows you model scenarios where you are expecting one out of a number of events to occur. \ No newline at end of file +The [Event-based Gateway](https://docs.camunda.org/manual/7.20/reference/bpmn20/gateways/event-based-gateway/) allows you model scenarios where you are expecting one out of a number of events to occur. \ No newline at end of file diff --git a/docs/src/developer-documentation/concepts/bpmn/intro.md b/docs/src/developer-documentation/concepts/bpmn/intro.md index de7f59511..2922e2b4b 100644 --- a/docs/src/developer-documentation/concepts/bpmn/intro.md +++ b/docs/src/developer-documentation/concepts/bpmn/intro.md @@ -3,13 +3,4 @@ title: Introduction icon: creative --- -The DSF uses BPMN 2.0 to model processes. Specifically, the [Camunda 7](https://docs.camunda.org/manual/7.20/) dialect from the [Camunda Modeler](https://camunda.com/de/download/modeler/). -Modeling processes for the DSF requires this modeler or any other modeler which is able to produce the correct Camunda dialect. - -### Common BPMN Components -- Sequence Flow -- Service Tasks -- User Tasks -- Message Events -- Timer Events -- \ No newline at end of file +The DSF uses BPMN 2.0 to model processes. Specifically, the [Camunda 7](https://docs.camunda.org/manual/7.20/) dialect from the [Camunda Modeler](https://camunda.com/de/download/modeler/). Modeling processes for the DSF requires this modeler or any other modeler which is able to produce the correct Camunda dialect. \ No newline at end of file diff --git a/docs/src/developer-documentation/concepts/bpmn/messaging.md b/docs/src/developer-documentation/concepts/bpmn/messaging.md index a7bf57612..a8bec3071 100644 --- a/docs/src/developer-documentation/concepts/bpmn/messaging.md +++ b/docs/src/developer-documentation/concepts/bpmn/messaging.md @@ -6,34 +6,19 @@ icon: creative ### Messaging -In order to enable communication with other lanes, pools or even entirely separate processes you need to be able -to exchange information. In BPMN, you can use [Message Events](https://docs.camunda.org/manual/7.20/reference/bpmn20/events/message-events/) -to model this information exchange. Modeling communication with [Message Events](https://docs.camunda.org/manual/7.20/reference/bpmn20/events/message-events/) in the same diagram -uses Message Flow. Message Flow is typically represented by a dashed line arrow between BPMN elements with a black (send) or white (receive) envelope icon. -The following BPMN collaboration diagram shows message exchange between two processes. - -<picture> - <source media="(prefers-color-scheme: dark)" srcset="/photos/developer-documentation/exercise3_message_flow_inverted.svg"> - <source media="(prefers-color-scheme: light)" srcset="/photos/developer-documentation/exercise3_message_flow.svg"> - <img alt="BPMN collaboration diagram with two processes using message flow to exchange information between two organizations" src="/photos/developer-documentation/exercise3_message_flow.svg"> -</picture> +In order to enable communication with other lanes, pools or even entirely separate processes you need to be able to exchange information. In BPMN, you can use [Message Events](https://docs.camunda.org/manual/7.20/reference/bpmn20/events/message-events/) to model this information exchange. Modeling communication with [Message Events](https://docs.camunda.org/manual/7.20/reference/bpmn20/events/message-events/) in the same diagram uses Message Flow. Message Flow is typically represented by a dashed line arrow between BPMN elements with a black (send) or white (receive) envelope icon. The following BPMN collaboration diagram shows message exchange between two processes. + +![BPMN collaboration diagram with two processes using message flow to exchange information between two organizations](/photos/developer-documentation/exercise3_message_flow.svg) #### Message Start Event -[Message Start Events](https://docs.camunda.org/manual/7.20/reference/bpmn20/events/message-events/#message-start-event) -allow a BPMN process to be started by an incoming message. In the DSF, all BPMN processes are started via messages. Therefore, -you will have to include a [Message Start Event](https://docs.camunda.org/manual/7.20/reference/bpmn20/events/message-events/#message-start-event) at -the beginning of all of your BPMN models. +[Message Start Events](https://docs.camunda.org/manual/7.20/reference/bpmn20/events/message-events/#message-start-event) allow a BPMN process to be started by an incoming message. In the DSF, all BPMN processes are started via messages. Therefore, you will have to include a [Message Start Event](https://docs.camunda.org/manual/7.20/reference/bpmn20/events/message-events/#message-start-event) at the beginning of all of your BPMN models. #### Message Intermediate Throwing Event -[Message Intermediate Throwing Events](https://docs.camunda.org/manual/7.20/reference/bpmn20/events/message-events/#message-intermediate-throwing-event) -are used to send messages during process execution. +[Message Intermediate Throwing Events](https://docs.camunda.org/manual/7.20/reference/bpmn20/events/message-events/#message-intermediate-throwing-event) are used to send messages during process execution. #### Message Intermediate Catching Event -[Message Intermediate Catching Events](https://docs.camunda.org/manual/7.20/reference/bpmn20/events/message-events/#message-intermediate-catching-event) serve as -the counterpart to [Message Intermediate Throwing Events](messaging.md#message-intermediate-throwing-event). -Use them whenever you expect to receive a message from another process or organization during execution. +[Message Intermediate Catching Events](https://docs.camunda.org/manual/7.20/reference/bpmn20/events/message-events/#message-intermediate-catching-event) serve as the counterpart to [Message Intermediate Throwing Events](messaging.md#message-intermediate-throwing-event). Use them whenever you expect to receive a message from another process or organization during execution. #### Message End Event -The [Message End Event](https://docs.camunda.org/manual/7.20/reference/bpmn20/events/message-events/#message-end-event) will -stop the execution of a BPMN process and finish by sending a message. \ No newline at end of file +The [Message End Event](https://docs.camunda.org/manual/7.20/reference/bpmn20/events/message-events/#message-end-event) will stop the execution of a BPMN process and finish by sending a message. \ No newline at end of file diff --git a/docs/src/developer-documentation/concepts/bpmn/sequence-flow.md b/docs/src/developer-documentation/concepts/bpmn/sequence-flow.md index 715e8de49..3650cc635 100644 --- a/docs/src/developer-documentation/concepts/bpmn/sequence-flow.md +++ b/docs/src/developer-documentation/concepts/bpmn/sequence-flow.md @@ -4,5 +4,4 @@ icon: creative --- ### Sequence Flow -BPMN 2.0 calls the continuous arrows connecting the BPMN elements in BPMN models, Sequence Flow. -Sequence Flow exits one BPMN element and points at the next BPMN element to be processed. +BPMN 2.0 calls the continuous arrows connecting the BPMN elements in BPMN models, Sequence Flow. Sequence Flow exits one BPMN element and points at the next BPMN element to be processed. diff --git a/docs/src/developer-documentation/concepts/bpmn/service-tasks.md b/docs/src/developer-documentation/concepts/bpmn/service-tasks.md index e690669df..50849d488 100644 --- a/docs/src/developer-documentation/concepts/bpmn/service-tasks.md +++ b/docs/src/developer-documentation/concepts/bpmn/service-tasks.md @@ -5,8 +5,4 @@ icon: creative ### Service Tasks -You will primarily use [Service Tasks](https://docs.camunda.org/manual/7.20/reference/bpmn20/tasks/service-task/) -when creating BPMN models. They are different from regular BPMN Tasks in that they offer the ability to -link an implementation to the [Service Task](https://docs.camunda.org/manual/7.20/reference/bpmn20/tasks/service-task/) -which can be called and executed by a BPMN engine. The BPE (Business Process Engine) server of the DSF leverages -this engine to execute your BPMN processes. \ No newline at end of file +One of the most common types of BPMN Tasks used for modeling DSF processes is the [Service Task](https://docs.camunda.org/manual/7.20/reference/bpmn20/tasks/service-task/). They are different from regular BPMN Tasks in that they offer the ability to link an implementation to the [Service Task](https://docs.camunda.org/manual/7.20/reference/bpmn20/tasks/service-task/) which can be called and executed by a BPMN engine. The BPE (Business Process Engine) server of the DSF leverages this engine to execute your BPMN processes. \ No newline at end of file diff --git a/docs/src/developer-documentation/concepts/bpmn/timer-intermediate-catching-events.md b/docs/src/developer-documentation/concepts/bpmn/timer-intermediate-catching-events.md index bd467ca2d..c8e8b8ffc 100644 --- a/docs/src/developer-documentation/concepts/bpmn/timer-intermediate-catching-events.md +++ b/docs/src/developer-documentation/concepts/bpmn/timer-intermediate-catching-events.md @@ -5,8 +5,4 @@ icon: creative ### Timer Intermediate Catching Events -A [Timer Intermediate Catching Event](https://docs.camunda.org/manual/7.17/reference/bpmn20/events/timer-events/#timer-intermediate-catching-event) -allows you model stopwatch behavior. A timer is started once the BPMN execution arrives at the event. -The duration until the timer runs out is specified using the [ISO 8601 Durations](http://en.wikipedia.org/wiki/ISO_8601#Durations) format. -Examples can be found [here](https://docs.camunda.org/manual/7.17/reference/bpmn20/events/timer-events/#time-duration). After running out, the BPMN process executes the [Sequence Flow](../../concepts/bpmn/sequence-flow.md) following -the [Timer Intermediate Catching Event](https://docs.camunda.org/manual/7.17/reference/bpmn20/events/timer-events/#timer-intermediate-catching-event). \ No newline at end of file +A [Timer Intermediate Catching Event](https://docs.camunda.org/manual/7.17/reference/bpmn20/events/timer-events/#timer-intermediate-catching-event) allows you to model stopwatch behavior. A timer is started once the BPMN execution arrives at the event. The duration until the timer runs out is specified using the [ISO 8601 Durations](http://en.wikipedia.org/wiki/ISO_8601#Durations) format. Examples can be found [here](https://docs.camunda.org/manual/7.17/reference/bpmn20/events/timer-events/#time-duration). After running out, the BPMN process executes the [Sequence Flow](../../concepts/bpmn/sequence-flow.md) following the [Timer Intermediate Catching Event](https://docs.camunda.org/manual/7.17/reference/bpmn20/events/timer-events/#timer-intermediate-catching-event). \ No newline at end of file diff --git a/docs/src/developer-documentation/concepts/dsf/about-version-placeholders-and-urls.md b/docs/src/developer-documentation/concepts/dsf/about-version-placeholders-and-urls.md index 0fddea685..8ca7c542d 100644 --- a/docs/src/developer-documentation/concepts/dsf/about-version-placeholders-and-urls.md +++ b/docs/src/developer-documentation/concepts/dsf/about-version-placeholders-and-urls.md @@ -12,20 +12,11 @@ Process plugin versions have to obey the pattern: \d+\.\d+\.\d+\.\d+ Example: 1.0.1.2 ``` -The first two numbers (`1.0`) are used in FHIR resources and signal changes which break compatibility with previous -process versions. For example, altering FHIR resources usually results in a breaking change. The latter two (`1.2`) signal changes which do not break compatibility with previous process versions. Specifically, -the 4th number is reserved for bug-fixes and the 3rd number includes all other non-breaking changes. +The first two numbers (`1.0`) are used in FHIR resources and signal changes which break compatibility with previous process versions. For example, altering FHIR resources usually results in a breaking change. The latter two (`1.2`) signal changes which do not break compatibility with previous process versions. Specifically, the 4th number is reserved for bug-fixes and the 3rd number includes all other non-breaking changes. #### Placeholders -To avoid the need to specify the version and release date for each [ActivityDefinition](../../concepts/fhir/activitydefinition.md), [CodeSystem](../../concepts/fhir/codesystem.md), -[Task](../../concepts/fhir/task.md) profile and [ValueSet](../../concepts/fhir/valueset.md) resource, -the placeholders `#{version}` and `#{date}` can be used when creating FHIR resources or even in BPMN models. -They are replaced with the values returned by the methods `ProcessPluginDefinition#getResourceVersion` -and `ProcessPluginDefinition#getReleaseDate` respectively during deployment of a process plugin by the DSF BPE server. -There is also a placeholder for the organization the DSF instance is running in: `#{organization}`. You would typically use -this placeholder in [Draft Task Resources](draft-task-resources.md) but like the other placeholders, it can be used anywhere -as long as the file gets loaded by the [BPE](https://dsf.dev/intro/info/architecture.html#business-process-engine-bpe). +To avoid the need to specify the version and release date, the placeholders `#{version}` and `#{date}` can be used when creating FHIR resources or even in BPMN models. They are replaced with the values returned by the methods `ProcessPluginDefinition#getResourceVersion` and `ProcessPluginDefinition#getReleaseDate` respectively during deployment of a process plugin by the DSF BPE server. There is also a placeholder for the organization the DSF instance is running in: `#{organization}`. You would typically use this placeholder in [Draft Task Resources](draft-task-resources.md) but like the other placeholders, it can be used anywhere as long as the file gets loaded by the [BPE](https://dsf.dev/intro/info/architecture.html#business-process-engine-bpe). #### URLs @@ -33,26 +24,14 @@ BPMN models have an ID we call process definition key. The BPMN process definiti ``` ^[-a-zA-Z0-9]+_[-a-zA-Z0-9]+$ Example: domainorg_processKey ``` -In addition, the BPMN model needs to specify a version. You should be using the ``#{version}`` [placeholder](../../concepts/dsf/about-version-placeholders-and-urls.md#placeholders) -for this as well. The DSF will also reference this process in URL form in FHIR resources: +In addition, the BPMN model needs to specify a version. You should be using the ``#{version}`` [placeholder](../../concepts/dsf/about-version-placeholders-and-urls.md#placeholders) for this as well. The DSF will also reference this process in URL form in FHIR resources: ``` http://domain.org/bpe/Process/processKey|1.0 ``` -As you can see, the version in the URL ``|1.0`` only uses the resource version and omits the code base version. -As mentioned in [Version Pattern](about-version-placeholders-and-urls.md#version-pattern), this means that only changes to the first two -version numbers are significant to signal compatibility when communicating with other process plugin instances. -The process definition key and URL are also related to each other. The DSF will try to match BPMN models -to FHIR resources by transforming the URL into a process definition key. That is why it is important you obey -the pattern above. - -You will use the above URL as your instantiatesCanonical value for [Task](../../concepts/fhir/task.md) profile definitions as well as references -to [Task](../../concepts/fhir/task.md) profiles in other resources. -You will also use it as the URL value for your [ActivityDefinitions](../../concepts/fhir/activitydefinition.md). In this case though, you -have to split up the URL into two parts. You will separate the version (``|1.0``) from the URL and use it as a value for the -`ActivityDefinition.version` element. Since it refers to the plugin's resource version, you should also use the `#{version}` -[placeholder](about-version-placeholders-and-urls.md#placeholders) here instead. Going by the example from above, you will be left with a URL that looks -like this: +As you can see, the version in the URL ``|1.0`` only uses the resource version and omits the code base version. As mentioned in [Version Pattern](about-version-placeholders-and-urls.md#version-pattern), this means that only changes to the first two version numbers are significant to signal compatibility when communicating with other process plugin instances. The process definition key and URL are also related to each other. The DSF will try to match BPMN models to FHIR resources by transforming the URL into a process definition key. That is why it is important you obey the pattern above. + +You will use the above URL as your instantiatesCanonical value for [Task](../../concepts/fhir/task.md) profile definitions as well as references to [Task](../../concepts/fhir/task.md) profiles in other resources. You will also use it as the URL value for your [ActivityDefinitions](../../concepts/fhir/activitydefinition.md). In this case though, you have to split up the URL into two parts. You will separate the version (``|1.0``) from the URL and use it as a value for the `ActivityDefinition.version` element. Since it refers to the plugin's resource version, you should also use the `#{version}` [placeholder](about-version-placeholders-and-urls.md#placeholders) here instead. Going by the example from above, you will be left with a URL that looks like this: ``` http://domain.org/bpe/Process/processKey ``` diff --git a/docs/src/developer-documentation/concepts/dsf/bpmn-process-execution.md b/docs/src/developer-documentation/concepts/dsf/bpmn-process-execution.md index 29c7c3b0d..e9aea7a67 100644 --- a/docs/src/developer-documentation/concepts/dsf/bpmn-process-execution.md +++ b/docs/src/developer-documentation/concepts/dsf/bpmn-process-execution.md @@ -6,11 +6,4 @@ icon: creative ### BPMN Process Execution -The BPMN process execution is the in-memory representation of a running BPMN process. BPMN processes have their -executions structured as a tree hierarchy. Each BPMN process -starts with the [process instance](https://docs.camunda.org/manual/7.20/user-guide/process-engine/process-engine-concepts/#process-instances) -as its root level execution. If, for example, this root execution reaches a parallel gateway with two paths, it would spawn two child executions -under itself for them to process all tasks along their paths on their own. -Executions can access all the BPMN elements from the BPMN model as well as the [BPMN process variables](../../concepts/dsf/bpmn-process-variables.md). -You have access to this representation in your Java code when overriding certain methods in [Service](../../concepts/dsf/service-delegates.md) / [Message](../../concepts/dsf/message-delegates.md) Delegates -like `doExecute` or `getAdditionalInputParameters` through the `execution` parameter. \ No newline at end of file +The BPMN process execution is the in-memory representation of a running BPMN process. BPMN processes have their executions structured as a tree hierarchy. Each BPMN process starts with the [process instance](https://docs.camunda.org/manual/7.20/user-guide/process-engine/process-engine-concepts/#process-instances) as its root level execution. If, for example, this root execution reaches a parallel gateway with two paths, it would spawn two child executions under itself for them to process all tasks along their paths on their own. Executions can access all the BPMN elements from the BPMN model as well as the [BPMN process variables](../../concepts/dsf/bpmn-process-variables.md). You have access to this representation in your Java code through the `execution` parameter when overriding certain methods in [Service](../../concepts/dsf/service-delegates.md) / [Message](../../concepts/dsf/message-delegates.md) Delegates like `doExecute` or `getAdditionalInputParameters`. \ No newline at end of file diff --git a/docs/src/developer-documentation/concepts/dsf/bpmn-process-variables.md b/docs/src/developer-documentation/concepts/dsf/bpmn-process-variables.md index 802de45c0..ce456d542 100644 --- a/docs/src/developer-documentation/concepts/dsf/bpmn-process-variables.md +++ b/docs/src/developer-documentation/concepts/dsf/bpmn-process-variables.md @@ -5,10 +5,6 @@ icon: creative ### BPMN Process Variables -BPMN process variables hold additional information which has to be available during BPMN process execution. -Variables can be directly related to BPMN elements like the boolean value for [Conditions](../../concepts/bpmn/conditions.md), but -do not have to be. BPMN process variables are stored as key-value pairs with the key being the variable name. -They are accessible during the entirety of the execution to all [Service](../../concepts/dsf/service-delegates.md) / -[Message](../../concepts/dsf/message-delegates.md) Delegates. +BPMN process variables hold additional information which has to be available during BPMN process execution. Variables can be directly related to BPMN elements like the boolean value for [Conditions](../../concepts/bpmn/conditions.md), but do not have to be. BPMN process variables are stored as key-value pairs with the key being the variable name. They are accessible during the entirety of the execution to all [Service](../../concepts/dsf/service-delegates.md) / [Message](../../concepts/dsf/message-delegates.md) Delegates. You can learn how to access to the BPMN process variables [here](../../guides/accessing-bpmn-process-variables.md). \ No newline at end of file diff --git a/docs/src/developer-documentation/concepts/dsf/certificates.md b/docs/src/developer-documentation/concepts/dsf/certificates.md deleted file mode 100644 index 89cf5f958..000000000 --- a/docs/src/developer-documentation/concepts/dsf/certificates.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -title: Certificates -icon: creative ---- - -### Certificates - -There is a number of certificates that need to be generated in order for DSF instances to communicate with each other securely. -You can find a comprehensive lists of certificates needed by the [DSF FHIR](https://dsf.dev/stable/maintain/fhir/configuration.html) -and [DSF BPE](https://dsf.dev/stable/maintain/bpe/configuration.html) servers on the DSF website. -Certificates will be created by the `test-data-generator` project through Maven by the time of the `package` phase in your process plugin build. -You can also invoke the generation of certificates separately by running the Maven build of `test-data-generator` until (and including) the `package` phase. -Since this tutorial comes with three preconfigured DSF instances, the only time you will need to interact with certificates -is when you want to make requests to the DSF FHIR server. Either for access to the web frontend under https://instance-host-name/fhir/, -or when [starting your process plugin](../../guides/starting-a-process-via-task-resources.md). -In case of the web frontend, you will need to add the CA certificate and client certificate of the DSF instance you want to access to your browser. -Certificates can be found in `test-data-generator/cert`. - -**Example:** -You want to access the `dic` DSF FHIR server. You add the CA certificate located in `test-data-generator/cert/ca` to your -browser's certificate store. You also add the client certificate for `dic` located in `test-data-generator/cert/dic-client` -to your browser's client certificates. - -**Important: Passwords for .p12 files are always "password"** diff --git a/docs/src/developer-documentation/concepts/dsf/draft-task-resources.md b/docs/src/developer-documentation/concepts/dsf/draft-task-resources.md index 66e38dff6..4f0444422 100644 --- a/docs/src/developer-documentation/concepts/dsf/draft-task-resources.md +++ b/docs/src/developer-documentation/concepts/dsf/draft-task-resources.md @@ -5,14 +5,7 @@ icon: creative ### Draft Task Resources -[Task](../../concepts/fhir/task.md) resources with status `draft` are used to create the DSF FHIR server's functionality -of starting processes via its web interface. They are stored in `.../tutorial-process/src/main/resources/fhir/Task`. -Compared to regular [Task](../../concepts/fhir/task.md) resources used to -start BPMN processes, this type of [Task](../../concepts/fhir/task.md) resource requires the status `draft` instead the usual `requested`. -It also replaces the value for `authoredOn` with the placeholder `#{date}`, the values of organization -identifiers with the placeholder `#{organization}` and all instances of version numbers with `#{version}`. -Additionally, it requires setting the `Task.identifier` -element. It should look something like this: +[Task](../../concepts/fhir/task.md) resources with status `draft` are used to create the DSF FHIR server's functionality of starting processes via its web interface. They are stored in `.../tutorial-process/src/main/resources/fhir/Task`. Compared to regular [Task](../../concepts/fhir/task.md) resources used to start BPMN processes, this type of [Task](../../concepts/fhir/task.md) resource requires the status `draft` instead the usual `requested`. It also replaces the value for `authoredOn` with the placeholder `#{date}`, the values of organization identifiers with the placeholder `#{organization}` and all instances of version numbers with `#{version}`. Additionally, it requires setting the `Task.identifier` element. It should look something like this: ```xml <identifier> @@ -23,9 +16,6 @@ element. It should look something like this: `processKey` should be the same one used in [URLs](../../concepts/dsf/about-version-placeholders-and-urls.md#urls). `task-name` can be any String you wish to identify this task with. E.g. you can use the file name of the Draft Task. -For a complete example you can take a look at the Draft Task Resource in one of the solution branches -and compare it to the one needed for cURL. The [Task](../../concepts/fhir/task.md) resource created -for cURL can be found at `.../tutorial-process/src/main/resources/example-task.xml`. +For a complete example you can take a look at the Draft Task Resource in one of the solution branches and compare it to the one needed for cURL. The [Task](../../concepts/fhir/task.md) resource created for cURL can be found at `.../tutorial-process/src/main/resources/example-task.xml`. -You might also want to check out [this guide](../../guides/creating-task-resources-based-on-a-definition.md) -if you do not know how to create [Task](../../concepts/fhir/task.md) resources in general. \ No newline at end of file +You might also want to check out [this guide](../../guides/creating-task-resources-based-on-a-definition.md) if you do not know how to create [Task](../../concepts/fhir/task.md) resources in general. \ No newline at end of file diff --git a/docs/src/developer-documentation/concepts/dsf/environment-variables.md b/docs/src/developer-documentation/concepts/dsf/environment-variables.md index e6a28648a..2ce877cc5 100644 --- a/docs/src/developer-documentation/concepts/dsf/environment-variables.md +++ b/docs/src/developer-documentation/concepts/dsf/environment-variables.md @@ -5,15 +5,6 @@ icon: creative ### Environment Variables -Environment variables offer a way to make configuration data available at the start of a [BPMN process execution](../../concepts/dsf/bpmn-process-execution.md). -They are the same for all running process instances. They can be defined by adding a member variable with -the [Spring-Framework @Value](https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#beans-value-annotations) annotation to the configuration class `TutorialConfig`. The value of the annotation uses -the `${..}` notation and follows the form `${some.property:defaultValue}`, where each dot in the property name corresponds -to an underscore in the equivalent environment variable. Environment variables are always written upper-case. -The property `some.property` therefore corresponds to the environment variable `SOME_PROPERTY`. +Environment variables offer a way to make configuration data available at the start of a [BPMN process execution](../../concepts/dsf/bpmn-process-execution.md). They are the same for all running process instances. They can be defined by adding a member variable with the [Spring-Framework @Value](https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#beans-value-annotations) annotation to the configuration class `TutorialConfig`. The value of the annotation uses the `${..}` notation and follows the form `${some.property:defaultValue}`, where each dot in the property name corresponds to an underscore in the equivalent environment variable. Environment variables are always written upper-case. The property `some.property` therefore corresponds to the environment variable `SOME_PROPERTY`. -The DSF provides a feature to automatically generate documentation of environment variables during the Maven build process. -You can use the `@ProcessDocumentation` annotation to automatically generate Markdown documentation for all fields with this annotation. -You simply have to add [dsf-tools-documentation-generator](https://mvnrepository.com/artifact/dev.dsf/dsf-tools-documentation-generator) as a maven plugin. -You can take a look at the `pom.xml` for the `tutorial-process` submodule to see how you can add it to your own project. -Keep in mind to point the `<workingPackage>` field to the package you want documentation for. \ No newline at end of file +The DSF provides a feature to automatically generate documentation of environment variables during the Maven build process. You can use the `@ProcessDocumentation` annotation to automatically generate Markdown documentation for all fields with this annotation. You simply have to add [dsf-tools-documentation-generator](https://mvnrepository.com/artifact/dev.dsf/dsf-tools-documentation-generator) as a maven plugin. You can take a look at the `pom.xml` for the `tutorial-process` submodule [here](https://github.com/datasharingframework/dsf-process-tutorial/blob/main/tutorial-process/pom.xml) to see how you can add it to your own project. Keep in mind to point the `<workingPackage>` field to the package you want documentation for. \ No newline at end of file diff --git a/docs/src/developer-documentation/concepts/dsf/examples-for-requester-and-recipient-elements.md b/docs/src/developer-documentation/concepts/dsf/examples-for-requester-and-recipient-elements.md index 8b145aa43..64d0164f8 100644 --- a/docs/src/developer-documentation/concepts/dsf/examples-for-requester-and-recipient-elements.md +++ b/docs/src/developer-documentation/concepts/dsf/examples-for-requester-and-recipient-elements.md @@ -5,9 +5,7 @@ icon: creative ### Examples for Requester and Recipient Elements -Below you will find a set of examples for each Coding used by `requester` and `recipient` elements from -the [dsf-extension-process-authorization](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-extension-process-authorization-1.0.0.xml). CodeSystems referenced in the examples can be found [here](https://github.com/datasharingframework/dsf/tree/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/CodeSystem). -Use this collection as a reference point when creating your own [ActivityDefinitions](../../concepts/fhir/activitydefinition.md). +Below you will find a set of examples for each Coding used by `requester` and `recipient` elements from the [dsf-extension-process-authorization](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-extension-process-authorization-1.0.0.xml). CodeSystems referenced in the examples can be found [here](https://github.com/datasharingframework/dsf/tree/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/CodeSystem). Use this collection as a reference point when creating your own [ActivityDefinitions](../../concepts/fhir/activitydefinition.md). #### Requester The `requester` element uses one of the following Codings: diff --git a/docs/src/developer-documentation/concepts/dsf/message-correlation.md b/docs/src/developer-documentation/concepts/dsf/message-correlation.md index 51836aecf..4e91e1515 100644 --- a/docs/src/developer-documentation/concepts/dsf/message-correlation.md +++ b/docs/src/developer-documentation/concepts/dsf/message-correlation.md @@ -5,14 +5,6 @@ icon: creative ### Message Correlation -In order for messages to be able to be sent back and forth between organizations with potentially multiple of the -same process plugin instances running at the same time and still arriving at the correct process instance, -we need some mechanism to map messages to their rightful process instance. -This mechanism is called Message Correlation and requires attaching a unique identifier to every process instance. -This identifier is called the `business-key`. The `business-key` will get attached to every outgoing message automatically. +In order for messages to be able to be sent back and forth between organizations with potentially multiple of the same process plugin instances running at the same time and still arriving at the correct process instance, we need some mechanism to map messages to their rightful process instance. This mechanism is called Message Correlation and requires attaching a unique identifier to every process instance. This identifier is called the `business-key`. The `business-key` will get attached to every outgoing message automatically. -It is possible that the `business-key` is insufficient to map messages to the correct process instance. This happens -when you use subprocesses in your BPMN model which all expect messages to be sent to them, not the parent process. -To solve this issue, [Task](../../concepts/fhir/task.md) resources also come with an [Input Parameter](../../concepts/fhir/task.md#task-input-parameters) called `correlation-key`. -This is a secondary identifier you can attach to all messages if you need them to arrive at a specific subprocess. -You can learn more about how `correlation-keys` are used by studying the [Ping-Pong Process](https://github.com/datasharingframework/dsf-process-ping-pong). \ No newline at end of file +It is possible that the `business-key` is insufficient to map messages to the correct process instance. This happens when you use subprocesses in your BPMN model which all expect messages to be sent to them, not the parent process. To solve this issue, [Task](../../concepts/fhir/task.md) resources also come with an [Input Parameter](../../concepts/fhir/task.md#task-input-parameters) called `correlation-key`. This is a secondary identifier you can attach to all messages if you need them to arrive at a specific subprocess. You can learn more about how `correlation-keys` are used by studying the [Ping-Pong Process](https://github.com/datasharingframework/dsf-process-ping-pong). \ No newline at end of file diff --git a/docs/src/developer-documentation/concepts/dsf/message-delegates.md b/docs/src/developer-documentation/concepts/dsf/message-delegates.md index c1d21e01b..a5aada5d0 100644 --- a/docs/src/developer-documentation/concepts/dsf/message-delegates.md +++ b/docs/src/developer-documentation/concepts/dsf/message-delegates.md @@ -5,25 +5,11 @@ icon: creative ### Message Delegates -Message Delegates are the Java representation of the [Message Events](../../concepts/bpmn/messaging.md) in your BPMN model. -You link a Message Delegate to a certain [Message Event](../../concepts/bpmn/messaging.md) by selecting the Message Event -in the [Camunda Modeler](https://camunda.com/download/modeler/) and adding a Java class to the `Implementation` field. -Make sure you use the fully qualified class name. Like this: +Message Delegates are the Java representation of the [Message Events](../../concepts/bpmn/messaging.md) in your BPMN model. You link a Message Delegate to a certain [Message Event](../../concepts/bpmn/messaging.md) by selecting the Message Event in the [Camunda Modeler](https://camunda.com/download/modeler/) and adding a Java class to the `Implementation` field. Make sure you use the fully qualified class name. Like this: ``` org.package.myClass ``` -You will only need Message Delegates for [Message Send Events](../../concepts/bpmn/messaging.md). Incoming messages will -be resolved to the correct [BPMN process execution](../../concepts/dsf/bpmn-process-execution.md) automatically using [Message Correlation](../../concepts/dsf/message-correlation.md) -and the message inputs will be added to that execution's [process variables](../../concepts/dsf/bpmn-process-variables.md). +You will only need Message Delegates for [Message Send Events](../../concepts/bpmn/messaging.md). Incoming messages will be resolved to the correct [BPMN process execution](../../concepts/dsf/bpmn-process-execution.md) automatically using [Message Correlation](../../concepts/dsf/message-correlation.md) and the message inputs will be added to that execution's [process variables](../../concepts/dsf/bpmn-process-variables.md). -To make a Message Delegate for [Message Send Events](../../concepts/bpmn/messaging.md), your Java class needs to extend -`AbstractTaskMessageSend`. Most of the time, you will not be adding any processing logic to your Message Delegates, therefore you usually won't be overwriting -the `doExecute` method like with [Service Delegates](../../concepts/dsf/service-delegates.md). Instead, you most likely want to -aggregate the information you processed in earlier steps and attach it to a message. For this you need to overwrite the -`getAdditionalInputParamters` method. The DSF translates BPMN messages -into FHIR [Task](../../concepts/fhir/task.md) resources to execute the communication modeled by your BPMN diagrams. The information -you are sending to another BPMN process is specified in the Task.input elements a.k.a. [Input Parameters](../../concepts/fhir/task.md#task-input-parameters), -hence the name of the method. -The constructor of your delegate class should also forward a `ProcessPluginApi` instance to its superclass constructor. -You can learn more about the `ProcessPluginApi` [here](../../concepts/dsf/process-api.md). +To make a Message Delegate for [Message Send Events](../../concepts/bpmn/messaging.md), your Java class needs to extend `AbstractTaskMessageSend`. Most of the time, you will not be adding any processing logic to your Message Delegates, therefore you usually won't be overwriting the `doExecute` method like with [Service Delegates](../../concepts/dsf/service-delegates.md). Instead, you most likely want to aggregate the information you processed in earlier steps and attach it to a message. For this you need to overwrite the `getAdditionalInputParamters` method. The DSF translates BPMN messages into FHIR [Task](../../concepts/fhir/task.md) resources to execute the communication modeled by your BPMN diagrams. The information you are sending to another BPMN process is specified in the Task.input elements a.k.a. [Input Parameters](../../concepts/fhir/task.md#task-input-parameters), hence the name of the method. The constructor of your delegate class should also forward a `ProcessPluginApi` instance to its superclass constructor. You can learn more about the `ProcessPluginApi` [here](../../concepts/dsf/process-api.md). diff --git a/docs/src/developer-documentation/concepts/dsf/organization-identifiers.md b/docs/src/developer-documentation/concepts/dsf/organization-identifiers.md index f632ca7b8..265f75958 100644 --- a/docs/src/developer-documentation/concepts/dsf/organization-identifiers.md +++ b/docs/src/developer-documentation/concepts/dsf/organization-identifiers.md @@ -4,17 +4,7 @@ icon: creative --- ### Organization Identifiers -DSF FHIR server instances always have something called an `organization identifer`. It uniquely identifies -the organization the DSF FHIR server instance belongs to for its [Allow-List mechanism](https://dsf.dev/intro/info/allowList.html). -It is configured as an [environment variable](https://dsf.dev/stable/maintain/fhir/configuration.html#dev-dsf-fhir-server-organization-identifier-value). -You can make a GET request to `https://domain/fhir/Organization` to get a list of all organizations for the DSF FHIR server -instance running under `domain`. The results will also include the `organization identifier` of each organization. +DSF FHIR server instances always have something called an `organization identifer`. It uniquely identifies the organization the DSF FHIR server instance belongs to for its [Allow-List mechanism](https://dsf.dev/intro/info/allowList.html). It is configured as an [environment variable](https://dsf.dev/stable/maintain/fhir/configuration.html#dev-dsf-fhir-server-organization-identifier-value). You can make a GET request to `https://domain/fhir/Organization` to get a list of all organizations for the DSF FHIR server instance running under `domain`. The results will also include the `organization identifier` of each organization. #### Organization Identifiers in Task Resources -[Task](../../concepts/fhir/task.md) resources require you to reference an organization via its identifier as -the `Task.requester` and `Task.restriction.recipient` elements. The exact values for these elements -depend on the [ActivityDefinition](../../concepts/fhir/activitydefinition.md) the [Task](../../concepts/fhir/task.md) resource -should conform to. -As a general rule, you will want to put the identifier of your own organization as the `Task.requester` and `Task.restriction.recipient` elements -for [Task](../../concepts/fhir/task.md) resources which initially start processes. All other cases depend on the context of -the message being sent during process execution. \ No newline at end of file +[Task](../../concepts/fhir/task.md) resources require you to reference an organization via its identifier as the `Task.requester` and `Task.restriction.recipient` elements. The exact values for these elements depend on the [ActivityDefinition](../../concepts/fhir/activitydefinition.md) the [Task](../../concepts/fhir/task.md) resource should conform to. As a general rule, you will want to put the identifier of your own organization as the `Task.requester` and `Task.restriction.recipient` elements for [Task](../../concepts/fhir/task.md) resources which initially start processes. All other cases depend on the context of the message being sent during process execution. \ No newline at end of file diff --git a/docs/src/developer-documentation/concepts/dsf/process-api.md b/docs/src/developer-documentation/concepts/dsf/process-api.md index a18dfdd0d..24774372e 100644 --- a/docs/src/developer-documentation/concepts/dsf/process-api.md +++ b/docs/src/developer-documentation/concepts/dsf/process-api.md @@ -5,12 +5,10 @@ icon: creative ### DSF Process API Package -The [DSF Process API package](https://mvnrepository.com/artifact/dev.dsf/dsf-bpe-process-api-v1) consists of a set of utility classes designed to provide easy access to solutions for process plugin use cases. -This includes for example the `Variables` class, which provides access to the [BPMN process variables](../../concepts/dsf/bpmn-process-variables.md). +The [DSF Process API package](https://mvnrepository.com/artifact/dev.dsf/dsf-bpe-process-api-v1) consists of a set of utility classes designed to provide easy access to solutions for process plugin use cases. This includes for example the `Variables` class, which provides access to the [BPMN process variables](../../concepts/dsf/bpmn-process-variables.md). #### Process Plugin Api -When creating [Service Delegates](../../concepts/dsf/service-delegates.md) or [Message Delegates](../../concepts/dsf/message-delegates.md) you will -notice that you need to provide a constructor which expects a `ProcessPluginApi` object and forward it to the superclasses' constructor. +When creating [Service Delegates](../../concepts/dsf/service-delegates.md) or [Message Delegates](../../concepts/dsf/message-delegates.md) you wil notice that you need to provide a constructor which expects a `ProcessPluginApi` object and forward it to the superclasses' constructor. This API instance provides a variety of utility classes: - `ProxyConfig`**:** forward proxy configuration - `EndpointProvider`**:** access to Endpoint resources diff --git a/docs/src/developer-documentation/concepts/dsf/read-access-tag.md b/docs/src/developer-documentation/concepts/dsf/read-access-tag.md index 0c4131790..98c947241 100644 --- a/docs/src/developer-documentation/concepts/dsf/read-access-tag.md +++ b/docs/src/developer-documentation/concepts/dsf/read-access-tag.md @@ -5,13 +5,7 @@ icon: creative ### Read Access Tag -Axiomatically, nobody is allowed to write FHIR resources (except [Task](../../concepts/fhir/task.md)) to the DSF FHIR server -unless it is your own organization. By default, the same applies to reading FHIR resources -(again except [Task](../../concepts/fhir/task.md)). But since the DSF is often used to offer medical data in form of -FHIR resources, you will find yourself wanting other organizations to be allowed to read the resources you are offering. -The `Resource.meta.tag` element is used define access rules for all FHIR resources in the DSF, with the -exception of [Task](../../concepts/fhir/task.md) resources. We will explain the reason for this exception shortly. -For example, allowing read access for all organizations, you would use the following `system` and `code` in your FHIR resource: +Axiomatically, nobody is allowed to write FHIR resources (except [Task](../../concepts/fhir/task.md)) to the DSF FHIR server unless it is your own organization. By default, the same applies to reading FHIR resources (again except [Task](../../concepts/fhir/task.md)). But since the DSF is often used to offer medical data in form of FHIR resources, you will find yourself wanting other organizations to be allowed to read the resources you are offering. The `Resource.meta.tag` element is used define access rules for all FHIR resources in the DSF, with the exception of [Task](../../concepts/fhir/task.md) resources. We will explain the reason for this exception shortly. For example, allowing read access for all organizations, you would use the following `system` and `code` in your FHIR resource: ```xml <meta> @@ -23,9 +17,6 @@ For example, allowing read access for all organizations, you would use the follo ``` You can find all codes for the Read Access Tag in its [CodeSystem](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/CodeSystem/dsf-read-access-tag-1.0.0.xml). -The read access rules for [Task](../../concepts/fhir/task.md) resources are defined through the `requester` and `recipient` elements of the [dsf-extension-process-authorization](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-extension-process-authorization-1.0.0.xml) in your plugin's -[ActivityDefinitions](../../concepts/fhir/activitydefinition.md). Therefore, no `read-access-tag` is needed. +The read access rules for [Task](../../concepts/fhir/task.md) resources are defined through the `requester` and `recipient` elements of the [dsf-extension-process-authorization](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-extension-process-authorization-1.0.0.xml) in your plugin's [ActivityDefinitions](../../concepts/fhir/activitydefinition.md). Therefore, no `read-access-tag` is needed. -It is also possible to restrict read access of FHIR resources to organizations with -a specific role in a parent organization or a specific identifier. -If you want to find out more, you may look at the [guide on configuring the Read Access Tag](../../guides/configuring-the-read-access-tag.md). +It is also possible to restrict read access of FHIR resources to organizations with a specific role in a parent organization or a specific identifier. If you want to find out more, you may look at the [guide on configuring the Read Access Tag](../../guides/configuring-the-read-access-tag.md). diff --git a/docs/src/developer-documentation/concepts/dsf/service-delegates.md b/docs/src/developer-documentation/concepts/dsf/service-delegates.md index c393d1e13..e39c4bd69 100644 --- a/docs/src/developer-documentation/concepts/dsf/service-delegates.md +++ b/docs/src/developer-documentation/concepts/dsf/service-delegates.md @@ -5,15 +5,8 @@ icon: creative ### Service Delegates -Service Delegates are the Java representation of the [Service Tasks](../../concepts/bpmn/service-tasks.md) in your BPMN model. -You link a Service Delegate to a certain [Service Task](../../concepts/bpmn/service-tasks.md) by selecting the [Service Task](../../concepts/bpmn/service-tasks.md) -in the [Camunda Modeler](https://camunda.com/download/modeler/) and adding a Java class to the `Implementation` field. -Make sure you use the fully qualified class name. Like this: +Service Delegates are the Java representation of the [Service Tasks](../../concepts/bpmn/service-tasks.md) in your BPMN model. You link a Service Delegate to a certain [Service Task](../../concepts/bpmn/service-tasks.md) by selecting the [Service Task](../../concepts/bpmn/service-tasks.md) in the [Camunda Modeler](https://camunda.com/download/modeler/) and adding a Java class to the `Implementation` field. Make sure you use the fully qualified class name. Like this: ``` org.package.myClass ``` -All that is left is for your Java class to extend `AbstractServiceDelegate` and override the `doExecute` method. -This is the place where you can put your actual business logic. The method will be called when the [BPMN process execution](../../concepts/dsf/bpmn-process-execution.md) -arrives at the [Service Task](../../concepts/bpmn/service-tasks.md) your Service Delegate is linked to. -The constructor of your delegate class should also forward a `ProcessPluginApi` instance to its superclass constructor. -You can learn more about the `ProcessPluginApi` [here](../../concepts/dsf/process-api.md). \ No newline at end of file +All that is left is for your Java class to extend `AbstractServiceDelegate` and override the `doExecute` method. This is the place where you can put your actual business logic. The method will be called when the [BPMN process execution](../../concepts/dsf/bpmn-process-execution.md) arrives at the [Service Task](../../concepts/bpmn/service-tasks.md) your Service Delegate is linked to. The constructor of your delegate class should also forward a `ProcessPluginApi` instance to its superclass constructor. You can learn more about the `ProcessPluginApi` [here](../../concepts/dsf/process-api.md). \ No newline at end of file diff --git a/docs/src/developer-documentation/concepts/dsf/spring-integration.md b/docs/src/developer-documentation/concepts/dsf/spring-integration.md index c49e9973f..74fe000f0 100644 --- a/docs/src/developer-documentation/concepts/dsf/spring-integration.md +++ b/docs/src/developer-documentation/concepts/dsf/spring-integration.md @@ -5,16 +5,10 @@ icon: creative ### Spring Integration -Since the DSF also employs the use of the [Spring Framework](https://spring.io/projects/spring-framework) you will also -have to provide some Spring functionality. -When deployed, every process plugin exists in its own [Spring context](https://docs.spring.io/spring-framework/reference/core/beans/introduction.html). To make the process plugin work, you -have to provide [Spring Beans](https://docs.spring.io/spring-framework/reference/core/beans/definition.html) with `prototype` [scope](https://docs.spring.io/spring-framework/reference/core/beans/factory-scopes.html) for all classes which either extend or implement the following classes/interfaces (as of version 1.4.0): +Since the DSF also employs the use of the [Spring Framework](https://spring.io/projects/spring-framework) you will also have to provide some Spring functionality. When deployed, every process plugin exists in its own [Spring context](https://docs.spring.io/spring-framework/reference/core/beans/introduction.html). To make the process plugin work, you have to provide [Spring Beans](https://docs.spring.io/spring-framework/reference/core/beans/definition.html) with `prototype` [scope](https://docs.spring.io/spring-framework/reference/core/beans/factory-scopes.html) for all classes which either extend or implement the following classes/interfaces (as of version 1.4.0): - `AbstractTaskMessageSend` - `AbstractServiceDelegate` - `DefaultUserTaskListener` - `ProcessPluginDeploymentStateListener` -A [Spring-Framework configuration class](https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#beans-java-basic-concepts) located in `spring/config` is expected to provide the Spring Beans. -For this tutorial, the `TutorialConfig` class will take this role. -If you are unfamiliar with the Spring Framework, you might want to check out the chapter [Java-based Container Configuration](https://docs.spring.io/spring-framework/reference/core/beans/java.html) -of the Spring Framework documentation, specifically the topics [Using the @Bean Annotation](https://docs.spring.io/spring-framework/reference/core/beans/java/bean-annotation.html) and [Using the @Configuration Annotation](https://docs.spring.io/spring-framework/reference/core/beans/java/configuration-annotation.html). \ No newline at end of file +A [Spring-Framework configuration class](https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#beans-java-basic-concepts) located in `spring/config` is expected to provide the Spring Beans. For this tutorial, the `TutorialConfig` class will take this role. If you are unfamiliar with the Spring Framework, you might want to check out the chapter [Java-based Container Configuration](https://docs.spring.io/spring-framework/reference/core/beans/java.html) of the Spring Framework documentation, specifically the topics [Using the @Bean Annotation](https://docs.spring.io/spring-framework/reference/core/beans/java/bean-annotation.html) and [Using the @Configuration Annotation](https://docs.spring.io/spring-framework/reference/core/beans/java/configuration-annotation.html). \ No newline at end of file diff --git a/docs/src/developer-documentation/concepts/dsf/the-process-plugin-definition.md b/docs/src/developer-documentation/concepts/dsf/the-process-plugin-definition.md index ac7810b5e..06297175a 100644 --- a/docs/src/developer-documentation/concepts/dsf/the-process-plugin-definition.md +++ b/docs/src/developer-documentation/concepts/dsf/the-process-plugin-definition.md @@ -13,8 +13,4 @@ In order for the DSF BPE server to load your plugin you need to provide it with * The FHIR resources grouped by BPMN process ID. Your plugin may have any number of BPMN models. Each has their own BPMN process ID and FHIR resources specific to that BPMN process (think [Task](../../concepts/fhir/task.md) resources needed for messages specific to that BPMN model) * The Class holding your [Spring Configuration](../../concepts/dsf/spring-integration.md) -You will provide this information by implementing the `dev.dsf.bpe.ProcessPluginDefinition` interface. -The DSF BPE server then searches for classes implementing this interface using the -Java [ServiceLoader](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/ServiceLoader.html) mechanism. Therefore, you will have to register your interface implementation in the `src/main/resources/META-INF/services/dev.dsf.bpe.ProcessPluginDefinition` file. -For this tutorial, the class implementing the `ProcessPluginDefinition` interface, `TutorialProcessPluginDefinition`, -has already been added to the file. You can use it as a reference for later when you want to create your own plugin. \ No newline at end of file +You will provide this information by implementing the `dev.dsf.bpe.ProcessPluginDefinition` interface. The DSF BPE server then searches for classes implementing this interface using the Java [ServiceLoader](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/ServiceLoader.html) mechanism. Therefore, you will have to register your interface implementation in the `src/main/resources/META-INF/services/dev.dsf.bpe.ProcessPluginDefinition` file. For this tutorial, the class implementing the `ProcessPluginDefinition` interface, `TutorialProcessPluginDefinition`, has already been added to the file. You can use it as a reference for later when you want to create your own plugin. \ No newline at end of file diff --git a/docs/src/developer-documentation/concepts/fhir/activitydefinition.md b/docs/src/developer-documentation/concepts/fhir/activitydefinition.md index b51904c0a..4a5bf5e1b 100644 --- a/docs/src/developer-documentation/concepts/fhir/activitydefinition.md +++ b/docs/src/developer-documentation/concepts/fhir/activitydefinition.md @@ -5,9 +5,7 @@ icon: creative ### ActivityDefinition -[ActivityDefinitions](http://hl7.org/fhir/R4/activitydefinition.html) are used by the DSF to advertise which processes are -available at any given instance and who is allowed to request and who is allowed to execute a process. The DSF defined elements -for this purpose in the [dsf-activity-definition](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-activity-definition-1.0.0.xml) profile. +[ActivityDefinitions](http://hl7.org/fhir/R4/activitydefinition.html) are used by the DSF to advertise which processes are available at any given instance and who is allowed to request and who is allowed to execute a process. The DSF defined elements for this purpose in the [dsf-activity-definition](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-activity-definition-1.0.0.xml) profile. The most important elements in ActivityDefinitions are: @@ -16,17 +14,10 @@ The most important elements in ActivityDefinitions are: - `requester` - `recipient` -The `message-name` element contains the name of the [BPMN message start event](../../concepts/bpmn/messaging.md#message-start-event) or -[BPMN message intermediate catching event](../../concepts/bpmn/messaging.md#message-intermediate-catching-event) which expects -a [Task](../../concepts/fhir/task.md) resource complying to the profile defined by `task-profile`. +The `message-name` element contains the name of the [BPMN message start event](../../concepts/bpmn/messaging.md#message-start-event) or [BPMN message intermediate catching event](../../concepts/bpmn/messaging.md#message-intermediate-catching-event) which expects a [Task](../../concepts/fhir/task.md) resource complying to the profile defined by `task-profile`. -The `requester` and `recipient` elements define the organisation(s) or person(s) who are allowed to request or receive the message -specified by `message-name`. The receiving DSF instance is the one who will execute the process connected to the message. +The `requester` and `recipient` elements define the organisation(s) or person(s) who are allowed to request or receive the message specified by `message-name`. The receiving DSF instance is the one who will execute the process connected to the message. -You will have to create your own [ActivityDefinitions](../../concepts/fhir/activitydefinition.md) when developing a process plugin. -If you are fluent in reading XML FHIR definitions and translating them into XML resources, you can take a look at the -DSF's profile for ActivityDefinitions [here](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-activity-definition-1.0.0.xml). -ActivityDefinitions also reference other resource definitions. Depending on the resource, you will find them in one of [these folders](https://github.com/datasharingframework/dsf/tree/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir). -If you are not as comfortable with these requirements you might want to check out the guide on [creating ActivityDefinitions](../../guides/creating-an-activity-definition.md). +You will have to create your own [ActivityDefinitions](../../concepts/fhir/activitydefinition.md) when developing a process plugin. If you are fluent in reading XML FHIR definitions and translating them into XML resources, you can take a look at the DSF's profile for ActivityDefinitions [here](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-activity-definition-1.0.0.xml). ActivityDefinitions also reference other resource definitions. Depending on the resource, you will find them in one of [these folders](https://github.com/datasharingframework/dsf/tree/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir). If you are not as comfortable with these requirements you might want to check out the guide on [creating ActivityDefinitions](../../guides/creating-an-activity-definition.md). You can also find examples for all possible `requester` and `recipient` elements [here](../../concepts/dsf/examples-for-requester-and-recipient-elements.md). \ No newline at end of file diff --git a/docs/src/developer-documentation/concepts/fhir/codesystem.md b/docs/src/developer-documentation/concepts/fhir/codesystem.md index 6e2bcc8cc..6787445c9 100644 --- a/docs/src/developer-documentation/concepts/fhir/codesystem.md +++ b/docs/src/developer-documentation/concepts/fhir/codesystem.md @@ -5,9 +5,7 @@ icon: creative ### CodeSystem -[CodeSystems](https://www.hl7.org/fhir/R4/codesystem.html) usually represent a set of concepts which -can be assigned to a code (think LOINC). If you want to use a Code in a resource, you will usually include them in a -[ValueSet](../../concepts/fhir/valueset.md). +[CodeSystems](https://www.hl7.org/fhir/R4/codesystem.html) usually represent a set of concepts which can be assigned to a code (think LOINC). If you want to use a Code in a resource, you will usually include them in a [ValueSet](../../concepts/fhir/valueset.md). Plugin development for the DSF requires the use of [CodeSystems](https://www.hl7.org/fhir/R4/codesystem.html) in two major ways: 1. Using existing [DSF CodeSystems](https://github.com/datasharingframework/dsf/tree/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/CodeSystem) in other FHIR resources like the [dsf-extension-process-authorization](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-extension-process-authorization-1.0.0.xml). diff --git a/docs/src/developer-documentation/concepts/fhir/introduction.md b/docs/src/developer-documentation/concepts/fhir/introduction.md index 16614fb74..19d3e9b23 100644 --- a/docs/src/developer-documentation/concepts/fhir/introduction.md +++ b/docs/src/developer-documentation/concepts/fhir/introduction.md @@ -5,8 +5,4 @@ icon: creative ## FHIR Introduction -The DSF uses a variety of [FHIR resources](https://dsf.dev/intro/info/basics.html#why-are-we-using-fhir-and-bpmn). The DSF uses XML as the format for FHIR resources. -The most important resources for plugin development are [ActivityDefinitions](../../concepts/fhir/activitydefinition.md), [Tasks](../../concepts/fhir/task.md), -[CodeSystems](../../concepts/fhir/codesystem.md) and [ValueSets](../../concepts/fhir/valueset.md). -There is also a catalogue of DSF-specific FHIR resources including CodeSystems, ValueSets and Extensions. For now, you can find them in the official -DSF GitHub repository [here](https://github.com/datasharingframework/dsf/tree/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir). +The DSF uses a variety of [FHIR resources](https://dsf.dev/intro/info/basics.html#why-are-we-using-fhir-and-bpmn). The DSF uses XML as the format for FHIR resources. The most important resources for plugin development are [ActivityDefinitions](../../concepts/fhir/activitydefinition.md), [Tasks](../../concepts/fhir/task.md), [CodeSystems](../../concepts/fhir/codesystem.md) and [ValueSets](../../concepts/fhir/valueset.md). There is also a catalogue of DSF-specific FHIR resources including CodeSystems, ValueSets and Extensions. For now, you can find them in the official DSF GitHub repository [here](https://github.com/datasharingframework/dsf/tree/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir). diff --git a/docs/src/developer-documentation/concepts/fhir/task.md b/docs/src/developer-documentation/concepts/fhir/task.md index 573cb9028..85e6dab5e 100644 --- a/docs/src/developer-documentation/concepts/fhir/task.md +++ b/docs/src/developer-documentation/concepts/fhir/task.md @@ -5,12 +5,7 @@ icon: creative ### Task -The [FHIR Task](https://www.hl7.org/fhir/R4/task.html) resource enables the DSF's distributed communication. -Whenever a BPMN process instance communicates with a different process instance, the DSF will create a Task resource -based on parameters you set in the BPMN model and during execution. It will then -automatically send the Task resource to the recipient to start or continue whatever process the Task resource referred to. -All Task resources used in the DSF derive from the [dsf-task-base](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-task-base-1.0.0.xml). -This profile includes a splicing for `Task.input` with three additional [Input Parameters](../../concepts/fhir/task.md#task-input-parameters): +The [FHIR Task](https://www.hl7.org/fhir/R4/task.html) resource enables the DSF's distributed communication. Whenever a BPMN process instance communicates with a different process instance, the DSF will create a Task resource based on parameters you set in the BPMN model and during execution. It will then automatically send the Task resource to the recipient to start or continue whatever process the Task resource referred to. All Task resources used in the DSF derive from the [dsf-task-base](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-task-base-1.0.0.xml). This profile includes a splicing for `Task.input` with three additional [Input Parameters](../../concepts/fhir/task.md#task-input-parameters): - `message-name` - `business-key` - `correlation-key` @@ -19,9 +14,6 @@ When creating your own plugin, you will want to create your own profiles based o #### Task Input Parameters -Task Input Parameters allow you to add additional information to [Task](task.md#task) resources. -For example, if your particular data exchange requires additional medical data, you would add a slice to your Task profile in the same -way the [dsf-task-base](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-task-base-1.0.0.xml) adds slices to the original [FHIR Task](https://www.hl7.org/fhir/R4/task.html) resource. Notice that this also requires creating a [CodeSystem](../../concepts/fhir/codesystem.md) and -including it in a [ValueSet](../../concepts/fhir/valueset.md) to be able to use it in the Task resource. +Task Input Parameters allow you to add additional information to [Task](task.md#task) resources. For example, if your particular data exchange requires additional medical data, you would add a slice to your Task profile in the same way the [dsf-task-base](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-task-base-1.0.0.xml) adds slices to the original [FHIR Task](https://www.hl7.org/fhir/R4/task.html) resource. Notice that this also requires creating a [CodeSystem](../../concepts/fhir/codesystem.md) and including it in a [ValueSet](../../concepts/fhir/valueset.md) to be able to use it in the Task resource. If these instructions are insufficient you can check out the guide on [how to add Task Input Parameters](../../guides/adding-task-input-parameters-to-task-profiles.md). \ No newline at end of file diff --git a/docs/src/developer-documentation/concepts/fhir/valueset.md b/docs/src/developer-documentation/concepts/fhir/valueset.md index d53f19990..918ec2ffe 100644 --- a/docs/src/developer-documentation/concepts/fhir/valueset.md +++ b/docs/src/developer-documentation/concepts/fhir/valueset.md @@ -5,8 +5,6 @@ icon: creative ### ValueSet -[ValueSets](https://www.hl7.org/fhir/R4/valueset.html) bind codes from [CodeSystems](../../concepts/fhir/codesystem.md) to coded elements like -`code`, `Coding` or `CodeableConcept`. +[ValueSets](https://www.hl7.org/fhir/R4/valueset.html) bind codes from [CodeSystems](../../concepts/fhir/codesystem.md) to coded elements like `code`, `Coding` or `CodeableConcept`. -[ValueSets](https://www.hl7.org/fhir/R4/valueset.html) are mostly needed to use the [Concepts](https://www.hl7.org/fhir/R4/codesystem-definitions.html#CodeSystem.concept) from [CodeSystems](../../concepts/fhir/codesystem.md) -in your [Task](../../concepts/fhir/task.md) profiles. \ No newline at end of file +[ValueSets](https://www.hl7.org/fhir/R4/valueset.html) are mostly needed to use the [Concepts](https://www.hl7.org/fhir/R4/codesystem-definitions.html#CodeSystem.concept) from [CodeSystems](../../concepts/fhir/codesystem.md) in your [Task](../../concepts/fhir/task.md) profiles. \ No newline at end of file diff --git a/docs/src/developer-documentation/guides/accessing-bpmn-process-variables.md b/docs/src/developer-documentation/guides/accessing-bpmn-process-variables.md index 1a4410686..97e355c9f 100644 --- a/docs/src/developer-documentation/guides/accessing-bpmn-process-variables.md +++ b/docs/src/developer-documentation/guides/accessing-bpmn-process-variables.md @@ -5,10 +5,6 @@ icon: creative ### Accessing BPMN Process Variables -After creating a [Service Delegate](../concepts/dsf/service-delegates.md) or [Message Delegate](../concepts/dsf/message-delegates.md), you might want to -retrieve data from or store data in the [BPMN process variables](../concepts/dsf/bpmn-process-variables.md). -You can achieve this either through the [BPMN process execution](../concepts/dsf/bpmn-process-execution.md) or via the `Variables` class. +After creating a [Service Delegate](../concepts/dsf/service-delegates.md) or [Message Delegate](../concepts/dsf/message-delegates.md), you might want to retrieve data from or store data in the [BPMN process variables](../concepts/dsf/bpmn-process-variables.md).You can achieve this either through the [BPMN process execution](../concepts/dsf/bpmn-process-execution.md) or via the `Variables` class. *It is very much recommended you use the latter method*. -The `Variables` class provides lots of utility methods to read or write certain types -of [BPMN process variables](../concepts/dsf/bpmn-process-variables.md). If for some reason you need to fall back on the [BPMN process execution](../concepts/dsf/bpmn-process-execution.md) -to solve your problem, we would like to learn how the current API of the `Variables` class is limiting you. Contact us, and we might turn it into a feature request ([Contribute](https://dsf.dev/stable/contribute)). +The `Variables` class provides lots of utility methods to read or write certain types of [BPMN process variables](../concepts/dsf/bpmn-process-variables.md). If for some reason you need to fall back on the [BPMN process execution](../concepts/dsf/bpmn-process-execution.md) to solve your problem, we would like to learn how the current API of the `Variables` class is limiting you. Contact us, and we might turn it into a feature request ([Contribute](https://dsf.dev/stable/contribute)). diff --git a/docs/src/developer-documentation/guides/accessing-task-resources-during-execution.md b/docs/src/developer-documentation/guides/accessing-task-resources-during-execution.md index b40b2c31a..808b0fa4f 100644 --- a/docs/src/developer-documentation/guides/accessing-task-resources-during-execution.md +++ b/docs/src/developer-documentation/guides/accessing-task-resources-during-execution.md @@ -5,20 +5,8 @@ icon: creative ### Accessing Task Resources During Execution -If you want access to the [Task](../concepts/fhir/task.md) resources in your [Service](../concepts/dsf/service-delegates.md) / [Message](../concepts/dsf/message-delegates.md) Delegates, the `Variables` class will -provide methods which return certain kinds of [Task](../concepts/fhir/task.md) resources. The most commonly used ones are -the start [Task](../concepts/fhir/task.md), referring to the [Task](../concepts/fhir/task.md) / [Message Start Event](../concepts/bpmn/messaging.md#message-start-event) responsible for starting the process, -and the latest [Task](../concepts/fhir/task.md), referring to most recently received [Task](../concepts/fhir/task.md) / Message. -In principle, this is sufficient to access all information in a [Task](basic-concepts-and-guides.md#task) resource, since you have -the [Task](../concepts/fhir/task.md) resource's Java object, but very cumbersome. -Instead of navigating the [Task](../concepts/fhir/task.md) resource's element tree, -you should first try to use the [ProcessPluginApi's](../concepts/dsf/process-api.md) `TaskHelper` in conjunction with the method above. The `TaskHelper` class -offers specific methods related to [Task](../concepts/fhir/task.md) resources. -The most common use case for this is retrieving data from a [Task's](../concepts/fhir/task.md) [Input Parameter](../concepts/fhir/task.md#task-input-parameters) or creating a new [Input Parameter](../concepts/fhir/task.md#task-input-parameters) -for a [Message Delegate's](../concepts/dsf/message-delegates.md) `getAdditionalInputParameters` method. -When retrieving data from a [Task's](../concepts/fhir/task.md) Input Parameter you first have to get to the [Input Parameter](../concepts/fhir/task.md#task-input-parameters) you are looking to extract -data from. You can use one of the `TaskHelper's` getters for [Input Parameters](../concepts/fhir/task.md#task-input-parameters) to find the right one. The methods will try to match -the provided [CodeSystem](../concepts/fhir/codesystem.md) and Code to any [Input Parameter](../concepts/fhir/task.md#task-input-parameters) of the provided [Task](../concepts/fhir/task.md) resource. -Depending on the method you chose you will for example receive all matches or just the first one. -To create new [Input Parameters](../concepts/fhir/task.md#task-input-parameters) to attach to a [Task](../concepts/fhir/task.md) resource, you may invoke the `TaskHelper#createInput` method. This -is most often used when overriding the `getAdditionalInputParamters` method of you [Message Delegate](../concepts/dsf/message-delegates.md). \ No newline at end of file +If you want access to the [Task](../concepts/fhir/task.md) resources in your [Service](../concepts/dsf/service-delegates.md) / [Message](../concepts/dsf/message-delegates.md) Delegates, the `Variables` class will provide methods which return certain kinds of [Task](../concepts/fhir/task.md) resources. The most commonly used ones are the start [Task](../concepts/fhir/task.md), referring to the [Task](../concepts/fhir/task.md) / [Message Start Event](../concepts/bpmn/messaging.md#message-start-event) responsible for starting the process, and the latest [Task](../concepts/fhir/task.md), referring to most recently received [Task](../concepts/fhir/task.md) / Message. +In principle, this is sufficient to access all information in a [Task](basic-concepts-and-guides.md#task) resource, since you have the [Task](../concepts/fhir/task.md) resource's Java object, but very cumbersome. +Instead of navigating the [Task](../concepts/fhir/task.md) resource's element tree, you should first try to use the [ProcessPluginApi's](../concepts/dsf/process-api.md) `TaskHelper` in conjunction with the method above. The `TaskHelper` class offers specific methods related to [Task](../concepts/fhir/task.md) resources. +The most common use case for this is retrieving data from a [Task's](../concepts/fhir/task.md) [Input Parameter](../concepts/fhir/task.md#task-input-parameters) or creating a new [Input Parameter](../concepts/fhir/task.md#task-input-parameters) for a [Message Delegate's](../concepts/dsf/message-delegates.md) `getAdditionalInputParameters` method. When retrieving data from a [Task's](../concepts/fhir/task.md) Input Parameter you first have to get to the [Input Parameter](../concepts/fhir/task.md#task-input-parameters) you are looking to extract data from. You can use one of the `TaskHelper's` getters for [Input Parameters](../concepts/fhir/task.md#task-input-parameters) to find the right one. The methods will try to match the provided [CodeSystem](../concepts/fhir/codesystem.md) and Code to any [Input Parameter](../concepts/fhir/task.md#task-input-parameters) of the provided [Task](../concepts/fhir/task.md) resource. Depending on the method you chose you will for example receive all matches or just the first one. +To create new [Input Parameters](../concepts/fhir/task.md#task-input-parameters) to attach to a [Task](../concepts/fhir/task.md) resource, you may invoke the `TaskHelper#createInput` method. This is most often used when overriding the `getAdditionalInputParamters` method of you [Message Delegate](../concepts/dsf/message-delegates.md). \ No newline at end of file diff --git a/docs/src/developer-documentation/guides/adding-task-input-parameters-to-task-profiles.md b/docs/src/developer-documentation/guides/adding-task-input-parameters-to-task-profiles.md index c3bbf0a21..3fded3631 100644 --- a/docs/src/developer-documentation/guides/adding-task-input-parameters-to-task-profiles.md +++ b/docs/src/developer-documentation/guides/adding-task-input-parameters-to-task-profiles.md @@ -5,20 +5,11 @@ icon: creative ### Adding Task Input Parameters to Task Profiles -When adding a new [Input Parameter](../concepts/fhir/task.md#task-input-parameters) to a [Task](../concepts/fhir/task.md) -profile, you are essentially adding a new slice to `Task.input`. [Slicing](https://www.hl7.org/fhir/R4/profiling.html#slicing) is part -of [profiling](https://www.hl7.org/fhir/R4/profiling.html) in FHIR. Profiling lets you create your own -FHIR definitions based on pre-existing FHIR definitions. A slicing defines constraints on element lists -like `Task.input` e.g. by only allowing the elements to be of certain types. For example, you -might have a list of fruits in a `FruitBasket` resource. Constraining that list to only include -fruits of type `Apple`, `Banana` and `Orange` would be considered [slicing](https://www.hl7.org/fhir/R4/profiling.html#slicing). -This guide will not cover how slicing works in general, only for the case presented by the DSF FHIR resource -context. Our goal will be to add a new [Input Parameter](../concepts/fhir/task.md#task-input-parameters) -of type `example-input` to the `task-start-dic-process.xml` profile which will be used to submit `integer` values to our `dicProcess`. - -Let us start out by adding a slice to `task-start-dic-process.xml`. Since there is already a slicing defined -on `Task.input` by `task-start-dic-process.xml`'s `baseDefinition`, we have to check out this resource first. -As a part of the [differential](https://www.hl7.org/fhir/R4/profiling.html#snapshot) statement, slicing also uses [Element Definitions](https://www.hl7.org/fhir/R4/elementdefinition.html). +When adding a new [Input Parameter](../concepts/fhir/task.md#task-input-parameters) to a [Task](../concepts/fhir/task.md) profile, you are essentially adding a new slice to `Task.input`. [Slicing](https://www.hl7.org/fhir/R4/profiling.html#slicing) is part of [profiling](https://www.hl7.org/fhir/R4/profiling.html) in FHIR. Profiling lets you create your own FHIR definitions based on pre-existing FHIR definitions. A slicing defines constraints on element lists like `Task.input` e.g. by only allowing the elements to be of certain types. +For example, you might have a list of fruits in a `FruitBasket` resource. Constraining that list to only include fruits of type `Apple`, `Banana` and `Orange` would be considered [slicing](https://www.hl7.org/fhir/R4/profiling.html#slicing). +This guide will not cover how slicing works in general, only for the case presented by the DSF FHIR resource context. Our goal will be to add a new [Input Parameter](../concepts/fhir/task.md#task-input-parameters) of type `example-input` to the `task-start-dic-process.xml` profile which will be used to submit `integer` values to our `dicProcess`. + +Let us start out by adding a slice to `task-start-dic-process.xml`. Since there is already a slicing defined on `Task.input` by `task-start-dic-process.xml`'s `baseDefinition`, we have to check out this resource first. As a part of the [differential](https://www.hl7.org/fhir/R4/profiling.html#snapshot) statement, slicing also uses [Element Definitions](https://www.hl7.org/fhir/R4/elementdefinition.html). The slicing for `Task.input` is defined in this part of the `baseDefinition`: ```xml <element id="Task.input"> @@ -42,12 +33,7 @@ The slicing for `Task.input` is defined in this part of the `baseDefinition`: ``` *The resource can be found [here](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-task-base-1.0.0.xml)* -We will only need to take a look at the `discrimitator` tag for now. -Discriminators define the elements a FHIR processor needs to distinguish slices by. In our case, a processor -would look at the values for `type.coding.system` and `type.coding.code` to determine which -slice this element belongs to. The discriminator type `value` implies that `type.coding.system` and `type.coding.code` -have to be present in all slices and need to have a fixed value. -You can learn more about discriminators [here](https://www.hl7.org/fhir/R4/profiling.html#discriminator). +We will only need to take a look at the `discrimitator` tag for now. Discriminators define the elements a FHIR processor needs to distinguish slices by. In our case, a processor would look at the values for `type.coding.system` and `type.coding.code` to determine which slice this element belongs to. The discriminator type `value` implies that `type.coding.system` and `type.coding.code` have to be present in all slices and need to have a fixed value. You can learn more about discriminators [here](https://www.hl7.org/fhir/R4/profiling.html#discriminator). Let us revisit `task-start-dic-process.xml` and start adding a slice called `example-input` to it: ```xml @@ -64,17 +50,11 @@ Let us revisit `task-start-dic-process.xml` and start adding a slice called `exa </differential> </StructureDefinition> ``` -*Unnecessary elements for this guide are hidden by ... placeholders.* +*Irrelevant elements for this guide are hidden by ... placeholders.* -We have now defined a slice on `Task.input` with the name and id of `example-input` and cardinality of `1..1`. You might -want a different cardinality for your use case. We recommend you also take a look at the documentation for [ElementDefinition.id](https://www.hl7.org/fhir/R4/elementdefinition.html#id) -and [ElementDefinition.path](https://www.hl7.org/fhir/R4/elementdefinition.html#path). They explain how to create the proper -values for these elements. Cardinality is also part of the [element definition](https://www.hl7.org/fhir/R4/elementdefinition.html) -hierarchy (see [ElementDefinition.min](https://www.hl7.org/fhir/R4/elementdefinition-definitions.html#ElementDefinition.min) and [ElementDefinition.max](https://www.hl7.org/fhir/R4/elementdefinition-definitions.html#ElementDefinition.max)). +We have now defined a slice on `Task.input` with the name and id of `example-input` and cardinality of `1..1`. You might want a different cardinality for your use case. We recommend you also take a look at the documentation for [ElementDefinition.id](https://www.hl7.org/fhir/R4/elementdefinition.html#id) and [ElementDefinition.path](https://www.hl7.org/fhir/R4/elementdefinition.html#path). They explain how to create the proper values for these elements. Cardinality is also part of the [element definition](https://www.hl7.org/fhir/R4/elementdefinition.html) hierarchy (see [ElementDefinition.min](https://www.hl7.org/fhir/R4/elementdefinition-definitions.html#ElementDefinition.min) and [ElementDefinition.max](https://www.hl7.org/fhir/R4/elementdefinition-definitions.html#ElementDefinition.max)). -Next up, we need to define the binding for `Task.input:example-input.type`. Because `Task.input.type` -is a `CodeableConcept` which uses codings from a [ValueSet](../concepts/fhir/valueset.md), -the [discriminator](https://www.hl7.org/fhir/R4/profiling.html#discriminator) requires us to use `required` as the binding strength: +Next up, we need to define the binding for `Task.input:example-input.type`. Because `Task.input.type` is a `CodeableConcept` which uses codings from a [ValueSet](../concepts/fhir/valueset.md), the [discriminator](https://www.hl7.org/fhir/R4/profiling.html#discriminator) requires us to use `required` as the binding strength: ```xml <StructureDefinition xmlns="http://hl7.org/fhir"> ... @@ -96,12 +76,9 @@ the [discriminator](https://www.hl7.org/fhir/R4/profiling.html#discriminator) re </differential> </StructureDefinition> ``` -As you can see, we referenced a [ValueSet](../concepts/fhir/valueset.md) in this binding. -When adding an actual slice for your use case, you will have to reference an existing [ValueSet](../concepts/fhir/valueset.md) resource or create a new -one. A guide on how to create them can be found [here](../guides/creating-valuesets-for-dsf-processes.md). +As you can see, we referenced a [ValueSet](../concepts/fhir/valueset.md) in this binding. When adding an actual slice for your use case, you will have to reference an existing [ValueSet](../concepts/fhir/valueset.md) resource or create a new one. A guide on how to create them can be found [here](../guides/creating-valuesets-for-dsf-processes.md). -Since the [discriminator](https://www.hl7.org/fhir/R4/profiling.html#discriminator) requires -`Task.input.coding.code` and `Task.input.coding.system` to be present, we will make `Task.input.coding` mandatory as well: +Since the [discriminator](https://www.hl7.org/fhir/R4/profiling.html#discriminator) requires `Task.input.coding.code` and `Task.input.coding.system` to be present, we will make `Task.input.coding` mandatory as well: ```xml <StructureDefinition xmlns="http://hl7.org/fhir"> ... @@ -128,8 +105,7 @@ Since the [discriminator](https://www.hl7.org/fhir/R4/profiling.html#discriminat </StructureDefinition> ``` -In the beginning we mentioned how `Task.input.type.coding.system` and `Task.input.type.coding.code` -have to use fixed values. Here is how we accomplish this: +In the beginning we mentioned how `Task.input.type.coding.system` and `Task.input.type.coding.code` have to use fixed values. Here is how we accomplish this: ```xml <StructureDefinition xmlns="http://hl7.org/fhir"> @@ -168,11 +144,7 @@ have to use fixed values. Here is how we accomplish this: ``` *Notice that we also made the two elements mandatory because they are required by the discriminator.* -For the `type.coding.system` element we referenced a [CodeSystem](../concepts/fhir/codesystem.md). -The `type.coding.code` element uses a code from this [CodeSystem](../concepts/fhir/codesystem.md) called `example-input`. -This is the mechanism by which you actually "name" your [Input Parameter](../concepts/fhir/task.md#task-input-parameters). The -`type.coding.code` value will identify your [Input Parameter](../concepts/fhir/task.md#task-input-parameters) when you use -it in an actual [Task](../concepts/fhir/task.md#task-input-parameters) resource. Here is how this would look like: +For the `type.coding.system` element we referenced a [CodeSystem](../concepts/fhir/codesystem.md). The `type.coding.code` element uses a code from this [CodeSystem](../concepts/fhir/codesystem.md) called `example-input`. This is the mechanism by which you actually "name" your [Input Parameter](../concepts/fhir/task.md#task-input-parameters). The `type.coding.code` value will identify your [Input Parameter](../concepts/fhir/task.md#task-input-parameters) when you use it in an actual [Task](../concepts/fhir/task.md#task-input-parameters) resource. Here is how this would look like: ```xml <Task xmlns="http://hl7.org/fhir"> @@ -189,12 +161,9 @@ it in an actual [Task](../concepts/fhir/task.md#task-input-parameters) resource. </Task> ``` -When adding an actual slice for your use case, you will also need to reference an existing [CodeSystem](../concepts/fhir/codesystem.md) resource or create a new one to reference. -A guide on how to create them can be found [here](../guides/creating-codesystems-for-dsf-processes.md). +When adding an actual slice for your use case, you will also need to reference an existing [CodeSystem](../concepts/fhir/codesystem.md) resource or create a new one to reference. A guide on how to create them can be found [here](../guides/creating-codesystems-for-dsf-processes.md). -`Task.input.value[x]` is the actual value you will submit using your Input Parameter. You can make it -any of [these](https://www.hl7.org/fhir/R4/datatypes.html#open) data types. This is because `Type.input.value[x]` -refers to `*` instead of any particular type in its [definition](https://www.hl7.org/fhir/R4/task-definitions.html#Task.input.value_x_). Let us define it as an `integer` type`: +`Task.input.value[x]` is the actual value you will submit using your Input Parameter. You can make it any of [these](https://www.hl7.org/fhir/R4/datatypes.html#open) data types. This is because `Type.input.value[x]` refers to `*` instead of any particular type in its [definition](https://www.hl7.org/fhir/R4/task-definitions.html#Task.input.value_x_). Let us define it as an `integer` type`: ```xml <StructureDefinition xmlns="http://hl7.org/fhir"> diff --git a/docs/src/developer-documentation/guides/configuring-the-read-access-tag.md b/docs/src/developer-documentation/guides/configuring-the-read-access-tag.md index 320e12b31..983d7cdba 100644 --- a/docs/src/developer-documentation/guides/configuring-the-read-access-tag.md +++ b/docs/src/developer-documentation/guides/configuring-the-read-access-tag.md @@ -5,8 +5,7 @@ icon: creative ### Configuring the Read Access Tag -To start off, you want to take a look at the [CodeSystem](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/CodeSystem/dsf-read-access-tag-1.0.0.xml) defined for the [Read Access Tag](../concepts/dsf/read-access-tag.md) -and choose one of the codes from it: +To start off, you want to take a look at the [CodeSystem](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/CodeSystem/dsf-read-access-tag-1.0.0.xml) defined for the [Read Access Tag](../concepts/dsf/read-access-tag.md) and choose one of the codes from it: ```xml <CodeSystem xmlns="http://hl7.org/fhir"> ... @@ -135,8 +134,7 @@ The most important part of it is the `differential` statement. It uses [element </StructureDefinition> ``` -All extensions for the [Read Access Tag](../concepts/dsf/read-access-tag.md) CodeSystem are defined on the `meta.tag.extension` element through -the extension's `context` element: +All extensions for the [Read Access Tag](../concepts/dsf/read-access-tag.md) CodeSystem are defined on the `meta.tag.extension` element through the extension's `context` element: ```xml <context> <type value="element" /> @@ -177,11 +175,7 @@ We will now go through the `differential` statement one element at a time, start </StructureDefinition> ``` -It defines a [slicing](https://www.hl7.org/fhir/R4/profiling.html#slicing) for the `Extension.extension` element, meaning we are dealing -with a nested extension. The `discriminator` element tells us that slices will be identified by the value of their `url` attribute. -A `rules` element with value `open` means other types of slices may be added later on e.g. when creating a profile. We do not have to -add any elements from here to the `meta.tag.extension` element. -Next up is the first slice called `parentOrganization`: +It defines a [slicing](https://www.hl7.org/fhir/R4/profiling.html#slicing) for the `Extension.extension` element, meaning we are dealing with a nested extension. The `discriminator` element tells us that slices will be identified by the value of their `url` attribute. A `rules` element with value `open` means other types of slices may be added later on e.g. when creating a profile. We do not have to add any elements from here to the `meta.tag.extension` element. Next up is the first slice called `parentOrganization`: ```xml <StructureDefinition xmlns="http://hl7.org/fhir"> @@ -219,10 +213,7 @@ Next up is the first slice called `parentOrganization`: </StructureDefinition> ``` -The first element defines a slice called `parentOrganization` on the `Extension.extension` element with cardinality `1..1`. -The second element defines the url attribute of the `parentOrganization` slice to be fixed to the value `parent-organization`. -With this information we can add the next element to `meta.tag`. Since it is defined on `Extension.extension` we will add it to -`meta.tag.extension.extension` like this: +The first element defines a slice called `parentOrganization` on the `Extension.extension` element with cardinality `1..1`. The second element defines the url attribute of the `parentOrganization` slice to be fixed to the value `parent-organization`. With this information we can add the next element to `meta.tag`. Since it is defined on `Extension.extension` we will add it to `meta.tag.extension.extension` like this: ```xml <meta> <tag> @@ -237,10 +228,7 @@ With this information we can add the next element to `meta.tag`. Since it is def </meta> ``` -After that, it defines `parentOrganization.value[x]` to occur at least once and have a type of `Identifier`. To turn this into an -element to add to `meta.tag.extension.extension` we have to replace `[x]` with our code in `value[x].type`, which in this case is `Identifier`. It is important -to note, that should the value in the code element be lowercase, you will have make it uppercase before replacement. In our case this means we will have a -`meta.tag.extension.extension.valueIdentifier` element: +After that, it defines `parentOrganization.value[x]` to occur at least once and have a type of `Identifier`. To turn this into an element to add to `meta.tag.extension.extension` we have to replace `[x]` with our code in `value[x].type`, which in this case is `Identifier`. It is important to note, that should the value in the code element be lowercase, you will have make it uppercase before replacement. In our case this means we will have a `meta.tag.extension.extension.valueIdentifier` element: ```xml <meta> <tag> @@ -257,11 +245,7 @@ to note, that should the value in the code element be lowercase, you will have m </meta> ``` -The last two elements define a `system` element with a fixed value and `value` element we can fill in on our own, since it does not have any constraints applied. Notice that -the element definition still uses `value[x].system` and `value[x].value`. The replacement mentioned earlier does not happen in -the element definition, but since `value[x]` is defined to have the type `Identifier` it is inferred that we mean to reference `Identifier.system` -and `Identifier.value`. -We will choose an arbitrary `Idenfier` value, but you should be using an actual organization identifier depending on who you want to allow read access to the resource. +The last two elements define a `system` element with a fixed value and `value` element we can fill in on our own, since it does not have any constraints applied. Notice that the element definition still uses `value[x].system` and `value[x].value`. The replacement mentioned earlier does not happen in the element definition, but since `value[x]` is defined to have the type `Identifier` it is inferred that we mean to reference `Identifier.system` and `Identifier.value`. We will choose an arbitrary `Idenfier` value, but you should be using an actual organization identifier depending on who you want to allow read access to the resource. ```xml <meta> @@ -360,9 +344,7 @@ Instead of `Identifier`, the `value[x]` element is now defined as a `Coding` typ </meta> ``` -A `Coding` has to belong to some [CodeSystem](../concepts/fhir/codesystem.md). The DSF has a CodeSystem called [dsf-organization-role](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/CodeSystem/dsf-organization-role-1.0.0.xml). -Before creating your own CodeSystem, it is worth taking a look at it to see if an appropriate role already exists for your organization. -For demonstration purposes, we will be using the `DIC` role: +A `Coding` has to belong to some [CodeSystem](../concepts/fhir/codesystem.md). The DSF has a CodeSystem called [dsf-organization-role](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/CodeSystem/dsf-organization-role-1.0.0.xml). Before creating your own CodeSystem, it is worth taking a look at it to see if an appropriate role already exists for your organization. For demonstration purposes, we will be using the `DIC` role: ```xml <meta> <tag> @@ -405,8 +387,7 @@ Now we only have two elements left in the `differential` statement: </StructureDefinition> ``` -The `Extension.url` element tells us to add a url attribute to `meta.tag.extension`. The last element makes it so we must not -add a `meta.tag.extension.value[x]` element. This leaves us with this final Read Access Tag: +The `Extension.url` element tells us to add a url attribute to `meta.tag.extension`. The last element makes it so we must not add a `meta.tag.extension.value[x]` element. This leaves us with this final Read Access Tag: ```xml <meta> diff --git a/docs/src/developer-documentation/guides/creating-an-activity-definition.md b/docs/src/developer-documentation/guides/creating-an-activity-definition.md index be8a6ed68..f83c866bf 100644 --- a/docs/src/developer-documentation/guides/creating-an-activity-definition.md +++ b/docs/src/developer-documentation/guides/creating-an-activity-definition.md @@ -14,8 +14,7 @@ It is divided into steps for each of the main components of ActivityDefinitions: *Regular elements* are all elements not part of the first 3 main components. -*We will assume you know how to translate [ElementDefinitions](https://www.hl7.org/fhir/R4/elementdefinition.html) to actual elements in a FHIR resource. -If you do not, you might want to check out the guide on [creating Task resources](../guides/creating-task-resources-based-on-a-definition.md) first.* +*We will assume you know how to translate [ElementDefinitions](https://www.hl7.org/fhir/R4/elementdefinition.html) to actual elements in a FHIR resource. If you do not, you might want to check out the guide on [creating Task resources](../guides/creating-task-resources-based-on-a-definition.md) first.* #### 1. Read Access Tag Let us start out with an empty [ActivityDefinition](../concepts/fhir/activitydefinition.md): @@ -25,9 +24,7 @@ Let us start out with an empty [ActivityDefinition](../concepts/fhir/activitydef </ActivityDefinition> ``` -The first element in DSF FHIR resources is always the [Read Access Tag](../concepts/dsf/read-access-tag.md). It describes who is -allowed to read this resource through the DSF FHIR server's REST API. You can learn more complex configurations of the -[Read Access Tag](../concepts/dsf/read-access-tag.md) in [this guide](../concepts/dsf/read-access-tag.md). In this case, we will allow read access to everyone: +The first element in DSF FHIR resources is always the [Read Access Tag](../concepts/dsf/read-access-tag.md). It describes who is allowed to read this resource through the DSF FHIR server's REST API. You can learn more complex configurations of the [Read Access Tag](../concepts/dsf/read-access-tag.md) in [this guide](../concepts/dsf/read-access-tag.md). In this case, we will allow read access to everyone: ```xml <ActivityDefinition xmlns="http://hl7.org/fhir"> @@ -41,13 +38,7 @@ allowed to read this resource through the DSF FHIR server's REST API. You can le ``` #### 2. Extension: Process Authorization -This part of your ActivityDefinition will tell the DSF who is allowed to request and receive messages ([Task](../concepts/fhir/task.md) resources) -for your BPMN process. If your plugin contains more than one BPMN process, you will have to create one [ActivityDefinition](../concepts/fhir/activitydefinition.md) -for each BPMN process. It is important to note that you need to include authorization rules for **ALL** messages received in your BPMN process. -This includes the message starting your BPMN process initially. -You can find the extension [here](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-extension-process-authorization-1.0.0.xml). -Let us continue by adding the [extension element](http://hl7.org/fhir/R4/extensibility.html#extension) with the correct URL. You can get the -value for the URL from the `Extension.url` element: +This part of your ActivityDefinition will tell the DSF who is allowed to request and receive messages ([Task](../concepts/fhir/task.md) resources) for your BPMN process. If your plugin contains more than one BPMN process, you will have to create one [ActivityDefinition](../concepts/fhir/activitydefinition.md) for each BPMN process. It is important to note that you need to include authorization rules for **ALL** messages received in your BPMN process. This includes the message starting your BPMN process initially. You can find the extension [here](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-extension-process-authorization-1.0.0.xml). Let us continue by adding the [extension element](http://hl7.org/fhir/R4/extensibility.html#extension) with the correct URL. You can get the value for the URL from the `Extension.url` element: ```xml <ActivityDefinition xmlns="http://hl7.org/fhir"> ... @@ -58,8 +49,7 @@ value for the URL from the `Extension.url` element: ``` *Elements not relevant to the current component are hidden with ... to increase readability.* -The [differential](https://www.hl7.org/fhir/R4/profiling.html#snapshot) statement -starts by defining the [slicing](https://www.hl7.org/fhir/R4/profiling.html#snapshot) for the `Extension.extension` element: +The [differential](https://www.hl7.org/fhir/R4/profiling.html#snapshot) statement starts by defining the [slicing](https://www.hl7.org/fhir/R4/profiling.html#snapshot) for the `Extension.extension` element: ```xml <StructureDefinition xmlns="http://hl7.org/fhir"> @@ -84,10 +74,7 @@ starts by defining the [slicing](https://www.hl7.org/fhir/R4/profiling.html#snap </StructureDefinition> ``` -The above states that whenever this extension is used in a profile, the profile needs to include this extension at least once (`<min value="1" />`). -The [slicing](https://www.hl7.org/fhir/R4/profiling.html#snapshot) on `Extension.extension` tells us that elements of this [slicing](https://www.hl7.org/fhir/R4/profiling.html#snapshot) -are identified by the value of their URL (`<discriminator>`), which is always the case for extensions, and that other extensions can be added to the [slicing](https://www.hl7.org/fhir/R4/profiling.html#snapshot) (`<rules value="open" />`). -Since there is a [slicing](https://www.hl7.org/fhir/R4/profiling.html#snapshot) on `Extension.extension`, we are dealing with a nested extension. +The above states that whenever this extension is used in a profile, the profile needs to include this extension at least once (`<min value="1" />`). The [slicing](https://www.hl7.org/fhir/R4/profiling.html#snapshot) on `Extension.extension` tells us that elements of this [slicing](https://www.hl7.org/fhir/R4/profiling.html#snapshot) are identified by the value of their URL (`<discriminator>`), which is always the case for extensions, and that other extensions can be added to the [slicing](https://www.hl7.org/fhir/R4/profiling.html#snapshot) (`<rules value="open" />`). Since there is a [slicing](https://www.hl7.org/fhir/R4/profiling.html#snapshot) on `Extension.extension`, we are dealing with a nested extension. After these initial element definitions come the elements relevant for your process plugin. The first one is the `message-name` slice: ```xml @@ -117,12 +104,7 @@ After these initial element definitions come the elements relevant for your proc </StructureDefinition> ``` -This section tells us that we need to include exactly one extension element from the `message-name` slice in our [ActivityDefinition](../concepts/fhir/activitydefinition.md). -The extension element will have a URL value of `message-name`. If you remember the `discriminator` configuration, this URL value identifies the element to belong to the `message-name` slice on `Extension.extension`. -Lastly, the extension element includes a `valueString` element. In case you are wondering how `value[x]` turned into `valueString`, -FHIR does not allow using `value[x]` as actual element. The value in `value[x]` is always strictly bound to some kind of type. -FHIR uses the `value[x].type.code` value to determine this type and replaces `[x]` with an uppercase version of `element.type.code`. -This results in the following extension element we will add to our [ActivityDefinition](../concepts/fhir/activitydefinition.md): +This section tells us that we need to include exactly one extension element from the `message-name` slice in our [ActivityDefinition](../concepts/fhir/activitydefinition.md). The extension element will have a URL value of `message-name`. If you remember the `discriminator` configuration, this URL value identifies the element to belong to the `message-name` slice on `Extension.extension`. Lastly, the extension element includes a `valueString` element. In case you are wondering how `value[x]` turned into `valueString`, FHIR does not allow using `value[x]` as actual element. The value in `value[x]` is always strictly bound to some kind of type. FHIR uses the `value[x].type.code` value to determine this type and replaces `[x]` with an uppercase version of `element.type.code`. This results in the following extension element we will add to our [ActivityDefinition](../concepts/fhir/activitydefinition.md): ```xml <extension url="message-name"> <valueString value="myMessage"/> @@ -179,11 +161,7 @@ The next slice is called `task-profile`: </StructureDefinition> ``` -This section has almost the same structure as `message-name`. The only difference is the value for `value[x].type.code`. -This means that instead of `valueString`, we will have to use a `valueCanonical` element for `task-profile.value[x]`. -Canonical values referring to [Task](../concepts/fhir/task.md) profiles in ActivityDefinitions have to conform -to the rules outlined by the documentation on [URLs](../concepts/dsf/about-version-placeholders-and-urls.md#urls). -From the definition above, we will create the following extension element and add it to our [ActivityDefinition](../concepts/fhir/activitydefinition.md): +This section has almost the same structure as `message-name`. The only difference is the value for `value[x].type.code`. This means that instead of `valueString`, we will have to use a `valueCanonical` element for `task-profile.value[x]`. Canonical values referring to [Task](../concepts/fhir/task.md) profiles in ActivityDefinitions have to conform to the rules outlined by the documentation on [URLs](../concepts/dsf/about-version-placeholders-and-urls.md#urls). From the definition above, we will create the following extension element and add it to our [ActivityDefinition](../concepts/fhir/activitydefinition.md): ```xml <extension url="task-profile"> <valueCanonical value="http://dsf.dev/fhir/StructureDefinition/my-task|#{version}"/> @@ -252,11 +230,7 @@ The next slice is `requester`: </differential> </StructureDefinition> ``` -Instead of a `string` or `canonical` type for `value[x]` we now have a `Coding` type. See the [FHIR documentation on Codings](https://www.hl7.org/fhir/R4/datatypes.html#Coding) -for more in-depth information. `Codings` are elements which contain, among other things, a `code` and the `system` the code belongs to. In the same way we transformed `value[x]` into `valueString` or `valueCanonical` before, we will also -have to turn `value[x]` into `valueCoding`. To use `Codings` in `valueCoding` elements, they are usually bound to the element through a [ValueSet](../concepts/fhir/valueset.md). This is the -responsibility of the `binding` element. You can also see that `value[x].type.profile` lists a number of profiles. Instead of defining the -elements in the same file, they were defined in different files for better readability. Depending on your use case, you have to pick one of the profiles. +Instead of a `string` or `canonical` type for `value[x]` we now have a `Coding` type. See the [FHIR documentation on Codings](https://www.hl7.org/fhir/R4/datatypes.html#Coding) for more in-depth information. `Codings` are elements which contain, among other things, a `code` and the `system` the code belongs to. In the same way we transformed `value[x]` into `valueString` or `valueCanonical` before, we will also have to turn `value[x]` into `valueCoding`. To use `Codings` in `valueCoding` elements, they are usually bound to the element through a [ValueSet](../concepts/fhir/valueset.md). This is the responsibility of the `binding` element. You can also see that `value[x].type.profile` lists a number of profiles. Instead of defining the elements in the same file, they were defined in different files for better readability. Depending on your use case, you have to pick one of the profiles. Here is what they mean: - `local-all`: All local requests will be allowed. Local requests are identified by matching the requester's certificate to a thumbprint which was internally marked by the DSF FHIR server as belonging to a local organization. - `local-organization`: All local requests made from an organization with a specific `organization-identifier` will be allowed. @@ -266,12 +240,9 @@ Here is what they mean: can be found [here](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/CodeSystem/dsf-practitioner-role-1.0.0.xml). This allows for more granularity when defining authorization rules within an organization and can be integrated into local user management via [OpenID Connect](https://dsf.dev/stable/maintain/fhir/access-control.html). -As you can see, there are no `practitioner` versions of `remote` authorization rules. From the perspective of the receiving DSF instance, -remote requests are always issued by an organization. They do not hold any information about the local user management of the requesting organization. -You can also find examples of all Codings from above [here](../concepts/dsf/examples-for-requester-and-recipient-elements.md). +As you can see, there are no `practitioner` versions of `remote` authorization rules. From the perspective of the receiving DSF instance, remote requests are always issued by an organization. They do not hold any information about the local user management of the requesting organization. You can also find examples of all Codings from above [here](../concepts/dsf/examples-for-requester-and-recipient-elements.md). -It is also good to keep in mind that you are allowed to add any number of `requester` elements into your [ActivityDefinition](../concepts/fhir/activitydefinition.md). -Let us start out by adding a `requester` element like we did for previous elements: +It is also good to keep in mind that you are allowed to add any number of `requester` elements into your [ActivityDefinition](../concepts/fhir/activitydefinition.md). Let us start out by adding a `requester` element like we did for previous elements: ```xml <extension url="requester"> @@ -281,9 +252,7 @@ Let us start out by adding a `requester` element like we did for previous elemen </extension> ``` -We now have to look at the elements that are defined in one of the profiles to fill in the remaining elements since they are not defined by the `requester` extension. For demonstration -purposes, we will choose the [dsf-coding-process-authorization-local-organization-practitioner](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-coding-process-authorization-local-organization-practitioner-1.0.0.xml) profile. -Since all elements listed in the [Coding definition](https://www.hl7.org/fhir/R4/datatypes.html#codesystem) are optional, we only have to look at the `differential` element from the profile we just selected: +We now have to look at the elements that are defined in one of the profiles to fill in the remaining elements since they are not defined by the `requester` extension. For demonstration purposes, we will choose the [dsf-coding-process-authorization-local-organization-practitioner](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-coding-process-authorization-local-organization-practitioner-1.0.0.xml) profile. Since all elements listed in the [Coding definition](https://www.hl7.org/fhir/R4/datatypes.html#codesystem) are optional, we only have to look at the `differential` element from the profile we just selected: <a id="coding-differential"></a> ```xml <differential> @@ -319,9 +288,7 @@ Since all elements listed in the [Coding definition](https://www.hl7.org/fhir/R4 </element> </differential> ``` -It defines an extension called `organization-practitioner` which is identified through its url attribute. Again, the extension -is only referenced, its location is in a different file. You can find it [here](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-extension-process-authorization-organization-practitioner-1.0.0.xml). -Let us look at its `differential` element in the extension file to see how we need to populate the extension: +It defines an extension called `organization-practitioner` which is identified through its url attribute. Again, the extension is only referenced, its location is in a different file. You can find it [here](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-extension-process-authorization-organization-practitioner-1.0.0.xml). Let us look at its `differential` element in the extension file to see how we need to populate the extension: ```xml <differential> <element id="Extension"> @@ -401,9 +368,7 @@ Let us look at its `differential` element in the extension file to see how we ne </differential> ``` -This extension does not reference any other files. This means we reached the "deepest" level. So now we can start working our way back up again from here, by translating this -definition into actual extension elements, then inserting it into the Coding we selected, translating the rest of the element -definitions from the Coding resource and adding everything to our [ActivityDefinition](../concepts/fhir/activitydefinition.md). +This extension does not reference any other files. This means we reached the "deepest" level. So now we can start working our way back up again from here, by translating this definition into actual extension elements, then inserting it into the Coding we selected, translating the rest of the element definitions from the Coding resource and adding everything to our [ActivityDefinition](../concepts/fhir/activitydefinition.md). We will start with the `Extension.url` element, since the `Extension` element is the parent element for all slices on the `Extension.extension` elements: ```xml @@ -442,11 +407,7 @@ Finally, we will add the `practitionerRole` slice: </extension> ``` -Notice that there is no `binding` element specified for `practitionerRole.value[x]`. This is intentional. In the example we used a code from the -[dsf-practitioner-role](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/CodeSystem/dsf-practitioner-role-1.0.0.xml) CodeSystem. -This CodeSystem includes a standard set of codes which are often sufficient for DSF use cases. You can freely add other CodeSystems if you find these codes -do not apply for your use case. The code you set here can be used in the [DSF role config](https://dsf.dev/stable/maintain/fhir/access-control.html) -to allow certain users with this `practitioner-role` to send requests. +Notice that there is no `binding` element specified for `practitionerRole.value[x]`. This is intentional. In the example we used a code from the [dsf-practitioner-role](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/CodeSystem/dsf-practitioner-role-1.0.0.xml) CodeSystem. This CodeSystem includes a standard set of codes which are often sufficient for DSF use cases. You can freely add other CodeSystems if you find these codes do not apply for your use case. The code you set here can be used in the [DSF role config](https://dsf.dev/stable/maintain/fhir/access-control.html) to allow certain users with this `practitioner-role` to send requests. Working our way back up to the Coding we selected, we will now add the extension we just created as the `Coding.extension:organization-practitioner` element: ```xml @@ -469,8 +430,7 @@ Working our way back up to the Coding we selected, we will now add the extension </valueCoding> </extension> ``` -Now might be a good time to look at the [differential](#coding-differential) from the Coding again. -Our next elements to be added are `Coding.system` and `Coding.code`: +Now might be a good time to look at the [differential](#coding-differential) from the Coding again. Our next elements to be added are `Coding.system` and `Coding.code`: ```xml <extension url="requester"> <valueCoding> @@ -493,8 +453,7 @@ Our next elements to be added are `Coding.system` and `Coding.code`: </valueCoding> </extension> ``` -Now we are finished with the `requester` extension and can add it to our [ActivityDefinition](../concepts/fhir/activitydefinition.md) under -the [dsf-extension-process-authorization](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-extension-process-authorization-1.0.0.xml). +Now we are finished with the `requester` extension and can add it to our [ActivityDefinition](../concepts/fhir/activitydefinition.md) under the [dsf-extension-process-authorization](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-extension-process-authorization-1.0.0.xml). <details> <summary>This is how your ActivityDefinition should look like so far</summary> @@ -539,8 +498,7 @@ the [dsf-extension-process-authorization](https://github.com/datasharingframewor ``` </details> -Now we are back to looking at the [dsf-extension-process-authorization](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-extension-process-authorization-1.0.0.xml) again. -The last slice for this extension is `recipient`: +Now we are back to looking at the [dsf-extension-process-authorization](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-extension-process-authorization-1.0.0.xml) again. The last slice for this extension is `recipient`: ```xml <StructureDefinition xmlns="http://hl7.org/fhir"> ... @@ -574,13 +532,7 @@ The last slice for this extension is `recipient`: </StructureDefinition> ``` -The `recipient` will decide which DSF instance is allowed to process that message. That is the reason why you will not find any Codings for `remote` or `practitioner` here. -For `requester`, we already decided that we will only allow users with a certain role from our own (local) organization to send this message. -So now we will only allow the DSF instance run by that same local organization to process the message. The right Coding for this job is -the [coding-process-authorization-local-organization](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-coding-process-authorization-local-organization-1.0.0.xml). -The configuration of a local requester and local receiver is often used for the message that starts up the first BPMN process of the plugin. -The process of adding the `recipient` slice is the exact same as it is for `requester`. You can follow the steps for the `requester` slice again -but just use a different Coding. +The `recipient` will decide which DSF instance is allowed to process that message. That is the reason why you will not find any Codings for `remote` or `practitioner` here. For `requester`, we already decided that we will only allow users with a certain role from our own (local) organization to send this message. So now we will only allow the DSF instance run by that same local organization to process the message. The right Coding for this job is the [coding-process-authorization-local-organization](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-coding-process-authorization-local-organization-1.0.0.xml). The configuration of a local requester and local receiver is often used for the message that starts up the first BPMN process of the plugin. The process of adding the `recipient` slice is the exact same as it is for `requester`. You can follow the steps for the `requester` slice again but just use a different Coding. <details> <summary>Using the Coding we just decided on, this is how your ActivityDefinition should look like</summary> @@ -637,13 +589,11 @@ but just use a different Coding. ``` </details> -The last element defined in the [process authorization extension](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-extension-process-authorization-1.0.0.xml) -is `Extension.url`. But since we added this element at the very beginning of the working through the extension, we are finished with it here. +The last element defined in the [process authorization extension](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-extension-process-authorization-1.0.0.xml) is `Extension.url`. But since we added this element at the very beginning of the working through the extension, we are finished with it here. #### 3. BPE Managed Elements -Some elements of [ActivityDefinitions](../concepts/fhir/activitydefinition.md) are managed by the DSF BPE and replaced with certain values -at appropriate times. +Some elements of [ActivityDefinitions](../concepts/fhir/activitydefinition.md) are managed by the DSF BPE and replaced with certain values at appropriate times. The following elements are managed by the DSF BPE: - `ActivityDefinition.version` should use the [placeholder](../concepts/dsf/about-version-placeholders-and-urls.md#placeholders) `#{version}` @@ -713,9 +663,7 @@ The following elements are managed by the DSF BPE: #### 4. Regular Elements -The only required elements in this set are `ActivityDefinition.url` and `ActivityDefinition.kind`. -Check out the documentation on [URLs](../concepts/dsf/about-version-placeholders-and-urls.md#urls) on how to choose the correct value for `ActivityDefinition.url`. `ActivityDefinition.kind` -must have the value `Task`. +The only required elements in this set are `ActivityDefinition.url` and `ActivityDefinition.kind`. Check out the documentation on [URLs](../concepts/dsf/about-version-placeholders-and-urls.md#urls) on how to choose the correct value for `ActivityDefinition.url`. `ActivityDefinition.kind` must have the value `Task`. All other elements can technically be omitted. Still, we recommend you include the following elements: - `AcitivityDefinition.name` - `AcitivityDefinition.title` diff --git a/docs/src/developer-documentation/guides/creating-codesystems-for-dsf-processes.md b/docs/src/developer-documentation/guides/creating-codesystems-for-dsf-processes.md index 20b240875..d939acc41 100644 --- a/docs/src/developer-documentation/guides/creating-codesystems-for-dsf-processes.md +++ b/docs/src/developer-documentation/guides/creating-codesystems-for-dsf-processes.md @@ -5,10 +5,7 @@ icon: creative ### Creating CodeSystems for DSF Processes -You might find yourself in a situation where you need to create a [CodeSystem](../concepts/fhir/codesystem.md). -For example, when defining the type of an [Input Parameter](../concepts/fhir/task.md#task-input-parameters). -[CodeSystems](../concepts/fhir/codesystem.md) for the DSF differ from regular [CodeSystems](../concepts/fhir/codesystem.md) -in that some element's values are managed by the DSF BPE server. You can use the following XML as a template: +You might find yourself in a situation where you need to create a [CodeSystem](../concepts/fhir/codesystem.md). For example, when defining the type of an [Input Parameter](../concepts/fhir/task.md#task-input-parameters). [CodeSystems](../concepts/fhir/codesystem.md) for the DSF differ from regular [CodeSystems](../concepts/fhir/codesystem.md) in that some element's values are managed by the DSF BPE server. You can use the following XML as a template: ```xml <CodeSystem xmlns="http://hl7.org/fhir"> <meta> @@ -40,8 +37,6 @@ in that some element's values are managed by the DSF BPE server. You can use the </concept> </CodeSystem> ``` -Replace dummy values with appropriate values of your own. Do not change elements managed by the DSF BPE server. -You can add as many codes as you like by defining more `concept` elements. +Replace dummy values with appropriate values of your own. Do not change elements managed by the DSF BPE server. You can add as many codes as you like by defining more `concept` elements. -The DSF BPE server will read your [CodeSystem](../concepts/fhir/codesystem.md) from -`tutorial-process/src/main/resources/fhir/CodeSystem`. \ No newline at end of file +The DSF BPE server will read your [CodeSystem](../concepts/fhir/codesystem.md) from `tutorial-process/src/main/resources/fhir/CodeSystem`. \ No newline at end of file diff --git a/docs/src/developer-documentation/guides/creating-task-resources-based-on-a-definition.md b/docs/src/developer-documentation/guides/creating-task-resources-based-on-a-definition.md index 16ccbddd1..220b519dd 100644 --- a/docs/src/developer-documentation/guides/creating-task-resources-based-on-a-definition.md +++ b/docs/src/developer-documentation/guides/creating-task-resources-based-on-a-definition.md @@ -5,49 +5,25 @@ icon: creative ### Creating Task Resources Based on a Definition -This short guide should help you understand how you can create [Task](../concepts/fhir/task.md) -resources for use in [Starting A Process Via Task Resources](../guides/starting-a-process-via-task-resources.md). -We will employ the use of the free version of [Forge](https://simplifier.net/forge?utm_source=firely-forge) to help -with visualization. You are invited to create a free account and follow along, but we will include screenshots of relevant -views either way. Remember that the free version of Forge [must not be used commercially](https://simplifier.net/pricing). -As an example, we will create a [Task](../concepts/fhir/task.md) resource from the `task-start-dic-process.xml` profile. +This short guide should help you understand how you can create [Task](../concepts/fhir/task.md) resources for use in [Starting A Process Via Task Resources](../guides/starting-a-process-via-task-resources.md). We will employ the use of the free version of [Forge](https://simplifier.net/forge?utm_source=firely-forge) to help with visualization. You are invited to create a free account and follow along, but we will include screenshots of relevant views either way. Remember that the free version of Forge [must not be used commercially](https://simplifier.net/pricing). As an example, we will create a [Task](../concepts/fhir/task.md) resource from the `task-start-dic-process.xml` profile. #### 1st Step: Removing Placeholders -`task-start-dic-process.xml` includes placeholders for the `version` and `date` elements. For the duration of this guide, -you can either remove or comment these elements, so Forge does not try to perform type checking on them, which -would result in an error and Forge not loading the file. +`task-start-dic-process.xml` includes placeholders for the `version` and `date` elements. For the duration of this guide, you can either remove or comment these elements, so Forge does not try to perform type checking on them, which would result in an error and Forge not loading the file. #### 2nd Step: Differential Chain -If the resource profile is only available as a [differential](https://www.hl7.org/fhir/R4/profiling.html#snapshot), like in our -case, we will want to aggregate the changes made to the base resource (in this case [Task](../concepts/fhir/task.md)) by all profiles to make -it more readable. -To do this, we first need all the profiles involved. We already have `task-start-dic-process.xml` in our `StructureDefinition` folder. -It lists a resource called `task-base` in its `baseDefinition` element. This resource is part of the DSF and can be -found [here](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-task-base-1.0.0.xml). -Put it into the `StructureDefinition` folder. Since `task-base` has the original FHIR Task as its `baseDefinition` -element, we are done with this chain. -In forge, you should now be able to open the `StructureDefinition` folder and select the `task-start-dic-process.xml` profile. -It should look something like this: +If the resource profile is only available as a [differential](https://www.hl7.org/fhir/R4/profiling.html#snapshot), like in our case, we will want to aggregate the changes made to the base resource (in this case [Task](../concepts/fhir/task.md)) by all profiles to make it more readable. To do this, we first need all the profiles involved. We already have `task-start-dic-process.xml` in our `StructureDefinition` folder. It lists a resource called `task-base` in its `baseDefinition` element. This resource is part of the DSF and can be found [here](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-task-base-1.0.0.xml). Put it into the `StructureDefinition` folder. Since `task-base` has the original FHIR Task as its `baseDefinition` element, we are done with this chain. In forge, you should now be able to open the `StructureDefinition` folder and select the `task-start-dic-process.xml` profile. It should look something like this: ![Forge overview](/photos/developer-documentation/forge_overview.png) #### 3rd Step: Building the Task Resource -We will now go through each element one by one and include it into our [Task](../concepts/fhir/task.md) -resource, provided it is mandatory (cardinality at least `1..1`) according to the profile. It is important -that you not use any placeholders like `#{version}` for resources not read by the DSF BPE server. This is the case -if we want a [Task](../concepts/fhir/task.md) resource for use with [cURL](../guides/starting-a-process-via-task-resources.md#using-curl). -But, placeholders should be used in [Draft Task Resources](../concepts/dsf/draft-task-resources.md) instead of actual values wherever possible, -since those are read by the DSF BPE server. This guide will create a [Task](../concepts/fhir/task.md) resource without placeholders. -We will start out with the base element for all [Task](../concepts/fhir/task.md) resources: +We will now go through each element one by one and include it into our [Task](../concepts/fhir/task.md) resource, provided it is mandatory (cardinality at least `1..1`) according to the profile. It is important that you not use any placeholders like `#{version}` for resources not read by the DSF BPE server. This is the case if we want a [Task](../concepts/fhir/task.md) resource for use with [cURL](../guides/starting-a-process-via-task-resources.md#using-curl). But, placeholders should be used in [Draft Task Resources](../concepts/dsf/draft-task-resources.md) instead of actual values wherever possible, since those are read by the DSF BPE server. This guide will create a [Task](../concepts/fhir/task.md) resource without placeholders. We will start out with the base element for all [Task](../concepts/fhir/task.md) resources: ```xml <Task xmlns="http://hl7.org/fhir"> </Task> ``` -Before we start adding any elements listed in Forge's element tree, we have to include the `Task.meta.profile` element. -Its requirement cannot be seen here which is why we mention it specifically. This is the only instance you will not see -it in the element tree. It should look like this: +Before we start adding any elements listed in Forge's element tree, we have to include the `Task.meta.profile` element. Its requirement cannot be seen here which is why we mention it specifically. This is the only instance you will not see it in the element tree. It should look like this: ```xml <Task xmlns="http://hl7.org/fhir"> <meta> @@ -56,8 +32,7 @@ it in the element tree. It should look like this: </Task> ``` -The first element which can be found in the element tree is the `instantiatesCanonical` element. To add it, we -will create an XML element with the same name and the value according to [URLs](../concepts/dsf/about-version-placeholders-and-urls.md#urls): +The first element which can be found in the element tree is the `instantiatesCanonical` element. To add it, we will create an XML element with the same name and the value according to [URLs](../concepts/dsf/about-version-placeholders-and-urls.md#urls): ```xml <Task xmlns="http://hl7.org/fhir"> <meta> @@ -66,8 +41,7 @@ will create an XML element with the same name and the value according to [URLs]( <instantiatesCanonical value="http://dsf.dev/bpe/Process/dicProcess|1.0" /> </Task> ``` -We can continue this process for all primitive elements like these. Just make sure you pay attention to use the correct -data type (e.g. proper coding value for elements with `coding` type). +We can continue this process for all primitive elements like these. Just make sure you pay attention to use the correct data type (e.g. proper coding value for elements with `coding` type). By now your [Task](../concepts/fhir/task.md) resources should look something like this: <details> @@ -142,13 +116,9 @@ Next, we will add the `identifier` element and its primitive sub-elements just l </requester> </Task> ``` -*Notice that `requester.identifier.system` has a `Fixed value` annotation. You can see what the value is supposed -to be by clicking on the `system` element in Forge or looking at the XML for the right Task profile. The right side will have all information about that element, including -the actual value for `Fixed value`.* +*Notice that `requester.identifier.system` has a `Fixed value` annotation. You can see what the value is supposed to be by clicking on the `system` element in Forge or looking at the XML for the right Task profile. The right side will have all information about that element, including the actual value for `Fixed value`.* -You should now be able to fill out all elements in your [Task](../concepts/fhir/task.md) resource until you reach -the [slicing](https://www.hl7.org/fhir/R4/profiling.html#slicing) for `Task.input`. Your [Task](../concepts/fhir/task.md) -resource should look something like this: +You should now be able to fill out all elements in your [Task](../concepts/fhir/task.md) resource until you reach the [slicing](https://www.hl7.org/fhir/R4/profiling.html#slicing) for `Task.input`. Your [Task](../concepts/fhir/task.md) resource should look something like this: <details> <summary>Suggested solution</summary> @@ -182,13 +152,11 @@ resource should look something like this: </details> -[Slicings](https://www.hl7.org/fhir/R4/profiling.html#slicing) are a bit different from regular elements. Let us look at the -slice `message-name`: +[Slicings](https://www.hl7.org/fhir/R4/profiling.html#slicing) are a bit different from regular elements. Let us look at the slice `message-name`: ![Forge slice message name](/photos/developer-documentation/forge_slice_message_name.png) -If we were to continue including slices to the [Task](../concepts/fhir/task.md) resource like we did so far, -we would add a `message-name` element to our XML like this: +If we were to continue including slices to the [Task](../concepts/fhir/task.md) resource like we did so far, we would add a `message-name` element to our XML like this: ```xml <Task xmlns="http://hl7.org/fhir"> @@ -201,14 +169,7 @@ we would add a `message-name` element to our XML like this: </Task> ``` -This approach however, would not work. FHIR processors do not use the name of the slice to map entries in -your [Task](../concepts/fhir/task.md) resource to the correct slice. They use [discriminators](https://www.hl7.org/fhir/R4/profiling.html#discriminator). -Discriminators define the elements a processor needs to distinguish slices by. You can see -how the discriminator is configured by selecting the `input` element in Forge. In our case, a processor -would look at the values for `input.type.coding.system` and `input.type.coding.code` to determine which -slice this element belongs to. This only works because `input.type.coding.system` and `input.type.coding.code` -are present in all slices and have a `Fixed value`. You can learn more about discriminators [here](https://www.hl7.org/fhir/R4/profiling.html#discriminator). -All this means is that we effectively ignore the name of the slice as an element and start adding elements like we did before: +This approach however, would not work. FHIR processors do not use the name of the slice to map entries in your [Task](../concepts/fhir/task.md) resource to the correct slice. They use [discriminators](https://www.hl7.org/fhir/R4/profiling.html#discriminator). Discriminators define the elements a processor needs to distinguish slices by. You can see how the discriminator is configured by selecting the `input` element in Forge. In our case, a processor would look at the values for `input.type.coding.system` and `input.type.coding.code` to determine which slice this element belongs to. This only works because `input.type.coding.system` and `input.type.coding.code` are present in all slices and have a `Fixed value`. You can learn more about discriminators [here](https://www.hl7.org/fhir/R4/profiling.html#discriminator). All this means is that we effectively ignore the name of the slice as an element and start adding elements like we did before: ```xml <Task xmlns="http://hl7.org/fhir"> @@ -225,8 +186,7 @@ All this means is that we effectively ignore the name of the slice as an element </Task> ``` -Now you should be able to add all remaining mandatory elements to your [Task](../concepts/fhir/task.md) -resource on your own. In the end, it should look something like this: +Now you should be able to add all remaining mandatory elements to your [Task](../concepts/fhir/task.md) resource on your own. In the end, it should look something like this: <details> <summary>Suggested solution</summary> diff --git a/docs/src/developer-documentation/guides/creating-valuesets-for-dsf-processes.md b/docs/src/developer-documentation/guides/creating-valuesets-for-dsf-processes.md index b22e0e018..3e9398d41 100644 --- a/docs/src/developer-documentation/guides/creating-valuesets-for-dsf-processes.md +++ b/docs/src/developer-documentation/guides/creating-valuesets-for-dsf-processes.md @@ -5,12 +5,7 @@ icon: creative ### Creating ValueSets for DSF Processes -You might find yourself in the situation where you need to create a [ValueSet](../concepts/fhir/valueset.md). -For example, when adding [Input Parameters](../concepts/fhir/task.md#task-input-parameters) to DSF [Task](../concepts/fhir/task.md) -resources, you will also have to reference a [ValueSet](../concepts/fhir/valueset.md) resource in your -binding for `Task.input.type` to be able to set the type of your [Input Parameter](../concepts/fhir/task.md#task-input-parameters). -[ValueSets](../concepts/fhir/valueset.md) for the DSF differ from regular [ValueSets](../concepts/fhir/valueset.md) -in that some element's values are managed by the DSF BPE server. You can use the following template for your +You might find yourself in the situation where you need to create a [ValueSet](../concepts/fhir/valueset.md). For example, when adding [Input Parameters](../concepts/fhir/task.md#task-input-parameters) to DSF [Task](../concepts/fhir/task.md) resources, you will also have to reference a [ValueSet](../concepts/fhir/valueset.md) resource in your binding for `Task.input.type` to be able to set the type of your [Input Parameter](../concepts/fhir/task.md#task-input-parameters). [ValueSets](../concepts/fhir/valueset.md) for the DSF differ from regular [ValueSets](../concepts/fhir/valueset.md) in that some element's values are managed by the DSF BPE server. You can use the following template for your [ValueSet](../concepts/fhir/valueset.md): ```xml <ValueSet xmlns="http://hl7.org/fhir"> @@ -41,11 +36,7 @@ in that some element's values are managed by the DSF BPE server. You can use the </compose> </ValueSet> ``` -Replace dummy values with appropriate values of your own. Do not change elements managed by the DSF BPE server. -The `compose` element defines the codes included in this [ValueSet](../concepts/fhir/valueset.md). -It holds at least one `include` element. Each `include` element refers to a [CodeSystem](../concepts/fhir/codesystem.md) -and contains a list of `concept` elements which in turn contain the actual `code` element. -Using one code from `my-code-system` and one code from `my-other-code-system` would result in the following `compose` element: +Replace dummy values with appropriate values of your own. Do not change elements managed by the DSF BPE server. The `compose` element defines the codes included in this [ValueSet](../concepts/fhir/valueset.md). It holds at least one `include` element. Each `include` element refers to a [CodeSystem](../concepts/fhir/codesystem.md) and contains a list of `concept` elements which in turn contain the actual `code` element. Using one code from `my-code-system` and one code from `my-other-code-system` would result in the following `compose` element: ```xml <ValueSet xmlns="http://hl7.org/fhir"> ... @@ -67,8 +58,6 @@ Using one code from `my-code-system` and one code from `my-other-code-system` wo </compose> </ValueSet> ``` -The DSF BPE server will read your [ValueSet](../concepts/fhir/valueset.md) from -`tutorial-process/src/main/resources/fhir/ValueSet`. +The DSF BPE server will read your [ValueSet](../concepts/fhir/valueset.md) from `tutorial-process/src/main/resources/fhir/ValueSet`. -You might also want to check out [this guide](../guides/creating-codesystems-for-dsf-processes.md) -on how to create [CodeSystems](../concepts/fhir/codesystem.md). \ No newline at end of file +You might also want to check out [this guide](../guides/creating-codesystems-for-dsf-processes.md) on how to create [CodeSystems](../concepts/fhir/codesystem.md). \ No newline at end of file diff --git a/docs/src/developer-documentation/guides/managing-mutiple-incoming-messages-and-missing-messages.md b/docs/src/developer-documentation/guides/managing-mutiple-incoming-messages-and-missing-messages.md index 6a6c089ab..4a6f3a08d 100644 --- a/docs/src/developer-documentation/guides/managing-mutiple-incoming-messages-and-missing-messages.md +++ b/docs/src/developer-documentation/guides/managing-mutiple-incoming-messages-and-missing-messages.md @@ -5,17 +5,11 @@ icon: creative ### Managing Multiple Incoming Messages and Missing Messages -If an already running process instance is waiting for a message from another organization, the corresponding FHIR [Task](../concepts/fhir/task.md) may never arrive. -Either because the other organization decides to never send the message or because some technical problem prohibits the [Task](../concepts/fhir/task.md) resource from being posted to the DSF FHIR server. -This would result in stale process instances that never finish. +If an already running process instance is waiting for a message from another organization, the corresponding FHIR [Task](../concepts/fhir/task.md) may never arrive. Either because the other organization decides to never send the message or because some technical problem prohibits the [Task](../concepts/fhir/task.md) resource from being posted to the DSF FHIR server. This would result in stale process instances that never finish. At the same time, you might also expect to receive one out of a number of different message types at once. -In order to solve both problems we can add an [Event Based Gateway](../concepts/bpmn/gateways.md#event-based-gateway) to the process waiting -for a response and then either handle a [Task](../concepts/fhir/task.md) resource with the response and finish the process in a success -state or trigger a [Timer Intermediate Catching Event](../concepts/bpmn/timer-intermediate-catching-events.md) after a defined wait period and finish the process in an error state. -The following BPMN collaboration diagram shows how the process at the first organization would look like if we wanted to react to multiple different messages -or missing messages: +In order to solve both problems we can add an [Event Based Gateway](../concepts/bpmn/gateways.md#event-based-gateway) to the process waiting for a response and then either handle a [Task](../concepts/fhir/task.md) resource with the response and finish the process in a success state or trigger a [Timer Intermediate Catching Event](../concepts/bpmn/timer-intermediate-catching-events.md) after a defined wait period and finish the process in an error state. The following BPMN collaboration diagram shows how the process at the first organization would look like if we wanted to react to multiple different messages or missing messages: <picture> <source media="(prefers-color-scheme: dark)" srcset="/photos/developer-documentation/exercise5_event_based_gateway_inverted.svg"> diff --git a/docs/src/developer-documentation/guides/setting-targets-for-message-events.md b/docs/src/developer-documentation/guides/setting-targets-for-message-events.md index 7b6490a42..d3d3961ee 100644 --- a/docs/src/developer-documentation/guides/setting-targets-for-message-events.md +++ b/docs/src/developer-documentation/guides/setting-targets-for-message-events.md @@ -5,15 +5,10 @@ icon: creative ### Setting Targets for Message Events -Setting a target for a message event requires a `Target` object. To create one, you require a target's organization identifier, endpoint identifier and endpoint address. -You can find these values by visiting the DSF FHIR server's web interface. In the top right corner, click -the `Show Bookmarks` button, then select `Endpoint`. You will be taken to a list of all Endpoints available to the FHIR server. -There are two ways of adding `targets` to the BPMN execution variables: +Setting a target for a message event requires a `Target` object. To create one, you require a target's organization identifier, endpoint identifier and endpoint address. You can find these values by visiting the DSF FHIR server's web interface. In the top right corner, click the `Show Bookmarks` button, then select `Endpoint`. You will be taken to a list of all Endpoints available to the FHIR server. There are two ways of adding `targets` to the BPMN execution variables: #### 1. Adding the target in the message event implementation -In your message event implementation (the class extending `AbstractTaskMessageSend`), you can override `AbstractTaskMessageSend#doExecute`, -add your targets and then call the super-method. +In your message event implementation (the class extending `AbstractTaskMessageSend`), you can override `AbstractTaskMessageSend#doExecute`, add your targets and then call the super-method. #### 2. Adding the target in a service task right before the message event -This is the preferred method of this tutorial but both methods will work perfectly fine. For our use cases, we usually prefer this one -since there is enough complexity to warrant putting it into a separate BPMN [Service Task](../concepts/bpmn/service-tasks.md). +This is the preferred method of this tutorial but both methods will work perfectly fine. For our use cases, we usually prefer this one since there is enough complexity to warrant putting it into a separate BPMN [Service Task](../concepts/bpmn/service-tasks.md). In both cases you can access methods to create and set `targets` through the `Variables` instance. diff --git a/docs/src/developer-documentation/guides/starting-a-process-via-task-resources.md b/docs/src/developer-documentation/guides/starting-a-process-via-task-resources.md index 6bcd9db67..c16336561 100644 --- a/docs/src/developer-documentation/guides/starting-a-process-via-task-resources.md +++ b/docs/src/developer-documentation/guides/starting-a-process-via-task-resources.md @@ -5,30 +5,16 @@ icon: creative ### Starting a Process via Task Resources -To start a BPMN process, you need to create new a [Task](../concepts/fhir/task.md) resource in the DSF FHIR server -by sending an HTTP request according to the [FHIR RESTful API](https://www.hl7.org/fhir/R4/http.html). Specifically, you need to [create](https://www.hl7.org/fhir/R4/http.html#create) -a resource for the first time. Also, remember that the [Task](../concepts/fhir/task.md) -resource you are sending needs to comply to the [Task](../concepts/fhir/task.md) profile of the process you -want to start and the [ActivityDefinition's](../concepts/fhir/activitydefinition.md) authorization rules. +To start a BPMN process, you need to create new a [Task](../concepts/fhir/task.md) resource in the DSF FHIR server by sending an HTTP request according to the [FHIR RESTful API](https://www.hl7.org/fhir/R4/http.html). Specifically, you need to [create](https://www.hl7.org/fhir/R4/http.html#create) +a resource for the first time. Also, remember that the [Task](../concepts/fhir/task.md) resource you are sending needs to comply to the [Task](../concepts/fhir/task.md) profile of the process you want to start and the [ActivityDefinition's](../concepts/fhir/activitydefinition.md) authorization rules. There are two major ways of making this HTTP request: 1. Using cURL 2. Using the DSF FHIR server's web interface #### Using cURL -Using cURL probably isn't as "pretty", -but since cURL requires the actual [Task](../concepts/fhir/task.md) payload as an XML, it will prove useful to -gain more insight in how actual [Task](../concepts/fhir/task.md) resources look like and how they relate to -your [Task](../concepts/fhir/task.md) profiles and [ActivityDefinitions](../concepts/fhir/activitydefinition.md). You will have to create -an appropriate [Task](../concepts/fhir/task.md) resource for this. -There already is a file called `example-task.xml` located in `tutorial-process/src/main/resources/fhir`. -You can use this as your starting point. You can try to follow [this guide](../guides/creating-task-resources-based-on-a-definition.md), -or you can check the solution branches for this -file if you need ideas on how to fill it out properly. +In order to use cURL, you will have to create an appropriate [Task](../concepts/fhir/task.md) resource to post to the DSF FHIR server. There already is a file called `example-task.xml` located in `tutorial-process/src/main/resources/fhir`. You can use this as your starting point. You can try to follow [this guide](../guides/creating-task-resources-based-on-a-definition.md), or you can check the solution branches for this file if you need ideas on how to fill it out properly. -Below are some cURL command skeletons. Replace all <>-Placeholders with appropriate values. Host name depends on the -instance you want to address. For this tutorial this is either one of `dic`, `cos` or `hrp`. [Certificates](../concepts/dsf/certificates.md) can be found in -`test-data-generator/cert`. Client [certificates](../concepts/dsf/certificates.md) and private keys can be found -in the folder of their respective instance e.g. `test-data-generator/cert/dic-client` for the `dic` instance. +Below are some cURL command skeletons. Replace all <>-Placeholders with appropriate values. Host name depends on the instance you want to address. ##### Linux: ```shell @@ -50,24 +36,8 @@ curl https://<instance-host-name>/fhir/Task ^ -H "Accept: application/fhir+xml" ^ -d @<path/to/example-task.xml> ``` -*This may throw an error depending on which version of cURL Windows is using. If this is the case for you after making sure -you entered everything correctly, you can try using Git's version of cURL instead by adding it to the very top of your system's PATH environment -variable. Git's cURL is usually situated in C:\Program Files\Git\mingw64\bin.* +*This may throw an error depending on which version of cURL Windows is using. If this is the case for you after making sure you entered everything correctly, you can try using Git's version of cURL instead by adding it to the very top of your system's PATH environment variable. Git's cURL is usually situated in C:\Program Files\Git\mingw64\bin.* #### Using the DSF FHIR Server's Web Interface -When visiting the web interface of a DSF FHIR server instance (e.g. https://instance-name/fhir), you -can query the DSF FHIR server using the [FHIR RESTful API](https://www.hl7.org/fhir/R4/http.html) to return a list of all [Draft Task Resources](../concepts/dsf/draft-task-resources.md). -These [Task](../concepts/fhir/task.md) resources act like a template you can use to -instantiate [Task](../concepts/fhir/task.md) resources which start BPMN processes. -Instead of querying the DSF FHIR server manually, you can use a predefined bookmark -to navigate to the query URL. You can find a list of Bookmarks in the top right corner of -the web interface. Simply select the bookmark referencing `?_sort=_profile,identifier&status=draft` under -the `Task` section, and you will be taken to the list of all [Draft Task Resources](../concepts/dsf/draft-task-resources.md). -Once there, you can select the one which starts your BPMN process. It will take you to a detailed view -of the resource where you will also have the chance to fill any [Task Input Parameters](../concepts/fhir/task.md#task-input-parameters) -you might need to specify. -If everything is filled out correctly, you may start your process by clicking `Start Process`. -Keep in mind that, for [Draft Task Resources](../concepts/dsf/draft-task-resources.md) to be -available, you need to include them in your mapping for your BPMN process ID in `ProcessPluginDefinition#getFhirResourcesByProcessId`. -Take a look at [the Process Plugin Definition](../concepts/dsf/the-process-plugin-definition.md) if you need a reminder. \ No newline at end of file +When visiting the web interface of a DSF FHIR server instance (e.g. https://instance-name/fhir), you can query the DSF FHIR server using the [FHIR RESTful API](https://www.hl7.org/fhir/R4/http.html) to return a list of all [Draft Task Resources](../concepts/dsf/draft-task-resources.md). These [Task](../concepts/fhir/task.md) resources act like a template you can use to instantiate [Task](../concepts/fhir/task.md) resources which start BPMN processes. Instead of querying the DSF FHIR server manually, you can use a predefined bookmark to navigate to the query URL. You can find a list of Bookmarks in the top right corner of the web interface. Simply select the bookmark referencing `?_sort=_profile,identifier&status=draft` under the `Task` section, and you will be taken to the list of all [Draft Task Resources](../concepts/dsf/draft-task-resources.md). Once there, you can select the one which starts your BPMN process. It will take you to a detailed view of the resource where you will also have the chance to fill any [Task Input Parameters](../concepts/fhir/task.md#task-input-parameters) you might need to specify. If everything is filled out correctly, you may start your process by clicking `Start Process`. Keep in mind that, for [Draft Task Resources](../concepts/dsf/draft-task-resources.md) to be available, you need to include them in your mapping for your BPMN process ID in `ProcessPluginDefinition#getFhirResourcesByProcessId`. Take a look at [the Process Plugin Definition](../concepts/dsf/the-process-plugin-definition.md) if you need a reminder. \ No newline at end of file From ce885f95b9d825279aa0868d9c601bdf2966a842 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20B=C3=B6hringer?= <jan.boehringer@hs-heilbronn.de> Date: Tue, 7 May 2024 13:43:22 +0200 Subject: [PATCH 04/14] Reverted --- docs/package-lock.json | 2 +- docs/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/package-lock.json b/docs/package-lock.json index 6086762fb..846fb23bc 100644 --- a/docs/package-lock.json +++ b/docs/package-lock.json @@ -12,7 +12,7 @@ "@vuepress/bundler-vite": "2.0.0-rc.9", "sass-loader": "14.1.1", "vue": "3.4.21", - "vuepress": "^2.0.0-rc.9", + "vuepress": "2.0.0-rc.9", "vuepress-plugin-search-pro": "2.0.0-rc.32", "vuepress-theme-hope": "2.0.0-rc.32" }, diff --git a/docs/package.json b/docs/package.json index bcadeb134..4c911d911 100644 --- a/docs/package.json +++ b/docs/package.json @@ -14,7 +14,7 @@ "@vuepress/bundler-vite": "2.0.0-rc.9", "sass-loader": "14.1.1", "vue": "3.4.21", - "vuepress": "^2.0.0-rc.9", + "vuepress": "2.0.0-rc.9", "vuepress-plugin-search-pro": "2.0.0-rc.32", "vuepress-theme-hope": "2.0.0-rc.32" }, From cafeee158eeabf981796b0d16a4682d496a23568 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20B=C3=B6hringer?= <jan.boehringer@hs-heilbronn.de> Date: Tue, 7 May 2024 13:51:19 +0200 Subject: [PATCH 05/14] Renamed tutorial files --- ...e5_event_based_gateway.bpmn => event_based_gateway.bpmn} | 0 ...ise5_event_based_gateway.svg => event_based_gateway.svg} | 0 ...ateway_inverted.svg => event_based_gateway_inverted.svg} | 2 +- .../{exercise3_message_flow.bpmn => message_flow.bpmn} | 0 .../{exercise3_message_flow.svg => message_flow.svg} | 0 ..._message_flow_inverted.svg => message_flow_inverted.svg} | 2 +- docs/src/developer-documentation/concepts/bpmn/messaging.md | 2 +- ...naging-mutiple-incoming-messages-and-missing-messages.md | 6 +++--- 8 files changed, 6 insertions(+), 6 deletions(-) rename docs/src/.vuepress/public/photos/developer-documentation/{exercise5_event_based_gateway.bpmn => event_based_gateway.bpmn} (100%) rename docs/src/.vuepress/public/photos/developer-documentation/{exercise5_event_based_gateway.svg => event_based_gateway.svg} (100%) rename docs/src/.vuepress/public/photos/developer-documentation/{exercise5_event_based_gateway_inverted.svg => event_based_gateway_inverted.svg} (99%) rename docs/src/.vuepress/public/photos/developer-documentation/{exercise3_message_flow.bpmn => message_flow.bpmn} (100%) rename docs/src/.vuepress/public/photos/developer-documentation/{exercise3_message_flow.svg => message_flow.svg} (100%) rename docs/src/.vuepress/public/photos/developer-documentation/{exercise3_message_flow_inverted.svg => message_flow_inverted.svg} (99%) diff --git a/docs/src/.vuepress/public/photos/developer-documentation/exercise5_event_based_gateway.bpmn b/docs/src/.vuepress/public/photos/developer-documentation/event_based_gateway.bpmn similarity index 100% rename from docs/src/.vuepress/public/photos/developer-documentation/exercise5_event_based_gateway.bpmn rename to docs/src/.vuepress/public/photos/developer-documentation/event_based_gateway.bpmn diff --git a/docs/src/.vuepress/public/photos/developer-documentation/exercise5_event_based_gateway.svg b/docs/src/.vuepress/public/photos/developer-documentation/event_based_gateway.svg similarity index 100% rename from docs/src/.vuepress/public/photos/developer-documentation/exercise5_event_based_gateway.svg rename to docs/src/.vuepress/public/photos/developer-documentation/event_based_gateway.svg diff --git a/docs/src/.vuepress/public/photos/developer-documentation/exercise5_event_based_gateway_inverted.svg b/docs/src/.vuepress/public/photos/developer-documentation/event_based_gateway_inverted.svg similarity index 99% rename from docs/src/.vuepress/public/photos/developer-documentation/exercise5_event_based_gateway_inverted.svg rename to docs/src/.vuepress/public/photos/developer-documentation/event_based_gateway_inverted.svg index e7ad511b9..d278f7db6 100644 --- a/docs/src/.vuepress/public/photos/developer-documentation/exercise5_event_based_gateway_inverted.svg +++ b/docs/src/.vuepress/public/photos/developer-documentation/event_based_gateway_inverted.svg @@ -11,7 +11,7 @@ viewBox="123 94 1073 372" version="1.1" id="svg417" - sodipodi:docname="exercise5_event_based_gateway_inverted.svg" + sodipodi:docname="event_based_gateway_inverted.svg" inkscape:version="1.0.1 (3bc2e813f5, 2020-09-07)"> <metadata id="metadata421"> diff --git a/docs/src/.vuepress/public/photos/developer-documentation/exercise3_message_flow.bpmn b/docs/src/.vuepress/public/photos/developer-documentation/message_flow.bpmn similarity index 100% rename from docs/src/.vuepress/public/photos/developer-documentation/exercise3_message_flow.bpmn rename to docs/src/.vuepress/public/photos/developer-documentation/message_flow.bpmn diff --git a/docs/src/.vuepress/public/photos/developer-documentation/exercise3_message_flow.svg b/docs/src/.vuepress/public/photos/developer-documentation/message_flow.svg similarity index 100% rename from docs/src/.vuepress/public/photos/developer-documentation/exercise3_message_flow.svg rename to docs/src/.vuepress/public/photos/developer-documentation/message_flow.svg diff --git a/docs/src/.vuepress/public/photos/developer-documentation/exercise3_message_flow_inverted.svg b/docs/src/.vuepress/public/photos/developer-documentation/message_flow_inverted.svg similarity index 99% rename from docs/src/.vuepress/public/photos/developer-documentation/exercise3_message_flow_inverted.svg rename to docs/src/.vuepress/public/photos/developer-documentation/message_flow_inverted.svg index 267c4e969..a1c8b17bc 100644 --- a/docs/src/.vuepress/public/photos/developer-documentation/exercise3_message_flow_inverted.svg +++ b/docs/src/.vuepress/public/photos/developer-documentation/message_flow_inverted.svg @@ -11,7 +11,7 @@ viewBox="123 104 774 162" version="1.1" id="svg203" - sodipodi:docname="exercise3_message_flow_inverted.svg" + sodipodi:docname="message_flow_inverted.svg" inkscape:version="1.0.1 (3bc2e813f5, 2020-09-07)"> <metadata id="metadata207"> diff --git a/docs/src/developer-documentation/concepts/bpmn/messaging.md b/docs/src/developer-documentation/concepts/bpmn/messaging.md index a8bec3071..fb6c455bd 100644 --- a/docs/src/developer-documentation/concepts/bpmn/messaging.md +++ b/docs/src/developer-documentation/concepts/bpmn/messaging.md @@ -8,7 +8,7 @@ icon: creative In order to enable communication with other lanes, pools or even entirely separate processes you need to be able to exchange information. In BPMN, you can use [Message Events](https://docs.camunda.org/manual/7.20/reference/bpmn20/events/message-events/) to model this information exchange. Modeling communication with [Message Events](https://docs.camunda.org/manual/7.20/reference/bpmn20/events/message-events/) in the same diagram uses Message Flow. Message Flow is typically represented by a dashed line arrow between BPMN elements with a black (send) or white (receive) envelope icon. The following BPMN collaboration diagram shows message exchange between two processes. -![BPMN collaboration diagram with two processes using message flow to exchange information between two organizations](/photos/developer-documentation/exercise3_message_flow.svg) +![BPMN collaboration diagram with two processes using message flow to exchange information between two organizations](/photos/developer-documentation/message_flow.svg) #### Message Start Event diff --git a/docs/src/developer-documentation/guides/managing-mutiple-incoming-messages-and-missing-messages.md b/docs/src/developer-documentation/guides/managing-mutiple-incoming-messages-and-missing-messages.md index 4a6f3a08d..5cf1241df 100644 --- a/docs/src/developer-documentation/guides/managing-mutiple-incoming-messages-and-missing-messages.md +++ b/docs/src/developer-documentation/guides/managing-mutiple-incoming-messages-and-missing-messages.md @@ -12,7 +12,7 @@ At the same time, you might also expect to receive one out of a number of differ In order to solve both problems we can add an [Event Based Gateway](../concepts/bpmn/gateways.md#event-based-gateway) to the process waiting for a response and then either handle a [Task](../concepts/fhir/task.md) resource with the response and finish the process in a success state or trigger a [Timer Intermediate Catching Event](../concepts/bpmn/timer-intermediate-catching-events.md) after a defined wait period and finish the process in an error state. The following BPMN collaboration diagram shows how the process at the first organization would look like if we wanted to react to multiple different messages or missing messages: <picture> - <source media="(prefers-color-scheme: dark)" srcset="/photos/developer-documentation/exercise5_event_based_gateway_inverted.svg"> - <source media="(prefers-color-scheme: light)" srcset="/photos/developer-documentation/exercise5_event_based_gateway.svg"> - <img alt="BPMN collaboration diagram with an Event Based Gateway" src="/photos/developer-documentation/exercise5_event_based_gateway.svg"> + <source media="(prefers-color-scheme: dark)" srcset="/photos/developer-documentation/event_based_gateway_inverted.svg"> + <source media="(prefers-color-scheme: light)" srcset="/photos/developer-documentation/event_based_gateway.svg"> + <img alt="BPMN collaboration diagram with an Event Based Gateway" src="/photos/developer-documentation/event_based_gateway.svg"> </picture> From 478189bbc8902f51164831c3e7598f9bab0647e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20B=C3=B6hringer?= <jan.boehringer@hs-heilbronn.de> Date: Tue, 7 May 2024 14:05:52 +0200 Subject: [PATCH 06/14] Elevated camunda docs versions to 7.21. All links are working as of the time of this commit --- .../concepts/bpmn/conditions.md | 2 +- .../concepts/bpmn/gateways.md | 6 +++--- .../concepts/bpmn/intro.md | 2 +- .../concepts/bpmn/messaging.md | 10 +++++----- .../concepts/bpmn/service-tasks.md | 2 +- .../bpmn/timer-intermediate-catching-events.md | 2 +- .../concepts/dsf/bpmn-process-execution.md | 2 +- .../tutorial/exercise1-simpleProcess.md | 2 +- .../tutorial/exercise3-messageEvents.md | 8 ++++---- .../tutorial/exercise4-exclusiveGateways.md | 6 +++--- .../tutorial/exercise5-eventBasedGateways.md | 18 +++++++++--------- 11 files changed, 30 insertions(+), 30 deletions(-) diff --git a/docs/src/developer-documentation/concepts/bpmn/conditions.md b/docs/src/developer-documentation/concepts/bpmn/conditions.md index 5aa85f5e2..4ac23388d 100644 --- a/docs/src/developer-documentation/concepts/bpmn/conditions.md +++ b/docs/src/developer-documentation/concepts/bpmn/conditions.md @@ -5,4 +5,4 @@ icon: creative ### Conditions -[Conditions](https://docs.camunda.org/manual/7.20/user-guide/process-engine/expression-language/#conditions) allow you to change the behaviour of BPMN processes during execution. There are two ways you are able to add decision logic to Conditions. The [Camunda Modeler](https://camunda.com/download/modeler/) refers to them as `Type`. You can find them in the ``Condition`` tab of certain BPMN elements. The first one is `Script`. This allows you to add arbitrary complexity to your decisions logic and is rarely used for process plugins. The more common Type is `Expression`. Expressions have the following syntax: `${expression}`. An example of a simple expression would be a boolean condition like `var == true`. For this to work during BPMN process execution, the variable you want to use for the boolean condition must be available in the BPMN process variables before [Sequence Flow](../../concepts/bpmn/sequence-flow.md) reaches the evaluation of the expression. You can learn more advanced features of Expressions [here](https://docs.camunda.org/manual/7.20/user-guide/process-engine/expression-language/). \ No newline at end of file +[Conditions](https://docs.camunda.org/manual/7.21/user-guide/process-engine/expression-language/#conditions) allow you to change the behaviour of BPMN processes during execution. There are two ways you are able to add decision logic to Conditions. The [Camunda Modeler](https://camunda.com/download/modeler/) refers to them as `Type`. You can find them in the ``Condition`` tab of certain BPMN elements. The first one is `Script`. This allows you to add arbitrary complexity to your decisions logic and is rarely used for process plugins. The more common Type is `Expression`. Expressions have the following syntax: `${expression}`. An example of a simple expression would be a boolean condition like `var == true`. For this to work during BPMN process execution, the variable you want to use for the boolean condition must be available in the BPMN process variables before [Sequence Flow](../../concepts/bpmn/sequence-flow.md) reaches the evaluation of the expression. You can learn more advanced features of Expressions [here](https://docs.camunda.org/manual/7.21/user-guide/process-engine/expression-language/). \ No newline at end of file diff --git a/docs/src/developer-documentation/concepts/bpmn/gateways.md b/docs/src/developer-documentation/concepts/bpmn/gateways.md index 083fbbb26..5b17a4205 100644 --- a/docs/src/developer-documentation/concepts/bpmn/gateways.md +++ b/docs/src/developer-documentation/concepts/bpmn/gateways.md @@ -5,12 +5,12 @@ icon: creative ### Gateways -[Gateways](https://docs.camunda.org/manual/7.20/reference/bpmn20/gateways/) allow you to control the [Sequence Flow](../../concepts/bpmn/sequence-flow.md). Different types of gateways will be useful for different scenarios. +[Gateways](https://docs.camunda.org/manual/7.21/reference/bpmn20/gateways/) allow you to control the [Sequence Flow](../../concepts/bpmn/sequence-flow.md). Different types of gateways will be useful for different scenarios. #### Exclusive Gateways -[Exclusive Gateways](https://docs.camunda.org/manual/7.20/reference/bpmn20/gateways/exclusive-gateway/) allow you to decide which [Sequence Flow](../../concepts/bpmn/sequence-flow.md) should be followed based on [conditions](https://docs.camunda.org/manual/7.20/user-guide/process-engine/expression-language/#conditions). [Conditions](https://docs.camunda.org/manual/7.20/user-guide/process-engine/expression-language/#conditions) are not part of the [Exclusive Gateways](https://docs.camunda.org/manual/7.20/reference/bpmn20/gateways/exclusive-gateway/) themselves. You set them through the sequence Flow Exiting the [Exclusive Gateway](https://docs.camunda.org/manual/7.20/reference/bpmn20/gateways/exclusive-gateway/). In the [Camunda Modeler](https://camunda.com/download/modeler/), you can add conditions to [Sequence Flow](../../concepts/bpmn/sequence-flow.md) by selecting a [Sequence Flow](../../concepts/bpmn/sequence-flow.md) and opening the `Condition` tab. You can find more information on how to use Conditions [here](../../concepts/bpmn/conditions.md). +[Exclusive Gateways](https://docs.camunda.org/manual/7.21/reference/bpmn20/gateways/exclusive-gateway/) allow you to decide which [Sequence Flow](../../concepts/bpmn/sequence-flow.md) should be followed based on [conditions](https://docs.camunda.org/manual/7.21/user-guide/process-engine/expression-language/#conditions). [Conditions](https://docs.camunda.org/manual/7.21/user-guide/process-engine/expression-language/#conditions) are not part of the [Exclusive Gateways](https://docs.camunda.org/manual/7.21/reference/bpmn20/gateways/exclusive-gateway/) themselves. You set them through the sequence Flow Exiting the [Exclusive Gateway](https://docs.camunda.org/manual/7.21/reference/bpmn20/gateways/exclusive-gateway/). In the [Camunda Modeler](https://camunda.com/download/modeler/), you can add conditions to [Sequence Flow](../../concepts/bpmn/sequence-flow.md) by selecting a [Sequence Flow](../../concepts/bpmn/sequence-flow.md) and opening the `Condition` tab. You can find more information on how to use Conditions [here](../../concepts/bpmn/conditions.md). #### Event-based Gateway -The [Event-based Gateway](https://docs.camunda.org/manual/7.20/reference/bpmn20/gateways/event-based-gateway/) allows you model scenarios where you are expecting one out of a number of events to occur. \ No newline at end of file +The [Event-based Gateway](https://docs.camunda.org/manual/7.21/reference/bpmn20/gateways/event-based-gateway/) allows you model scenarios where you are expecting one out of a number of events to occur. \ No newline at end of file diff --git a/docs/src/developer-documentation/concepts/bpmn/intro.md b/docs/src/developer-documentation/concepts/bpmn/intro.md index 2922e2b4b..aa901e9da 100644 --- a/docs/src/developer-documentation/concepts/bpmn/intro.md +++ b/docs/src/developer-documentation/concepts/bpmn/intro.md @@ -3,4 +3,4 @@ title: Introduction icon: creative --- -The DSF uses BPMN 2.0 to model processes. Specifically, the [Camunda 7](https://docs.camunda.org/manual/7.20/) dialect from the [Camunda Modeler](https://camunda.com/de/download/modeler/). Modeling processes for the DSF requires this modeler or any other modeler which is able to produce the correct Camunda dialect. \ No newline at end of file +The DSF uses BPMN 2.0 to model processes. Specifically, the [Camunda 7](https://docs.camunda.org/manual/7.21/) dialect from the [Camunda Modeler](https://camunda.com/de/download/modeler/). Modeling processes for the DSF requires this modeler or any other modeler which is able to produce the correct Camunda dialect. \ No newline at end of file diff --git a/docs/src/developer-documentation/concepts/bpmn/messaging.md b/docs/src/developer-documentation/concepts/bpmn/messaging.md index fb6c455bd..97d05703b 100644 --- a/docs/src/developer-documentation/concepts/bpmn/messaging.md +++ b/docs/src/developer-documentation/concepts/bpmn/messaging.md @@ -6,19 +6,19 @@ icon: creative ### Messaging -In order to enable communication with other lanes, pools or even entirely separate processes you need to be able to exchange information. In BPMN, you can use [Message Events](https://docs.camunda.org/manual/7.20/reference/bpmn20/events/message-events/) to model this information exchange. Modeling communication with [Message Events](https://docs.camunda.org/manual/7.20/reference/bpmn20/events/message-events/) in the same diagram uses Message Flow. Message Flow is typically represented by a dashed line arrow between BPMN elements with a black (send) or white (receive) envelope icon. The following BPMN collaboration diagram shows message exchange between two processes. +In order to enable communication with other lanes, pools or even entirely separate processes you need to be able to exchange information. In BPMN, you can use [Message Events](https://docs.camunda.org/manual/7.21/reference/bpmn20/events/message-events/) to model this information exchange. Modeling communication with [Message Events](https://docs.camunda.org/manual/7.21/reference/bpmn20/events/message-events/) in the same diagram uses Message Flow. Message Flow is typically represented by a dashed line arrow between BPMN elements with a black (send) or white (receive) envelope icon. The following BPMN collaboration diagram shows message exchange between two processes. ![BPMN collaboration diagram with two processes using message flow to exchange information between two organizations](/photos/developer-documentation/message_flow.svg) #### Message Start Event -[Message Start Events](https://docs.camunda.org/manual/7.20/reference/bpmn20/events/message-events/#message-start-event) allow a BPMN process to be started by an incoming message. In the DSF, all BPMN processes are started via messages. Therefore, you will have to include a [Message Start Event](https://docs.camunda.org/manual/7.20/reference/bpmn20/events/message-events/#message-start-event) at the beginning of all of your BPMN models. +[Message Start Events](https://docs.camunda.org/manual/7.21/reference/bpmn20/events/message-events/#message-start-event) allow a BPMN process to be started by an incoming message. In the DSF, all BPMN processes are started via messages. Therefore, you will have to include a [Message Start Event](https://docs.camunda.org/manual/7.21/reference/bpmn20/events/message-events/#message-start-event) at the beginning of all of your BPMN models. #### Message Intermediate Throwing Event -[Message Intermediate Throwing Events](https://docs.camunda.org/manual/7.20/reference/bpmn20/events/message-events/#message-intermediate-throwing-event) are used to send messages during process execution. +[Message Intermediate Throwing Events](https://docs.camunda.org/manual/7.21/reference/bpmn20/events/message-events/#message-intermediate-throwing-event) are used to send messages during process execution. #### Message Intermediate Catching Event -[Message Intermediate Catching Events](https://docs.camunda.org/manual/7.20/reference/bpmn20/events/message-events/#message-intermediate-catching-event) serve as the counterpart to [Message Intermediate Throwing Events](messaging.md#message-intermediate-throwing-event). Use them whenever you expect to receive a message from another process or organization during execution. +[Message Intermediate Catching Events](https://docs.camunda.org/manual/7.21/reference/bpmn20/events/message-events/#message-intermediate-catching-event) serve as the counterpart to [Message Intermediate Throwing Events](messaging.md#message-intermediate-throwing-event). Use them whenever you expect to receive a message from another process or organization during execution. #### Message End Event -The [Message End Event](https://docs.camunda.org/manual/7.20/reference/bpmn20/events/message-events/#message-end-event) will stop the execution of a BPMN process and finish by sending a message. \ No newline at end of file +The [Message End Event](https://docs.camunda.org/manual/7.21/reference/bpmn20/events/message-events/#message-end-event) will stop the execution of a BPMN process and finish by sending a message. \ No newline at end of file diff --git a/docs/src/developer-documentation/concepts/bpmn/service-tasks.md b/docs/src/developer-documentation/concepts/bpmn/service-tasks.md index 50849d488..ebe8ad3c9 100644 --- a/docs/src/developer-documentation/concepts/bpmn/service-tasks.md +++ b/docs/src/developer-documentation/concepts/bpmn/service-tasks.md @@ -5,4 +5,4 @@ icon: creative ### Service Tasks -One of the most common types of BPMN Tasks used for modeling DSF processes is the [Service Task](https://docs.camunda.org/manual/7.20/reference/bpmn20/tasks/service-task/). They are different from regular BPMN Tasks in that they offer the ability to link an implementation to the [Service Task](https://docs.camunda.org/manual/7.20/reference/bpmn20/tasks/service-task/) which can be called and executed by a BPMN engine. The BPE (Business Process Engine) server of the DSF leverages this engine to execute your BPMN processes. \ No newline at end of file +One of the most common types of BPMN Tasks used for modeling DSF processes is the [Service Task](https://docs.camunda.org/manual/7.21/reference/bpmn20/tasks/service-task/). They are different from regular BPMN Tasks in that they offer the ability to link an implementation to the [Service Task](https://docs.camunda.org/manual/7.21/reference/bpmn20/tasks/service-task/) which can be called and executed by a BPMN engine. The BPE (Business Process Engine) server of the DSF leverages this engine to execute your BPMN processes. \ No newline at end of file diff --git a/docs/src/developer-documentation/concepts/bpmn/timer-intermediate-catching-events.md b/docs/src/developer-documentation/concepts/bpmn/timer-intermediate-catching-events.md index c8e8b8ffc..bb4a0eb80 100644 --- a/docs/src/developer-documentation/concepts/bpmn/timer-intermediate-catching-events.md +++ b/docs/src/developer-documentation/concepts/bpmn/timer-intermediate-catching-events.md @@ -5,4 +5,4 @@ icon: creative ### Timer Intermediate Catching Events -A [Timer Intermediate Catching Event](https://docs.camunda.org/manual/7.17/reference/bpmn20/events/timer-events/#timer-intermediate-catching-event) allows you to model stopwatch behavior. A timer is started once the BPMN execution arrives at the event. The duration until the timer runs out is specified using the [ISO 8601 Durations](http://en.wikipedia.org/wiki/ISO_8601#Durations) format. Examples can be found [here](https://docs.camunda.org/manual/7.17/reference/bpmn20/events/timer-events/#time-duration). After running out, the BPMN process executes the [Sequence Flow](../../concepts/bpmn/sequence-flow.md) following the [Timer Intermediate Catching Event](https://docs.camunda.org/manual/7.17/reference/bpmn20/events/timer-events/#timer-intermediate-catching-event). \ No newline at end of file +A [Timer Intermediate Catching Event](https://docs.camunda.org/manual/7.21/reference/bpmn20/events/timer-events/#timer-intermediate-catching-event) allows you to model stopwatch behavior. A timer is started once the BPMN execution arrives at the event. The duration until the timer runs out is specified using the [ISO 8601 Durations](http://en.wikipedia.org/wiki/ISO_8601#Durations) format. Examples can be found [here](https://docs.camunda.org/manual/7.21/reference/bpmn20/events/timer-events/#time-duration). After running out, the BPMN process executes the [Sequence Flow](../../concepts/bpmn/sequence-flow.md) following the [Timer Intermediate Catching Event](https://docs.camunda.org/manual/7.21/reference/bpmn20/events/timer-events/#timer-intermediate-catching-event). \ No newline at end of file diff --git a/docs/src/developer-documentation/concepts/dsf/bpmn-process-execution.md b/docs/src/developer-documentation/concepts/dsf/bpmn-process-execution.md index e9aea7a67..643f371fc 100644 --- a/docs/src/developer-documentation/concepts/dsf/bpmn-process-execution.md +++ b/docs/src/developer-documentation/concepts/dsf/bpmn-process-execution.md @@ -6,4 +6,4 @@ icon: creative ### BPMN Process Execution -The BPMN process execution is the in-memory representation of a running BPMN process. BPMN processes have their executions structured as a tree hierarchy. Each BPMN process starts with the [process instance](https://docs.camunda.org/manual/7.20/user-guide/process-engine/process-engine-concepts/#process-instances) as its root level execution. If, for example, this root execution reaches a parallel gateway with two paths, it would spawn two child executions under itself for them to process all tasks along their paths on their own. Executions can access all the BPMN elements from the BPMN model as well as the [BPMN process variables](../../concepts/dsf/bpmn-process-variables.md). You have access to this representation in your Java code through the `execution` parameter when overriding certain methods in [Service](../../concepts/dsf/service-delegates.md) / [Message](../../concepts/dsf/message-delegates.md) Delegates like `doExecute` or `getAdditionalInputParameters`. \ No newline at end of file +The BPMN process execution is the in-memory representation of a running BPMN process. BPMN processes have their executions structured as a tree hierarchy. Each BPMN process starts with the [process instance](https://docs.camunda.org/manual/7.21/user-guide/process-engine/process-engine-concepts/#process-instances) as its root level execution. If, for example, this root execution reaches a parallel gateway with two paths, it would spawn two child executions under itself for them to process all tasks along their paths on their own. Executions can access all the BPMN elements from the BPMN model as well as the [BPMN process variables](../../concepts/dsf/bpmn-process-variables.md). You have access to this representation in your Java code through the `execution` parameter when overriding certain methods in [Service](../../concepts/dsf/service-delegates.md) / [Message](../../concepts/dsf/message-delegates.md) Delegates like `doExecute` or `getAdditionalInputParameters`. \ No newline at end of file diff --git a/docs/src/oldstable/tutorial/exercise1-simpleProcess.md b/docs/src/oldstable/tutorial/exercise1-simpleProcess.md index b50920c6c..79b0ff39e 100644 --- a/docs/src/oldstable/tutorial/exercise1-simpleProcess.md +++ b/docs/src/oldstable/tutorial/exercise1-simpleProcess.md @@ -22,7 +22,7 @@ Java code for the `tutorial-process` project is located at `src/main/java`, FHIR The most imported Java class used to specify the process plugin for the DSF BPE server is a class that implements the `org.highmed.dsf.bpe.ProcessPluginDefinition` interface from the DSF [dsf-bpe-process-base](https://github.com/highmed/highmed-dsf/packages/503054) module. The DSF BPE server searches for classes implementing this interface using the Java [ServiceLoader](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/ServiceLoader.html) mechanism. For this tutorial the `TutorialProcessPluginDefinition` class implements this interface. It is appropriately specified in the `src/main/resources/META-INF/services/org.highmed.dsf.bpe`.ProcessPluginDefinition file. The `TutorialProcessPluginDefinition` class is used to specify name and version of the process plugin, what BPMN processes are to be deployed and what FHIR resources and required by the BPMN processes. For the implementation of service task and message events of the processes a special Spring context is used for every process plugin. The `TutorialProcessPluginDefinition` class specifies what via [Spring-Framework configuration class](https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#beans-java-basic-concepts) with Spring Beans are used for the process plugin specific Spring Context. For this plugin the `TutorialConfig` cass is used to define Spring Beans. -The business process engine used by the DSF BPE server is based on the OpenSource Camunda Process Engine 7. In order to specify what Java code should be executed for a BPMN [ServiceTask](https://docs.camunda.org/manual/7.17/reference/bpmn20/tasks/service-task/) you need to specify the fully-qualified Java class name in the ServiceTask inside the BPMN model. To be executable the Java class needs to extend the `org.highmed.dsf.bpe.delegate.AbstractServiceDelegate` from the DSF [dsf-bpe-process-base](https://github.com/highmed/highmed-dsf/packages/503054) module and the class needs to be defined as as Spring Bean. +The business process engine used by the DSF BPE server is based on the OpenSource Camunda Process Engine 7. In order to specify what Java code should be executed for a BPMN [ServiceTask](https://docs.camunda.org/manual/7.21/reference/bpmn20/tasks/service-task/) you need to specify the fully-qualified Java class name in the ServiceTask inside the BPMN model. To be executable the Java class needs to extend the `org.highmed.dsf.bpe.delegate.AbstractServiceDelegate` from the DSF [dsf-bpe-process-base](https://github.com/highmed/highmed-dsf/packages/503054) module and the class needs to be defined as as Spring Bean. #### Process Execution and FHIR Task Resources diff --git a/docs/src/oldstable/tutorial/exercise3-messageEvents.md b/docs/src/oldstable/tutorial/exercise3-messageEvents.md index af6314b0f..09b5bbb1b 100644 --- a/docs/src/oldstable/tutorial/exercise3-messageEvents.md +++ b/docs/src/oldstable/tutorial/exercise3-messageEvents.md @@ -19,7 +19,7 @@ In order to exchange information between different processes, for example at two ![Message Flow](/photos/guideline/tutorial/ex3.png) -Every time message flow is used in a BPMN process for the DSF, a corresponding FHIR [Task](http://hl7.org/fhir/R4/task.html) profile needs to be specified for every interaction. This profile specifies which process should be started or continued and what the message name is when correlating the appropriate [Message Start Event](https://docs.camunda.org/manual/7.17/reference/bpmn20/events/message-events/#message-start-event) or [Intermediate Message Catch Event](https://docs.camunda.org/manual/7.17/reference/bpmn20/events/message-events/#message-intermediate-catching-event). A *Business Key* and a *Correlation Key* are specified if different process instances need to be linked to a single execution, for example to be able to send a message back. +Every time message flow is used in a BPMN process for the DSF, a corresponding FHIR [Task](http://hl7.org/fhir/R4/task.html) profile needs to be specified for every interaction. This profile specifies which process should be started or continued and what the message name is when correlating the appropriate [Message Start Event](https://docs.camunda.org/manual/7.21/reference/bpmn20/events/message-events/#message-start-event) or [Intermediate Message Catch Event](https://docs.camunda.org/manual/7.21/reference/bpmn20/events/message-events/#message-intermediate-catching-event). A *Business Key* and a *Correlation Key* are specified if different process instances need to be linked to a single execution, for example to be able to send a message back. #### BPMN Process Definition Key vs. FHIR Task.instantiatesUri and ActivityDefinition.url / version @@ -48,7 +48,7 @@ The authorization extension needs to be configured at least once and has four su ##### message-name [1..1] -String value specifying the message name of [Message Start Event](https://docs.camunda.org/manual/7.17/reference/bpmn20/events/message-events/#message-start-event), [Intermediate Message Catch Event](https://docs.camunda.org/manual/7.17/reference/bpmn20/events/message-events/#message-intermediate-catching-event) or [Message Receive Task](https://docs.camunda.org/manual/7.17/reference/bpmn20/tasks/receive-task/) this authorization rule should match. Can only be specified once per authorization rule extension. +String value specifying the message name of [Message Start Event](https://docs.camunda.org/manual/7.21/reference/bpmn20/events/message-events/#message-start-event), [Intermediate Message Catch Event](https://docs.camunda.org/manual/7.21/reference/bpmn20/events/message-events/#message-intermediate-catching-event) or [Message Receive Task](https://docs.camunda.org/manual/7.21/reference/bpmn20/tasks/receive-task/) this authorization rule should match. Can only be specified once per authorization rule extension. ##### task-profile [1..1] @@ -122,9 +122,9 @@ The following example specifies that process execution can only be requested by ### Exercise Tasks --- -1. Modify the ``highmedorg_helloDic`` process in the ``hello-dic.bpmn`` file and replace the [End Event](https://docs.camunda.org/manual/7.17/reference/bpmn20/events/none-events/#none-end-event) with a [Message End Event](https://docs.camunda.org/manual/7.17/reference/bpmn20/events/message-events/#message-end-event). Configure input parameters ``instantiatesUri``, ``profile`` and ``messageName`` in the BPMN model for the [Message End Event](https://docs.camunda.org/manual/7.17/reference/bpmn20/events/message-events/#message-end-event). Set the message name of the [Message End Event](https://docs.camunda.org/manual/7.17/reference/bpmn20/events/message-events/#message-end-event) and configure it to be executed using the HelloCosMessage class. +1. Modify the ``highmedorg_helloDic`` process in the ``hello-dic.bpmn`` file and replace the [End Event](https://docs.camunda.org/manual/7.21/reference/bpmn20/events/none-events/#none-end-event) with a [Message End Event](https://docs.camunda.org/manual/7.21/reference/bpmn20/events/message-events/#message-end-event). Configure input parameters ``instantiatesUri``, ``profile`` and ``messageName`` in the BPMN model for the [Message End Event](https://docs.camunda.org/manual/7.21/reference/bpmn20/events/message-events/#message-end-event). Set the message name of the [Message End Event](https://docs.camunda.org/manual/7.21/reference/bpmn20/events/message-events/#message-end-event) and configure it to be executed using the HelloCosMessage class. Use http://highmed.org/fhir/StructureDefinition/task-hello-cos|#{version} as the profile and ``helloCos`` as the message name. Figure out what the appropriate ``instantiatesUri`` value is, based on the name (process definition key) of the process to be triggered. -2. Modify the ``highmedorg_helloCos`` process in the ``hello-cos.bpmn`` file and configure the message name of the [Message Start Event](https://docs.camunda.org/manual/7.17/reference/bpmn20/events/message-events/#message-start-event) with the same value as the message name of the [Message End Event](https://docs.camunda.org/manual/7.17/reference/bpmn20/events/message-events/#message-end-event) in the ``highmedorg_helloDic`` process. +2. Modify the ``highmedorg_helloCos`` process in the ``hello-cos.bpmn`` file and configure the message name of the [Message Start Event](https://docs.camunda.org/manual/7.21/reference/bpmn20/events/message-events/#message-start-event) with the same value as the message name of the [Message End Event](https://docs.camunda.org/manual/7.21/reference/bpmn20/events/message-events/#message-end-event) in the ``highmedorg_helloDic`` process. 3. Create a new [StructureDefinition](http://hl7.org/fhir/R4/structuredefinition.html) with a [Task](http://hl7.org/fhir/R4/task.html) profile for the ``helloCos`` message. 4. Create a new [ActivityDefinition](http://hl7.org/fhir/R4/activitydefinition.html) resource for the ``highmedorg_helloCos`` process and configure the authorization extension to allow the ``Test_DIC`` organization as the requester and the ``Test_COS`` organization as the recipient. 5. Add the ``highmedorg_helloCos`` process and its resources to the ``TutorialProcessPluginDefinition`` class. diff --git a/docs/src/oldstable/tutorial/exercise4-exclusiveGateways.md b/docs/src/oldstable/tutorial/exercise4-exclusiveGateways.md index e11e63562..ed344a25c 100644 --- a/docs/src/oldstable/tutorial/exercise4-exclusiveGateways.md +++ b/docs/src/oldstable/tutorial/exercise4-exclusiveGateways.md @@ -11,11 +11,11 @@ Different execution paths in a process based on the state of process variables c --- #### Exclusive Gateways -Different sequence flows during the execution of a process instance can be modeled using BPMN [Exclusive Gateways](https://docs.camunda.org/manual/7.4/reference/bpmn20/gateways/exclusive-gateway/). For each outgoing sequence flow of the gateway, a BPMN [Condition Expression](https://docs.camunda.org/manual/7.17/user-guide/process-engine/expression-language/#conditions) can be added to the process model, deciding whether a sequence flow should be followed. Thereby, all condition decisions must be in an XOR relationship to each other. +Different sequence flows during the execution of a process instance can be modeled using BPMN [Exclusive Gateways](https://docs.camunda.org/manual/7.4/reference/bpmn20/gateways/exclusive-gateway/). For each outgoing sequence flow of the gateway, a BPMN [Condition Expression](https://docs.camunda.org/manual/7.21/user-guide/process-engine/expression-language/#conditions) can be added to the process model, deciding whether a sequence flow should be followed. Thereby, all condition decisions must be in an XOR relationship to each other. #### Condition Expressions -A BPMN [Condition Expression](https://docs.camunda.org/manual/7.17/user-guide/process-engine/expression-language/#conditions) uses the ``${..}`` notation. Within the curly braces all execution variables of a process instance can be accessed, e.g. the ones that were stored in a previous Java implementation of a BPMN [ServiceTask](https://docs.camunda.org/manual/7.17/reference/bpmn20/tasks/service-task/). For example, the BPMN [Condition Expression](https://docs.camunda.org/manual/7.17/user-guide/process-engine/expression-language/#conditions) ``${cohortSize > 100}`` checks whether the value in the execution variable *cohortSize* is greater than 100. +A BPMN [Condition Expression](https://docs.camunda.org/manual/7.21/user-guide/process-engine/expression-language/#conditions) uses the ``${..}`` notation. Within the curly braces all execution variables of a process instance can be accessed, e.g. the ones that were stored in a previous Java implementation of a BPMN [ServiceTask](https://docs.camunda.org/manual/7.21/reference/bpmn20/tasks/service-task/). For example, the BPMN [Condition Expression](https://docs.camunda.org/manual/7.21/user-guide/process-engine/expression-language/#conditions) ``${cohortSize > 100}`` checks whether the value in the execution variable *cohortSize* is greater than 100. #### Storing / Modifying Process Variables @@ -26,7 +26,7 @@ Via the ``DelegateExecution execution`` parameter of the ``doExecute`` method of boolean variable = (boolean) execution.getVariable("variable-name"); } ``` -For more details on process variables see the [Camunda documentation](https://docs.camunda.org/manual/7.17/user-guide/process-engine/variables/). +For more details on process variables see the [Camunda documentation](https://docs.camunda.org/manual/7.21/user-guide/process-engine/variables/). ### Exercise Tasks --- diff --git a/docs/src/oldstable/tutorial/exercise5-eventBasedGateways.md b/docs/src/oldstable/tutorial/exercise5-eventBasedGateways.md index d6afe6d87..8370f1881 100644 --- a/docs/src/oldstable/tutorial/exercise5-eventBasedGateways.md +++ b/docs/src/oldstable/tutorial/exercise5-eventBasedGateways.md @@ -14,13 +14,13 @@ In the final exercise we will look at message flow between three organizations a If an existing and started process instance is waiting for a message from another organization, the corresponding FHIR [Task](http://hl7.org/fhir/R4/task.html) may never arrive. Either because the other organization decides to never send the "message" or because some technical problem prohibits the [Task](http://hl7.org/fhir/R4/task.html) resource from being posted to the DSF FHIR server. This would result in stale process instances that never finish. -In order to solve this problem we can add an [Event Based Gateway](https://docs.camunda.org/manual/7.17/reference/bpmn20/gateways/event-based-gateway/) to the process waiting for a response and then either handle a [Task](http://hl7.org/fhir/R4/task.html) resource with the response and finish the process in a success state or fire of an [Intermediate Timer Catch Event](https://docs.camunda.org/manual/7.17/reference/bpmn20/events/timer-events/#timer-intermediate-catching-event) after a defined wait period and finish the process in an error state. The following BPMN collaboration diagram shows how the process at the first organization would look like if two different message or no message could be received: +In order to solve this problem we can add an [Event Based Gateway](https://docs.camunda.org/manual/7.21/reference/bpmn20/gateways/event-based-gateway/) to the process waiting for a response and then either handle a [Task](http://hl7.org/fhir/R4/task.html) resource with the response and finish the process in a success state or fire of an [Intermediate Timer Catch Event](https://docs.camunda.org/manual/7.21/reference/bpmn20/events/timer-events/#timer-intermediate-catching-event) after a defined wait period and finish the process in an error state. The following BPMN collaboration diagram shows how the process at the first organization would look like if two different message or no message could be received: ![](/photos/guideline/tutorial/ex5.png) ##### Timer Events -For [Timer Events](https://docs.camunda.org/manual/7.17/reference/bpmn20/events/timer-events/) the duration until the timer fires is specified using the [ISO 8601 Durations](https://en.wikipedia.org/wiki/ISO_8601#Durations) format. Examples can be found in the [Camunda 7 documentation](https://docs.camunda.org/manual/7.17/reference/bpmn20/events/timer-events/#time-duration). +For [Timer Events](https://docs.camunda.org/manual/7.21/reference/bpmn20/events/timer-events/) the duration until the timer fires is specified using the [ISO 8601 Durations](https://en.wikipedia.org/wiki/ISO_8601#Durations) format. Examples can be found in the [Camunda 7 documentation](https://docs.camunda.org/manual/7.21/reference/bpmn20/events/timer-events/#time-duration). #### Matching Process Instances With Business Keys @@ -36,7 +36,7 @@ The authorization extension needs to be configured at least once and has four su ##### message-name [1..1] -String value specifying the message name of [Message Start Event](https://docs.camunda.org/manual/7.17/reference/bpmn20/events/message-events/#message-start-event), [Intermediate Message Catch Event](https://docs.camunda.org/manual/7.17/reference/bpmn20/events/message-events/#message-intermediate-catching-event) or [Message Receive Task](https://docs.camunda.org/manual/7.17/reference/bpmn20/tasks/receive-task/) this authorization rule should match. Can only be specified once per authorization rule extension. +String value specifying the message name of [Message Start Event](https://docs.camunda.org/manual/7.21/reference/bpmn20/events/message-events/#message-start-event), [Intermediate Message Catch Event](https://docs.camunda.org/manual/7.21/reference/bpmn20/events/message-events/#message-intermediate-catching-event) or [Message Receive Task](https://docs.camunda.org/manual/7.21/reference/bpmn20/tasks/receive-task/) this authorization rule should match. Can only be specified once per authorization rule extension. ##### task-profile [1..1] @@ -126,13 +126,13 @@ The following example specifies that process execution can only be requested by ### Exercise Tasks --- 1. Modify the ``HelloCosMessage`` and use the value from the [Task.input](http://hl7.org/fhir/R4/task.html) parameter of the ``helloDic`` [Task](http://hl7.org/fhir/R4/task.html) to send it to the ``highmedorg_helloCos`` process via a [Task.input](http://hl7.org/fhir/R4/task.html) parameter in the ``helloCos`` Task. Override the ``getAdditionalInputParameters`` to configure a [Task.input](http://hl7.org/fhir/R4/task.html) parameter to be send. -2. Modify the ``highmedorg_helloCos`` process to use a [Message End Event](https://docs.camunda.org/manual/7.17/reference/bpmn20/events/message-events/#message-end-event) to trigger the process in file ``hello-hrp.bpmn``. Figure out the values for the ``instantiatesUri``, ``profile`` and ``messageName`` input parameters of the [Message End Event](https://docs.camunda.org/manual/7.17/reference/bpmn20/events/message-events/#message-end-event) based on the [AcitvityDefinition](http://hl7.org/fhir/R4/activitydefinition.html) in file ``hello-hrp.xml``. +2. Modify the ``highmedorg_helloCos`` process to use a [Message End Event](https://docs.camunda.org/manual/7.21/reference/bpmn20/events/message-events/#message-end-event) to trigger the process in file ``hello-hrp.bpmn``. Figure out the values for the ``instantiatesUri``, ``profile`` and ``messageName`` input parameters of the [Message End Event](https://docs.camunda.org/manual/7.21/reference/bpmn20/events/message-events/#message-end-event) based on the [AcitvityDefinition](http://hl7.org/fhir/R4/activitydefinition.html) in file ``hello-hrp.xml``. 3. Modify the ``highmedorg_helloDic`` process: - - Change the [Message End Event](https://docs.camunda.org/manual/7.17/reference/bpmn20/events/message-events/#message-end-event) to an [Intermediate Message Throw Event](https://docs.camunda.org/manual/7.17/reference/bpmn20/events/message-events/#message-intermediate-throwing-event) - - Add an [Event Based Gateway](https://docs.camunda.org/manual/7.17/reference/bpmn20/gateways/event-based-gateway/) after the throw event - - Configure two cases for the [Event Based Gateway](https://docs.camunda.org/manual/7.17/reference/bpmn20/gateways/event-based-gateway/): - 1. An [Intermediate Message Catch Event](https://docs.camunda.org/manual/7.17/reference/bpmn20/events/message-events/#message-intermediate-catching-event) to catch the ``goodbyDic`` message from the ``highmedorg_helloHrp`` process. - 2. An [Intermediate Timer Catch Event](https://docs.camunda.org/manual/7.17/reference/bpmn20/events/timer-events/#timer-intermediate-catching-event) to end the process if no message is sent by the ``highmedorg_helloHrp`` process after two minutes. Make sure both cases finish with a process [End Event](https://docs.camunda.org/manual/7.17/reference/bpmn20/events/none-events/). + - Change the [Message End Event](https://docs.camunda.org/manual/7.21/reference/bpmn20/events/message-events/#message-end-event) to an [Intermediate Message Throw Event](https://docs.camunda.org/manual/7.21/reference/bpmn20/events/message-events/#message-intermediate-throwing-event) + - Add an [Event Based Gateway](https://docs.camunda.org/manual/7.21/reference/bpmn20/gateways/event-based-gateway/) after the throw event + - Configure two cases for the [Event Based Gateway](https://docs.camunda.org/manual/7.21/reference/bpmn20/gateways/event-based-gateway/): + 1. An [Intermediate Message Catch Event](https://docs.camunda.org/manual/7.21/reference/bpmn20/events/message-events/#message-intermediate-catching-event) to catch the ``goodbyDic`` message from the ``highmedorg_helloHrp`` process. + 2. An [Intermediate Timer Catch Event](https://docs.camunda.org/manual/7.21/reference/bpmn20/events/timer-events/#timer-intermediate-catching-event) to end the process if no message is sent by the ``highmedorg_helloHrp`` process after two minutes. Make sure both cases finish with a process [End Event](https://docs.camunda.org/manual/7.21/reference/bpmn20/events/none-events/). 4. Modify the process in file ``hello-hrp.bpmn`` and set the process definition key and version. Figure out the appropriate values based on the [AcitvityDefinition](http://hl7.org/fhir/R4/activitydefinition.html) in file ``hello-hrp.xml``. 5. Add the process in file ``hello-hrp.bpmn`` to the ``TutorialProcessPluginDefinition`` and configure the FHIR resources needed for the three processes. 6. Add the ``HelloCos``, ``HelloHrpMessage`` , ``HelloHrp`` and ``GoodbyeDicMessage`` classes as spring beans. From a66ade29473dd7d343ccb3979a4a1ff1114a4928 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20B=C3=B6hringer?= <jan.boehringer@hs-heilbronn.de> Date: Tue, 14 May 2024 09:31:27 +0200 Subject: [PATCH 07/14] Renamed outgoing gateway flows --- .../event_based_gateway.svg | 1215 ++++++++++++++++- .../event_based_gateway_inverted.svg | 129 +- 2 files changed, 1297 insertions(+), 47 deletions(-) diff --git a/docs/src/.vuepress/public/photos/developer-documentation/event_based_gateway.svg b/docs/src/.vuepress/public/photos/developer-documentation/event_based_gateway.svg index e4c6a2552..bf792cb6e 100644 --- a/docs/src/.vuepress/public/photos/developer-documentation/event_based_gateway.svg +++ b/docs/src/.vuepress/public/photos/developer-documentation/event_based_gateway.svg @@ -1,4 +1,1213 @@ -<?xml version="1.0" encoding="utf-8"?> +<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!-- created with bpmn-js / http://bpmn.io --> -<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> -<svg xmlns="http://www.w3.org/2000/svg" width="1073" height="372" viewBox="123 94 1073 372" version="1.1"><defs><marker id="sequenceflow-end-white-black-att51rfxz5xb2bplwaj1r4xi8" viewBox="0 0 20 20" refX="11" refY="10" markerWidth="10" markerHeight="10" orient="auto"><path d="M 1 5 L 11 10 L 1 15 Z" style="fill: black; stroke-width: 1px; stroke-linecap: round; stroke-dasharray: 10000, 1; stroke: black;"/></marker><marker id="messageflow-end-white-black-att51rfxz5xb2bplwaj1r4xi8" viewBox="0 0 20 20" refX="8.5" refY="5" markerWidth="20" markerHeight="20" orient="auto"><path d="m 1 5 l 0 -3 l 7 3 l -7 3 z" style="fill: white; stroke-width: 1px; stroke-linecap: butt; stroke-dasharray: 10000, 1; stroke: black;"/></marker><marker id="messageflow-start-white-black-att51rfxz5xb2bplwaj1r4xi8" viewBox="0 0 20 20" refX="6" refY="6" markerWidth="20" markerHeight="20" orient="auto"><circle cx="6" cy="6" r="3.5" style="fill: white; stroke-width: 1px; stroke-linecap: round; stroke-dasharray: 10000, 1; stroke: black;"/></marker></defs><g class="djs-group"><g class="djs-element djs-shape" data-element-id="Participant_1u3es88" style="display: block;" transform="matrix(1 0 0 1 129 100)"><g class="djs-visual"><rect x="0" y="0" width="660" height="360" rx="0" ry="0" style="stroke: black; stroke-width: 2px; fill: white; fill-opacity: 0.95;"/><polyline points="30,0 30,360 " style="fill: none; stroke: black; stroke-width: 2px;"/><text lineHeight="1.2" class="djs-label" style="font-family: Arial, sans-serif; font-size: 12px; font-weight: normal; fill: black;" transform="matrix(-1.83697e-16 -1 1 -1.83697e-16 0 360)"><tspan x="140.9765625" y="18.6">Organization 1</tspan></text></g><rect x="-6" y="-6" width="672" height="372" class="djs-outline" style="fill: none;"/><rect class="djs-hit djs-hit-click-stroke" x="0" y="0" width="660" height="360" style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;"/><rect class="djs-hit djs-hit-all" x="0" y="0" width="30" height="360" style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;"/></g><g class="djs-children"><g class="djs-group"><g class="djs-element djs-connection" data-element-id="Flow_1vux1af" style="display: block;"><g class="djs-visual"><path d="m 215,177L270,177 " style="fill: none; stroke-width: 2px; stroke: black; stroke-linejoin: round; marker-end: url('#sequenceflow-end-white-black-att51rfxz5xb2bplwaj1r4xi8');"/></g><polyline points="215,177 270,177 " class="djs-hit djs-hit-stroke" style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;"/><rect x="209" y="171" width="67" height="12" class="djs-outline" style="fill: none;"/></g></g><g class="djs-group"><g class="djs-element djs-connection" data-element-id="Flow_1i7hh0u" style="display: block;"><g class="djs-visual"><path d="m 370,177L422,177 " style="fill: none; stroke-width: 2px; stroke: black; stroke-linejoin: round; marker-end: url('#sequenceflow-end-white-black-att51rfxz5xb2bplwaj1r4xi8');"/></g><polyline points="370,177 422,177 " class="djs-hit djs-hit-stroke" style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;"/><rect x="364" y="171" width="64" height="12" class="djs-outline" style="fill: none;"/></g></g><g class="djs-group"><g class="djs-element djs-connection" data-element-id="Flow_19hvbdm" style="display: block;"><g class="djs-visual"><path d="m 575,177L632,177 " style="fill: none; stroke-width: 2px; stroke: black; stroke-linejoin: round; marker-end: url('#sequenceflow-end-white-black-att51rfxz5xb2bplwaj1r4xi8');"/></g><polyline points="575,177 632,177 " class="djs-hit djs-hit-stroke" style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;"/><rect x="569" y="171" width="69" height="12" class="djs-outline" style="fill: none;"/></g></g><g class="djs-group"><g class="djs-element djs-connection" data-element-id="Flow_1pre2mk" style="display: block;"><g class="djs-visual"><path d="m 550,202L550,290 L632,290 " style="fill: none; stroke-width: 2px; stroke: black; stroke-linejoin: round; marker-end: url('#sequenceflow-end-white-black-att51rfxz5xb2bplwaj1r4xi8');"/></g><polyline points="550,202 550,290 632,290 " class="djs-hit djs-hit-stroke" style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;"/><rect x="544" y="196" width="94" height="100" class="djs-outline" style="fill: none;"/></g></g><g class="djs-group"><g class="djs-element djs-connection" data-element-id="Flow_0fn66bz" style="display: block;"><g class="djs-visual"><path d="m 668,177L732,177 " style="fill: none; stroke-width: 2px; stroke: black; stroke-linejoin: round; marker-end: url('#sequenceflow-end-white-black-att51rfxz5xb2bplwaj1r4xi8');"/></g><polyline points="668,177 732,177 " class="djs-hit djs-hit-stroke" style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;"/><rect x="662" y="171" width="76" height="12" class="djs-outline" style="fill: none;"/></g></g><g class="djs-group"><g class="djs-element djs-connection" data-element-id="Flow_1qeyly0" style="display: block;"><g class="djs-visual"><path d="m 668,290L732,290 " style="fill: none; stroke-width: 2px; stroke: black; stroke-linejoin: round; marker-end: url('#sequenceflow-end-white-black-att51rfxz5xb2bplwaj1r4xi8');"/></g><polyline points="668,290 732,290 " class="djs-hit djs-hit-stroke" style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;"/><rect x="662" y="284" width="76" height="12" class="djs-outline" style="fill: none;"/></g></g><g class="djs-group"><g class="djs-element djs-connection" data-element-id="Flow_1cwt97i" style="display: block;"><g class="djs-visual"><path d="m 458,177L525,177 " style="fill: none; stroke-width: 2px; stroke: black; stroke-linejoin: round; marker-end: url('#sequenceflow-end-white-black-att51rfxz5xb2bplwaj1r4xi8');"/></g><polyline points="458,177 525,177 " class="djs-hit djs-hit-stroke" style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;"/><rect x="452" y="171" width="79" height="12" class="djs-outline" style="fill: none;"/></g></g><g class="djs-group"><g class="djs-element djs-connection" data-element-id="Flow_1bf7gvl" style="display: block;"><g class="djs-visual"><path d="m 550,202L550,400 L632,400 " style="fill: none; stroke-width: 2px; stroke: black; stroke-linejoin: round; marker-end: url('#sequenceflow-end-white-black-att51rfxz5xb2bplwaj1r4xi8');"/></g><polyline points="550,202 550,400 632,400 " class="djs-hit djs-hit-stroke" style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;"/><rect x="544" y="196" width="94" height="210" class="djs-outline" style="fill: none;"/></g></g><g class="djs-group"><g class="djs-element djs-connection" data-element-id="Flow_0u7wl2h" style="display: block;"><g class="djs-visual"><path d="m 668,400L732,400 " style="fill: none; stroke-width: 2px; stroke: black; stroke-linejoin: round; marker-end: url('#sequenceflow-end-white-black-att51rfxz5xb2bplwaj1r4xi8');"/></g><polyline points="668,400 732,400 " class="djs-hit djs-hit-stroke" style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;"/><rect x="662" y="394" width="76" height="12" class="djs-outline" style="fill: none;"/></g></g><g class="djs-group"><g class="djs-element djs-shape" data-element-id="Activity_1qh9sf8" style="display: block;" transform="matrix(1 0 0 1 270 137)"><g class="djs-visual"><rect x="0" y="0" width="100" height="80" rx="10" ry="10" style="stroke: black; stroke-width: 2px; fill: white; fill-opacity: 0.95;"/><text lineHeight="1.2" class="djs-label" style="font-family: Arial, sans-serif; font-size: 12px; font-weight: normal; fill: black;"><tspan x="32.65625" y="43.599999999999994">Task 1</tspan></text></g><rect class="djs-hit djs-hit-all" x="0" y="0" width="100" height="80" style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;"/><rect x="-6" y="-6" width="112" height="92" class="djs-outline" style="fill: none;"/></g></g><g class="djs-group"><g class="djs-element djs-shape" data-element-id="Gateway_0bsqjma" style="display: block;" transform="matrix(1 0 0 1 525 152)"><g class="djs-visual"><polygon points="25,0 50,25 25,50 0,25" style="stroke: black; stroke-width: 2px; fill: white; fill-opacity: 0.95;"/><circle cx="25" cy="25" r="15" style="stroke: black; stroke-width: 1px; fill: none;"/><circle cx="25" cy="25" r="12" style="stroke: black; stroke-width: 1px; fill: none;"/><path d="m 18,22 7.363636363636364,-4.909090909090909 7.363636363636364,4.909090909090909 -2.4545454545454546,9.818181818181818 -9.818181818181818,0 z" style="fill: none; stroke-width: 2px; stroke: black;"/></g><rect class="djs-hit djs-hit-all" x="0" y="0" width="50" height="50" style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;"/><rect x="-6" y="-6" width="62" height="62" class="djs-outline" style="fill: none;"/></g></g><g class="djs-group"><g class="djs-element djs-shape" data-element-id="Event_0qbztd3" style="display: block;" transform="matrix(1 0 0 1 632 159)"><g class="djs-visual"><circle cx="18" cy="18" r="18" style="stroke: black; stroke-width: 1px; fill: white; fill-opacity: 0.95;"/><circle cx="18" cy="18" r="15" style="stroke: black; stroke-width: 1px; fill: none;"/><path d="m 8.459999999999999,11.34 l 0,12.6 l 18.900000000000002,0 l 0,-12.6 z l 9.450000000000001,5.4 l 9.450000000000001,-5.4" style="fill: white; stroke-width: 1px; stroke: black;"/></g><rect class="djs-hit djs-hit-all" x="0" y="0" width="36" height="36" style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;"/><rect x="-6" y="-6" width="48" height="48" class="djs-outline" style="fill: none;"/></g></g><g class="djs-group"><g class="djs-element djs-shape" data-element-id="Event_1pwd0kq" style="display: block;" transform="matrix(1 0 0 1 732 159)"><g class="djs-visual"><circle cx="18" cy="18" r="18" style="stroke: black; stroke-width: 4px; fill: white; fill-opacity: 0.95;"/></g><rect class="djs-hit djs-hit-all" x="0" y="0" width="36" height="36" style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;"/><rect x="-6" y="-6" width="48" height="48" class="djs-outline" style="fill: none;"/></g></g><g class="djs-group"><g class="djs-element djs-shape" data-element-id="Event_1voo3le" style="display: block;" transform="matrix(1 0 0 1 732 272)"><g class="djs-visual"><circle cx="18" cy="18" r="18" style="stroke: black; stroke-width: 4px; fill: white; fill-opacity: 0.95;"/></g><rect class="djs-hit djs-hit-all" x="0" y="0" width="36" height="36" style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;"/><rect x="-6" y="-6" width="48" height="48" class="djs-outline" style="fill: none;"/></g></g><g class="djs-group"><g class="djs-element djs-shape" data-element-id="Event_1ndrm5j" style="display: block;" transform="matrix(1 0 0 1 422 159)"><g class="djs-visual"><circle cx="18" cy="18" r="18" style="stroke: black; stroke-width: 1px; fill: white; fill-opacity: 0.95;"/><circle cx="18" cy="18" r="15" style="stroke: black; stroke-width: 1px; fill: none;"/><path d="m 8.459999999999999,11.34 l 0,12.6 l 18.900000000000002,0 l 0,-12.6 z l 9.450000000000001,5.4 l 9.450000000000001,-5.4" style="fill: black; stroke-width: 1px; stroke: white;"/></g><rect class="djs-hit djs-hit-all" x="0" y="0" width="36" height="36" style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;"/><rect x="-6" y="-6" width="48" height="48" class="djs-outline" style="fill: none;"/></g></g><g class="djs-group"><g class="djs-element djs-shape" data-element-id="Event_0pq5qbd" style="display: block;" transform="matrix(1 0 0 1 632 272)"><g class="djs-visual"><circle cx="18" cy="18" r="18" style="stroke: black; stroke-width: 1px; fill: white; fill-opacity: 0.95;"/><circle cx="18" cy="18" r="15" style="stroke: black; stroke-width: 1px; fill: none;"/><path d="m 8.459999999999999,11.34 l 0,12.6 l 18.900000000000002,0 l 0,-12.6 z l 9.450000000000001,5.4 l 9.450000000000001,-5.4" style="fill: white; stroke-width: 1px; stroke: black;"/></g><rect class="djs-hit djs-hit-all" x="0" y="0" width="36" height="36" style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;"/><rect x="-6" y="-6" width="48" height="48" class="djs-outline" style="fill: none;"/></g></g><g class="djs-group"><g class="djs-element djs-shape" data-element-id="Event_18u9tw6" style="display: block;" transform="matrix(1 0 0 1 632 382)"><g class="djs-visual"><circle cx="18" cy="18" r="18" style="stroke: black; stroke-width: 1px; fill: white; fill-opacity: 0.95;"/><circle cx="18" cy="18" r="15" style="stroke: black; stroke-width: 1px; fill: none;"/><circle cx="18" cy="18" r="11" style="stroke: black; stroke-width: 2px; fill: white;"/><path d="M 18,18 l 2.25,-7.5 m -2.25,7.5 l 5.25,1.5 " style="fill: none; stroke-width: 2px; stroke: black; stroke-linecap: square;"/><path d="M 18,18 m 0,7.5 l -0,2.25 " transform="rotate(0,18,18)" style="fill: none; stroke-width: 1px; stroke: black; stroke-linecap: square;"/><path d="M 18,18 m 0,7.5 l -0,2.25 " transform="rotate(30,18,18)" style="fill: none; stroke-width: 1px; stroke: black; stroke-linecap: square;"/><path d="M 18,18 m 0,7.5 l -0,2.25 " transform="rotate(60,18,18)" style="fill: none; stroke-width: 1px; stroke: black; stroke-linecap: square;"/><path d="M 18,18 m 0,7.5 l -0,2.25 " transform="rotate(90,18,18)" style="fill: none; stroke-width: 1px; stroke: black; stroke-linecap: square;"/><path d="M 18,18 m 0,7.5 l -0,2.25 " transform="rotate(120,18,18)" style="fill: none; stroke-width: 1px; stroke: black; stroke-linecap: square;"/><path d="M 18,18 m 0,7.5 l -0,2.25 " transform="rotate(150,18,18)" style="fill: none; stroke-width: 1px; stroke: black; stroke-linecap: square;"/><path d="M 18,18 m 0,7.5 l -0,2.25 " transform="rotate(180,18,18)" style="fill: none; stroke-width: 1px; stroke: black; stroke-linecap: square;"/><path d="M 18,18 m 0,7.5 l -0,2.25 " transform="rotate(210,18,18)" style="fill: none; stroke-width: 1px; stroke: black; stroke-linecap: square;"/><path d="M 18,18 m 0,7.5 l -0,2.25 " transform="rotate(240,18,18)" style="fill: none; stroke-width: 1px; stroke: black; stroke-linecap: square;"/><path d="M 18,18 m 0,7.5 l -0,2.25 " transform="rotate(270,18,18)" style="fill: none; stroke-width: 1px; stroke: black; stroke-linecap: square;"/><path d="M 18,18 m 0,7.5 l -0,2.25 " transform="rotate(300,18,18)" style="fill: none; stroke-width: 1px; stroke: black; stroke-linecap: square;"/><path d="M 18,18 m 0,7.5 l -0,2.25 " transform="rotate(330,18,18)" style="fill: none; stroke-width: 1px; stroke: black; stroke-linecap: square;"/></g><rect class="djs-hit djs-hit-all" x="0" y="0" width="36" height="36" style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;"/><rect x="-6" y="-6" width="48" height="48" class="djs-outline" style="fill: none;"/></g></g><g class="djs-group"><g class="djs-element djs-shape" data-element-id="Event_1uh09e9" style="display: block;" transform="matrix(1 0 0 1 732 382)"><g class="djs-visual"><circle cx="18" cy="18" r="18" style="stroke: black; stroke-width: 4px; fill: white; fill-opacity: 0.95;"/></g><rect class="djs-hit djs-hit-all" x="0" y="0" width="36" height="36" style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;"/><rect x="-6" y="-6" width="48" height="48" class="djs-outline" style="fill: none;"/></g></g><g class="djs-group"><g class="djs-element djs-shape" data-element-id="Event_1uh09e9_label" style="display: block;" transform="matrix(1 0 0 1 733 425)"><g class="djs-visual"><text lineHeight="1.2" class="djs-label" style="font-family: Arial, sans-serif; font-size: 11px; font-weight: normal; fill: black;"><tspan x="0" y="9.899999999999999">Failure</tspan></text></g><rect class="djs-hit djs-hit-all" x="0" y="0" width="34" height="14" style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;"/><rect x="-6" y="-6" width="46" height="26" class="djs-outline" style="fill: none;"/></g></g><g class="djs-group"><g class="djs-element djs-shape" data-element-id="StartEvent_1" style="display: block;" transform="matrix(1 0 0 1 179 159)"><g class="djs-visual"><circle cx="18" cy="18" r="18" style="stroke: black; stroke-width: 2px; fill: white; fill-opacity: 0.95;"/><path d="m 8.459999999999999,11.34 l 0,12.6 l 18.900000000000002,0 l 0,-12.6 z l 9.450000000000001,5.4 l 9.450000000000001,-5.4" style="fill: white; stroke-width: 1px; stroke: black;"/></g><rect class="djs-hit djs-hit-all" x="0" y="0" width="36" height="36" style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;"/><rect x="-6" y="-6" width="48" height="48" class="djs-outline" style="fill: none;"/></g></g></g></g><g class="djs-group"><g class="djs-element djs-shape" data-element-id="Event_1pwd0kq_label" style="display: block;" transform="matrix(1 0 0 1 729 202)"><g class="djs-visual"><text lineHeight="1.2" class="djs-label" style="font-family: Arial, sans-serif; font-size: 11px; font-weight: normal; fill: black;"><tspan x="0" y="9.899999999999999">Option A</tspan></text></g><rect class="djs-hit djs-hit-all" x="0" y="0" width="44" height="14" style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;"/><rect x="-6" y="-6" width="56" height="26" class="djs-outline" style="fill: none;"/></g></g><g class="djs-group"><g class="djs-element djs-shape" data-element-id="Event_1voo3le_label" style="display: block;" transform="matrix(1 0 0 1 729 315)"><g class="djs-visual"><text lineHeight="1.2" class="djs-label" style="font-family: Arial, sans-serif; font-size: 11px; font-weight: normal; fill: black;"><tspan x="0" y="9.899999999999999">Option B</tspan></text></g><rect class="djs-hit djs-hit-all" x="0" y="0" width="43" height="14" style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;"/><rect x="-6" y="-6" width="55" height="26" class="djs-outline" style="fill: none;"/></g></g><g class="djs-group"><g class="djs-element djs-shape" data-element-id="Participant_0h427kw" style="display: block;" transform="matrix(1 0 0 1 890 100)"><g class="djs-visual"><rect x="0" y="0" width="300" height="360" rx="0" ry="0" style="stroke: black; stroke-width: 2px; fill: white; fill-opacity: 0.95;"/><polyline points="30,0 30,360 " style="fill: none; stroke: black; stroke-width: 2px;"/><text lineHeight="1.2" class="djs-label" style="font-family: Arial, sans-serif; font-size: 12px; font-weight: normal; fill: black;" transform="matrix(-1.83697e-16 -1 1 -1.83697e-16 0 360)"><tspan x="140.9765625" y="18.6">Organization 2</tspan></text></g><rect x="-6" y="-6" width="312" height="372" class="djs-outline" style="fill: none;"/><rect class="djs-hit djs-hit-click-stroke" x="0" y="0" width="300" height="360" style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;"/><rect class="djs-hit djs-hit-all" x="0" y="0" width="30" height="360" style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;"/></g><g class="djs-children"/></g><g class="djs-group"><g class="djs-element djs-connection" data-element-id="Flow_0sswg90" style="display: block;"><g class="djs-visual"><path d="m 440,159L440,130 L890,130 " style="fill: none; stroke-width: 1.5px; stroke: black; marker-end: url('#messageflow-end-white-black-att51rfxz5xb2bplwaj1r4xi8'); marker-start: url('#messageflow-start-white-black-att51rfxz5xb2bplwaj1r4xi8'); stroke-dasharray: 10, 12; stroke-linecap: round; stroke-linejoin: round;"/></g><polyline points="440,159 440,130 890,130 " class="djs-hit djs-hit-stroke" style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;"/><rect x="434" y="124" width="462" height="41" class="djs-outline" style="fill: none;"/></g></g><g class="djs-group"><g class="djs-element djs-connection" data-element-id="Flow_1wjv8rh" style="display: block;"><g class="djs-visual"><path d="m 890,230L650,230 L650,195 " style="fill: none; stroke-width: 1.5px; stroke: black; marker-end: url('#messageflow-end-white-black-att51rfxz5xb2bplwaj1r4xi8'); marker-start: url('#messageflow-start-white-black-att51rfxz5xb2bplwaj1r4xi8'); stroke-dasharray: 10, 12; stroke-linecap: round; stroke-linejoin: round;"/></g><polyline points="890,230 650,230 650,195 " class="djs-hit djs-hit-stroke" style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;"/><rect x="644" y="189" width="252" height="47" class="djs-outline" style="fill: none;"/></g></g><g class="djs-group"><g class="djs-element djs-connection" data-element-id="Flow_0j7hwxl" style="display: block;"><g class="djs-visual"><path d="m 890,340L650,340 L650,308 " style="fill: none; stroke-width: 1.5px; stroke: black; marker-end: url('#messageflow-end-white-black-att51rfxz5xb2bplwaj1r4xi8'); marker-start: url('#messageflow-start-white-black-att51rfxz5xb2bplwaj1r4xi8'); stroke-dasharray: 10, 12; stroke-linecap: round; stroke-linejoin: round;"/></g><polyline points="890,340 650,340 650,308 " class="djs-hit djs-hit-stroke" style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;"/><rect x="644" y="302" width="252" height="44" class="djs-outline" style="fill: none;"/></g></g></svg> \ No newline at end of file + +<svg + width="1073" + height="372" + viewBox="123 94 1073 372" + version="1.1" + id="svg100" + sodipodi:docname="event_based_gateway.svg" + inkscape:version="1.3.2 (091e20e, 2023-11-25, custom)" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg"> + <sodipodi:namedview + id="namedview100" + pagecolor="#ffffff" + bordercolor="#000000" + borderopacity="0.25" + inkscape:showpageshadow="2" + inkscape:pageopacity="0.0" + inkscape:pagecheckerboard="0" + inkscape:deskcolor="#d1d1d1" + inkscape:zoom="2.8495151" + inkscape:cx="570.44793" + inkscape:cy="262.32533" + inkscape:window-width="1920" + inkscape:window-height="1121" + inkscape:window-x="-7" + inkscape:window-y="1613" + inkscape:window-maximized="1" + inkscape:current-layer="g79" /> + <defs + id="defs2"> + <marker + id="sequenceflow-end-white-black-att51rfxz5xb2bplwaj1r4xi8" + viewBox="0 0 20 20" + refX="11" + refY="10" + markerWidth="10" + markerHeight="10" + orient="auto"> + <path + d="M 1 5 L 11 10 L 1 15 Z" + style="fill: black; stroke-width: 1px; stroke-linecap: round; stroke-dasharray: 10000, 1; stroke: black;" + id="path1" /> + </marker> + <marker + id="messageflow-end-white-black-att51rfxz5xb2bplwaj1r4xi8" + viewBox="0 0 20 20" + refX="8.5" + refY="5" + markerWidth="20" + markerHeight="20" + orient="auto"> + <path + d="m 1 5 l 0 -3 l 7 3 l -7 3 z" + style="fill: white; stroke-width: 1px; stroke-linecap: butt; stroke-dasharray: 10000, 1; stroke: black;" + id="path2" /> + </marker> + <marker + id="messageflow-start-white-black-att51rfxz5xb2bplwaj1r4xi8" + viewBox="0 0 20 20" + refX="6" + refY="6" + markerWidth="20" + markerHeight="20" + orient="auto"> + <circle + cx="6" + cy="6" + r="3.5" + style="fill: white; stroke-width: 1px; stroke-linecap: round; stroke-dasharray: 10000, 1; stroke: black;" + id="circle2" /> + </marker> + </defs> + <g + class="djs-group" + id="g80"> + <g + class="djs-element djs-shape" + data-element-id="Participant_1u3es88" + style="display: block;" + transform="matrix(1 0 0 1 129 100)" + id="g5"> + <g + class="djs-visual" + id="g2"> + <rect + x="0" + y="0" + width="660" + height="360" + rx="0" + ry="0" + style="stroke: black; stroke-width: 2px; fill: white; fill-opacity: 0.95;" + id="rect2" /> + <polyline + points="30,0 30,360 " + style="fill: none; stroke: black; stroke-width: 2px;" + id="polyline2" /> + <text + lineHeight="1.2" + class="djs-label" + style="font-family: Arial, sans-serif; font-size: 12px; font-weight: normal; fill: black;" + transform="matrix(-1.83697e-16 -1 1 -1.83697e-16 0 360)" + id="text2"><tspan + x="140.9765625" + y="18.6" + id="tspan2">Organization 1</tspan></text> + </g> + <rect + x="-6" + y="-6" + width="672" + height="372" + class="djs-outline" + style="fill: none;" + id="rect3" /> + <rect + class="djs-hit djs-hit-click-stroke" + x="0" + y="0" + width="660" + height="360" + style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;" + id="rect4" /> + <rect + class="djs-hit djs-hit-all" + x="0" + y="0" + width="30" + height="360" + style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;" + id="rect5" /> + </g> + <g + class="djs-children" + id="g79"> + <g + class="djs-group" + id="g8"> + <g + class="djs-element djs-connection" + data-element-id="Flow_1vux1af" + style="display: block;" + id="g7"> + <g + class="djs-visual" + id="g6"> + <path + d="m 215,177L270,177 " + style="fill: none; stroke-width: 2px; stroke: black; stroke-linejoin: round; marker-end: url('#sequenceflow-end-white-black-att51rfxz5xb2bplwaj1r4xi8');" + id="path5" /> + </g> + <polyline + points="215,177 270,177 " + class="djs-hit djs-hit-stroke" + style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;" + id="polyline6" /> + <rect + x="209" + y="171" + width="67" + height="12" + class="djs-outline" + style="fill: none;" + id="rect6" /> + </g> + </g> + <g + class="djs-group" + id="g11"> + <g + class="djs-element djs-connection" + data-element-id="Flow_1i7hh0u" + style="display: block;" + id="g10"> + <g + class="djs-visual" + id="g9"> + <path + d="m 370,177L422,177 " + style="fill: none; stroke-width: 2px; stroke: black; stroke-linejoin: round; marker-end: url('#sequenceflow-end-white-black-att51rfxz5xb2bplwaj1r4xi8');" + id="path8" /> + </g> + <polyline + points="370,177 422,177 " + class="djs-hit djs-hit-stroke" + style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;" + id="polyline9" /> + <rect + x="364" + y="171" + width="64" + height="12" + class="djs-outline" + style="fill: none;" + id="rect9" /> + </g> + </g> + <g + class="djs-group" + id="g14"> + <g + class="djs-element djs-connection" + data-element-id="Flow_19hvbdm" + style="display: block;" + id="g13"> + <g + class="djs-visual" + id="g12"> + <path + d="m 575,177L632,177 " + style="fill: none; stroke-width: 2px; stroke: black; stroke-linejoin: round; marker-end: url('#sequenceflow-end-white-black-att51rfxz5xb2bplwaj1r4xi8');" + id="path11" /> + </g> + <polyline + points="575,177 632,177 " + class="djs-hit djs-hit-stroke" + style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;" + id="polyline12" /> + <rect + x="569" + y="171" + width="69" + height="12" + class="djs-outline" + style="fill: none;" + id="rect12" /> + </g> + </g> + <g + class="djs-group" + id="g17"> + <g + class="djs-element djs-connection" + data-element-id="Flow_1pre2mk" + style="display: block;" + id="g16"> + <g + class="djs-visual" + id="g15"> + <path + d="m 550,202L550,290 L632,290 " + style="fill: none; stroke-width: 2px; stroke: black; stroke-linejoin: round; marker-end: url('#sequenceflow-end-white-black-att51rfxz5xb2bplwaj1r4xi8');" + id="path14" /> + </g> + <polyline + points="550,202 550,290 632,290 " + class="djs-hit djs-hit-stroke" + style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;" + id="polyline15" /> + <rect + x="544" + y="196" + width="94" + height="100" + class="djs-outline" + style="fill: none;" + id="rect15" /> + </g> + </g> + <g + class="djs-group" + id="g20"> + <g + class="djs-element djs-connection" + data-element-id="Flow_0fn66bz" + style="display: block;" + id="g19"> + <g + class="djs-visual" + id="g18"> + <path + d="m 668,177L732,177 " + style="fill: none; stroke-width: 2px; stroke: black; stroke-linejoin: round; marker-end: url('#sequenceflow-end-white-black-att51rfxz5xb2bplwaj1r4xi8');" + id="path17" /> + </g> + <polyline + points="668,177 732,177 " + class="djs-hit djs-hit-stroke" + style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;" + id="polyline18" /> + <rect + x="662" + y="171" + width="76" + height="12" + class="djs-outline" + style="fill: none;" + id="rect18" /> + </g> + </g> + <g + class="djs-group" + id="g23"> + <g + class="djs-element djs-connection" + data-element-id="Flow_1qeyly0" + style="display: block;" + id="g22"> + <g + class="djs-visual" + id="g21"> + <path + d="m 668,290L732,290 " + style="fill: none; stroke-width: 2px; stroke: black; stroke-linejoin: round; marker-end: url('#sequenceflow-end-white-black-att51rfxz5xb2bplwaj1r4xi8');" + id="path20" /> + </g> + <polyline + points="668,290 732,290 " + class="djs-hit djs-hit-stroke" + style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;" + id="polyline21" /> + <rect + x="662" + y="284" + width="76" + height="12" + class="djs-outline" + style="fill: none;" + id="rect21" /> + </g> + </g> + <g + class="djs-group" + id="g26"> + <g + class="djs-element djs-connection" + data-element-id="Flow_1cwt97i" + style="display: block;" + id="g25"> + <g + class="djs-visual" + id="g24"> + <path + d="m 458,177L525,177 " + style="fill: none; stroke-width: 2px; stroke: black; stroke-linejoin: round; marker-end: url('#sequenceflow-end-white-black-att51rfxz5xb2bplwaj1r4xi8');" + id="path23" /> + </g> + <polyline + points="458,177 525,177 " + class="djs-hit djs-hit-stroke" + style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;" + id="polyline24" /> + <rect + x="452" + y="171" + width="79" + height="12" + class="djs-outline" + style="fill: none;" + id="rect24" /> + </g> + </g> + <g + class="djs-group" + id="g29"> + <g + class="djs-element djs-connection" + data-element-id="Flow_1bf7gvl" + style="display: block;" + id="g28"> + <g + class="djs-visual" + id="g27"> + <path + d="m 550,202L550,400 L632,400 " + style="fill: none; stroke-width: 2px; stroke: black; stroke-linejoin: round; marker-end: url('#sequenceflow-end-white-black-att51rfxz5xb2bplwaj1r4xi8');" + id="path26" /> + </g> + <polyline + points="550,202 550,400 632,400 " + class="djs-hit djs-hit-stroke" + style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;" + id="polyline27" /> + <rect + x="544" + y="196" + width="94" + height="210" + class="djs-outline" + style="fill: none;" + id="rect27" /> + </g> + </g> + <g + class="djs-group" + id="g32"> + <g + class="djs-element djs-connection" + data-element-id="Flow_0u7wl2h" + style="display: block;" + id="g31"> + <g + class="djs-visual" + id="g30"> + <path + d="m 668,400L732,400 " + style="fill: none; stroke-width: 2px; stroke: black; stroke-linejoin: round; marker-end: url('#sequenceflow-end-white-black-att51rfxz5xb2bplwaj1r4xi8');" + id="path29" /> + </g> + <polyline + points="668,400 732,400 " + class="djs-hit djs-hit-stroke" + style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;" + id="polyline30" /> + <rect + x="662" + y="394" + width="76" + height="12" + class="djs-outline" + style="fill: none;" + id="rect30" /> + </g> + </g> + <g + class="djs-group" + id="g35"> + <g + class="djs-element djs-shape" + data-element-id="Activity_1qh9sf8" + style="display: block;" + transform="matrix(1 0 0 1 270 137)" + id="g34"> + <g + class="djs-visual" + id="g33"> + <rect + x="0" + y="0" + width="100" + height="80" + rx="10" + ry="10" + style="stroke: black; stroke-width: 2px; fill: white; fill-opacity: 0.95;" + id="rect32" /> + <text + lineHeight="1.2" + class="djs-label" + style="font-family: Arial, sans-serif; font-size: 12px; font-weight: normal; fill: black;" + id="text32"><tspan + x="32.65625" + y="43.599999999999994" + id="tspan32">Task 1</tspan></text> + </g> + <rect + class="djs-hit djs-hit-all" + x="0" + y="0" + width="100" + height="80" + style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;" + id="rect33" /> + <rect + x="-6" + y="-6" + width="112" + height="92" + class="djs-outline" + style="fill: none;" + id="rect34" /> + </g> + </g> + <g + class="djs-group" + id="g38"> + <g + class="djs-element djs-shape" + data-element-id="Gateway_0bsqjma" + style="display: block;" + transform="matrix(1 0 0 1 525 152)" + id="g37"> + <g + class="djs-visual" + id="g36"> + <polygon + points="25,0 50,25 25,50 0,25" + style="stroke: black; stroke-width: 2px; fill: white; fill-opacity: 0.95;" + id="polygon35" /> + <circle + cx="25" + cy="25" + r="15" + style="stroke: black; stroke-width: 1px; fill: none;" + id="circle35" /> + <circle + cx="25" + cy="25" + r="12" + style="stroke: black; stroke-width: 1px; fill: none;" + id="circle36" /> + <path + d="m 18,22 7.363636363636364,-4.909090909090909 7.363636363636364,4.909090909090909 -2.4545454545454546,9.818181818181818 -9.818181818181818,0 z" + style="fill: none; stroke-width: 2px; stroke: black;" + id="path36" /> + </g> + <rect + class="djs-hit djs-hit-all" + x="0" + y="0" + width="50" + height="50" + style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;" + id="rect36" /> + <rect + x="-6" + y="-6" + width="62" + height="62" + class="djs-outline" + style="fill: none;" + id="rect37" /> + </g> + </g> + <g + class="djs-group" + id="g41"> + <g + class="djs-element djs-shape" + data-element-id="Event_0qbztd3" + style="display: block;" + transform="matrix(1 0 0 1 632 159)" + id="g40"> + <g + class="djs-visual" + id="g39"> + <circle + cx="18" + cy="18" + r="18" + style="stroke: black; stroke-width: 1px; fill: white; fill-opacity: 0.95;" + id="circle38" /> + <circle + cx="18" + cy="18" + r="15" + style="stroke: black; stroke-width: 1px; fill: none;" + id="circle39" /> + <path + d="m 8.459999999999999,11.34 l 0,12.6 l 18.900000000000002,0 l 0,-12.6 z l 9.450000000000001,5.4 l 9.450000000000001,-5.4" + style="fill: white; stroke-width: 1px; stroke: black;" + id="path39" /> + </g> + <rect + class="djs-hit djs-hit-all" + x="0" + y="0" + width="36" + height="36" + style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;" + id="rect39" /> + <rect + x="-6" + y="-6" + width="48" + height="48" + class="djs-outline" + style="fill: none;" + id="rect40" /> + </g> + </g> + <g + class="djs-group" + id="g44"> + <g + class="djs-element djs-shape" + data-element-id="Event_1pwd0kq" + style="display: block;" + transform="matrix(1 0 0 1 732 159)" + id="g43"> + <g + class="djs-visual" + id="g42"> + <circle + cx="18" + cy="18" + r="18" + style="stroke: black; stroke-width: 4px; fill: white; fill-opacity: 0.95;" + id="circle41" /> + </g> + <rect + class="djs-hit djs-hit-all" + x="0" + y="0" + width="36" + height="36" + style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;" + id="rect42" /> + <rect + x="-6" + y="-6" + width="48" + height="48" + class="djs-outline" + style="fill: none;" + id="rect43" /> + </g> + </g> + <g + class="djs-group" + id="g47"> + <g + class="djs-element djs-shape" + data-element-id="Event_1voo3le" + style="display: block;" + transform="matrix(1 0 0 1 732 272)" + id="g46"> + <g + class="djs-visual" + id="g45"> + <circle + cx="18" + cy="18" + r="18" + style="stroke: black; stroke-width: 4px; fill: white; fill-opacity: 0.95;" + id="circle44" /> + </g> + <rect + class="djs-hit djs-hit-all" + x="0" + y="0" + width="36" + height="36" + style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;" + id="rect45" /> + <rect + x="-6" + y="-6" + width="48" + height="48" + class="djs-outline" + style="fill: none;" + id="rect46" /> + </g> + </g> + <g + class="djs-group" + id="g50"> + <g + class="djs-element djs-shape" + data-element-id="Event_1ndrm5j" + style="display: block;" + transform="matrix(1 0 0 1 422 159)" + id="g49"> + <g + class="djs-visual" + id="g48"> + <circle + cx="18" + cy="18" + r="18" + style="stroke: black; stroke-width: 1px; fill: white; fill-opacity: 0.95;" + id="circle47" /> + <circle + cx="18" + cy="18" + r="15" + style="stroke: black; stroke-width: 1px; fill: none;" + id="circle48" /> + <path + d="m 8.459999999999999,11.34 l 0,12.6 l 18.900000000000002,0 l 0,-12.6 z l 9.450000000000001,5.4 l 9.450000000000001,-5.4" + style="fill: black; stroke-width: 1px; stroke: white;" + id="path48" /> + </g> + <rect + class="djs-hit djs-hit-all" + x="0" + y="0" + width="36" + height="36" + style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;" + id="rect48" /> + <rect + x="-6" + y="-6" + width="48" + height="48" + class="djs-outline" + style="fill: none;" + id="rect49" /> + </g> + </g> + <g + class="djs-group" + id="g53"> + <g + class="djs-element djs-shape" + data-element-id="Event_0pq5qbd" + style="display: block;" + transform="matrix(1 0 0 1 632 272)" + id="g52"> + <g + class="djs-visual" + id="g51"> + <circle + cx="18" + cy="18" + r="18" + style="stroke: black; stroke-width: 1px; fill: white; fill-opacity: 0.95;" + id="circle50" /> + <circle + cx="18" + cy="18" + r="15" + style="stroke: black; stroke-width: 1px; fill: none;" + id="circle51" /> + <path + d="m 8.459999999999999,11.34 l 0,12.6 l 18.900000000000002,0 l 0,-12.6 z l 9.450000000000001,5.4 l 9.450000000000001,-5.4" + style="fill: white; stroke-width: 1px; stroke: black;" + id="path51" /> + </g> + <rect + class="djs-hit djs-hit-all" + x="0" + y="0" + width="36" + height="36" + style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;" + id="rect51" /> + <rect + x="-6" + y="-6" + width="48" + height="48" + class="djs-outline" + style="fill: none;" + id="rect52" /> + </g> + </g> + <g + class="djs-group" + id="g69"> + <g + class="djs-element djs-shape" + data-element-id="Event_18u9tw6" + style="display: block;" + transform="matrix(1 0 0 1 632 382)" + id="g68"> + <g + class="djs-visual" + id="g67"> + <circle + cx="18" + cy="18" + r="18" + style="stroke: black; stroke-width: 1px; fill: white; fill-opacity: 0.95;" + id="circle53" /> + <circle + cx="18" + cy="18" + r="15" + style="stroke: black; stroke-width: 1px; fill: none;" + id="circle54" /> + <circle + cx="18" + cy="18" + r="11" + style="stroke: black; stroke-width: 2px; fill: white;" + id="circle55" /> + <path + d="M 18,18 l 2.25,-7.5 m -2.25,7.5 l 5.25,1.5 " + style="fill: none; stroke-width: 2px; stroke: black; stroke-linecap: square;" + id="path55" /> + <path + d="M 18,18 m 0,7.5 l -0,2.25 " + transform="rotate(0,18,18)" + style="fill: none; stroke-width: 1px; stroke: black; stroke-linecap: square;" + id="path56" /> + <path + d="M 18,18 m 0,7.5 l -0,2.25 " + transform="rotate(30,18,18)" + style="fill: none; stroke-width: 1px; stroke: black; stroke-linecap: square;" + id="path57" /> + <path + d="M 18,18 m 0,7.5 l -0,2.25 " + transform="rotate(60,18,18)" + style="fill: none; stroke-width: 1px; stroke: black; stroke-linecap: square;" + id="path58" /> + <path + d="M 18,18 m 0,7.5 l -0,2.25 " + transform="rotate(90,18,18)" + style="fill: none; stroke-width: 1px; stroke: black; stroke-linecap: square;" + id="path59" /> + <path + d="M 18,18 m 0,7.5 l -0,2.25 " + transform="rotate(120,18,18)" + style="fill: none; stroke-width: 1px; stroke: black; stroke-linecap: square;" + id="path60" /> + <path + d="M 18,18 m 0,7.5 l -0,2.25 " + transform="rotate(150,18,18)" + style="fill: none; stroke-width: 1px; stroke: black; stroke-linecap: square;" + id="path61" /> + <path + d="M 18,18 m 0,7.5 l -0,2.25 " + transform="rotate(180,18,18)" + style="fill: none; stroke-width: 1px; stroke: black; stroke-linecap: square;" + id="path62" /> + <path + d="M 18,18 m 0,7.5 l -0,2.25 " + transform="rotate(210,18,18)" + style="fill: none; stroke-width: 1px; stroke: black; stroke-linecap: square;" + id="path63" /> + <path + d="M 18,18 m 0,7.5 l -0,2.25 " + transform="rotate(240,18,18)" + style="fill: none; stroke-width: 1px; stroke: black; stroke-linecap: square;" + id="path64" /> + <path + d="M 18,18 m 0,7.5 l -0,2.25 " + transform="rotate(270,18,18)" + style="fill: none; stroke-width: 1px; stroke: black; stroke-linecap: square;" + id="path65" /> + <path + d="M 18,18 m 0,7.5 l -0,2.25 " + transform="rotate(300,18,18)" + style="fill: none; stroke-width: 1px; stroke: black; stroke-linecap: square;" + id="path66" /> + <path + d="M 18,18 m 0,7.5 l -0,2.25 " + transform="rotate(330,18,18)" + style="fill: none; stroke-width: 1px; stroke: black; stroke-linecap: square;" + id="path67" /> + </g> + <rect + class="djs-hit djs-hit-all" + x="0" + y="0" + width="36" + height="36" + style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;" + id="rect67" /> + <rect + x="-6" + y="-6" + width="48" + height="48" + class="djs-outline" + style="fill: none;" + id="rect68" /> + </g> + </g> + <g + class="djs-group" + id="g72"> + <g + class="djs-element djs-shape" + data-element-id="Event_1uh09e9" + style="display: block;" + transform="matrix(1 0 0 1 732 382)" + id="g71"> + <g + class="djs-visual" + id="g70"> + <circle + cx="18" + cy="18" + r="18" + style="stroke: black; stroke-width: 4px; fill: white; fill-opacity: 0.95;" + id="circle69" /> + </g> + <rect + class="djs-hit djs-hit-all" + x="0" + y="0" + width="36" + height="36" + style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;" + id="rect70" /> + <rect + x="-6" + y="-6" + width="48" + height="48" + class="djs-outline" + style="fill: none;" + id="rect71" /> + </g> + </g> + <g + class="djs-group" + id="g75"> + <g + class="djs-element djs-shape" + data-element-id="Event_1uh09e9_label" + style="display: block;" + transform="matrix(1 0 0 1 733 425)" + id="g74"> + <g + class="djs-visual" + id="g73"> + <text + lineHeight="1.2" + class="djs-label" + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:11px;font-family:Arial, sans-serif;-inkscape-font-specification:'Arial, sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#000000" + id="text72" + x="-3.5093689" + y="8.4224854"><tspan + sodipodi:role="line" + id="tspan102" + x="-3.5093689" + y="8.4224854">Timeout</tspan></text> + </g> + <rect + class="djs-hit djs-hit-all" + x="0" + y="0" + width="34" + height="14" + style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;" + id="rect73" /> + <rect + x="-6" + y="-6" + width="46" + height="26" + class="djs-outline" + style="fill: none;" + id="rect74" /> + </g> + </g> + <g + class="djs-group" + id="g78"> + <g + class="djs-element djs-shape" + data-element-id="StartEvent_1" + style="display: block;" + transform="matrix(1 0 0 1 179 159)" + id="g77"> + <g + class="djs-visual" + id="g76"> + <circle + cx="18" + cy="18" + r="18" + style="stroke: black; stroke-width: 2px; fill: white; fill-opacity: 0.95;" + id="circle75" /> + <path + d="m 8.459999999999999,11.34 l 0,12.6 l 18.900000000000002,0 l 0,-12.6 z l 9.450000000000001,5.4 l 9.450000000000001,-5.4" + style="fill: white; stroke-width: 1px; stroke: black;" + id="path75" /> + </g> + <rect + class="djs-hit djs-hit-all" + x="0" + y="0" + width="36" + height="36" + style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;" + id="rect76" /> + <rect + x="-6" + y="-6" + width="48" + height="48" + class="djs-outline" + style="fill: none;" + id="rect77" /> + </g> + </g> + </g> + </g> + <g + class="djs-group" + id="g83" + transform="translate(-2.1056214,-0.3509369)"> + <g + class="djs-element djs-shape" + data-element-id="Event_1pwd0kq_label" + style="display:block" + transform="translate(729,202)" + id="g82"> + <g + class="djs-visual" + id="g81"> + <text + lineHeight="1.2" + class="djs-label" + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:11px;font-family:Arial, sans-serif;-inkscape-font-specification:'Arial, sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#000000" + id="text80" + inkscape:label="text80" + x="1.4037476" + y="9.8262329"><tspan + sodipodi:role="line" + id="tspan100" + x="1.4037476" + y="9.8262329">Success</tspan></text> + </g> + <rect + class="djs-hit djs-hit-all" + x="0" + y="0" + width="44" + height="14" + style="fill:none;stroke:#ffffff;stroke-width:15px;stroke-opacity:0" + id="rect81" /> + <rect + x="-6" + y="-6" + width="56" + height="26" + class="djs-outline" + style="fill:none" + id="rect82" /> + </g> + </g> + <g + class="djs-group" + id="g86" + transform="translate(-0.7018738,-1.0528107)"> + <g + class="djs-element djs-shape" + data-element-id="Event_1voo3le_label" + style="display:block" + transform="translate(729,315)" + id="g85"> + <g + class="djs-visual" + id="g84"> + <text + lineHeight="1.2" + class="djs-label" + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:11px;font-family:Arial, sans-serif;-inkscape-font-specification:'Arial, sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#000000" + id="text83" + x="4.5621796" + y="12.282791"><tspan + sodipodi:role="line" + id="tspan101" + x="4.5621796" + y="12.282791">Failure</tspan></text> + </g> + <rect + class="djs-hit djs-hit-all" + x="0" + y="0" + width="43" + height="14" + style="fill:none;stroke:#ffffff;stroke-width:15px;stroke-opacity:0" + id="rect84" /> + <rect + x="-6" + y="-6" + width="55" + height="26" + class="djs-outline" + style="fill:none" + id="rect85" /> + </g> + </g> + <g + class="djs-group" + id="g91"> + <g + class="djs-element djs-shape" + data-element-id="Participant_0h427kw" + style="display: block;" + transform="matrix(1 0 0 1 890 100)" + id="g89"> + <g + class="djs-visual" + id="g87"> + <rect + x="0" + y="0" + width="300" + height="360" + rx="0" + ry="0" + style="stroke: black; stroke-width: 2px; fill: white; fill-opacity: 0.95;" + id="rect86" /> + <polyline + points="30,0 30,360 " + style="fill: none; stroke: black; stroke-width: 2px;" + id="polyline86" /> + <text + lineHeight="1.2" + class="djs-label" + style="font-family: Arial, sans-serif; font-size: 12px; font-weight: normal; fill: black;" + transform="matrix(-1.83697e-16 -1 1 -1.83697e-16 0 360)" + id="text86"><tspan + x="140.9765625" + y="18.6" + id="tspan86">Organization 2</tspan></text> + </g> + <rect + x="-6" + y="-6" + width="312" + height="372" + class="djs-outline" + style="fill: none;" + id="rect87" /> + <rect + class="djs-hit djs-hit-click-stroke" + x="0" + y="0" + width="300" + height="360" + style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;" + id="rect88" /> + <rect + class="djs-hit djs-hit-all" + x="0" + y="0" + width="30" + height="360" + style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;" + id="rect89" /> + </g> + <g + class="djs-children" + id="g90" /> + </g> + <g + class="djs-group" + id="g94"> + <g + class="djs-element djs-connection" + data-element-id="Flow_0sswg90" + style="display: block;" + id="g93"> + <g + class="djs-visual" + id="g92"> + <path + d="m 440,159L440,130 L890,130 " + style="fill: none; stroke-width: 1.5px; stroke: black; marker-end: url('#messageflow-end-white-black-att51rfxz5xb2bplwaj1r4xi8'); marker-start: url('#messageflow-start-white-black-att51rfxz5xb2bplwaj1r4xi8'); stroke-dasharray: 10, 12; stroke-linecap: round; stroke-linejoin: round;" + id="path91" /> + </g> + <polyline + points="440,159 440,130 890,130 " + class="djs-hit djs-hit-stroke" + style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;" + id="polyline92" /> + <rect + x="434" + y="124" + width="462" + height="41" + class="djs-outline" + style="fill: none;" + id="rect92" /> + </g> + </g> + <g + class="djs-group" + id="g97"> + <g + class="djs-element djs-connection" + data-element-id="Flow_1wjv8rh" + style="display: block;" + id="g96"> + <g + class="djs-visual" + id="g95"> + <path + d="m 890,230L650,230 L650,195 " + style="fill: none; stroke-width: 1.5px; stroke: black; marker-end: url('#messageflow-end-white-black-att51rfxz5xb2bplwaj1r4xi8'); marker-start: url('#messageflow-start-white-black-att51rfxz5xb2bplwaj1r4xi8'); stroke-dasharray: 10, 12; stroke-linecap: round; stroke-linejoin: round;" + id="path94" /> + </g> + <polyline + points="890,230 650,230 650,195 " + class="djs-hit djs-hit-stroke" + style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;" + id="polyline95" /> + <rect + x="644" + y="189" + width="252" + height="47" + class="djs-outline" + style="fill: none;" + id="rect95" /> + </g> + </g> + <g + class="djs-group" + id="g100"> + <g + class="djs-element djs-connection" + data-element-id="Flow_0j7hwxl" + style="display: block;" + id="g99"> + <g + class="djs-visual" + id="g98"> + <path + d="m 890,340L650,340 L650,308 " + style="fill: none; stroke-width: 1.5px; stroke: black; marker-end: url('#messageflow-end-white-black-att51rfxz5xb2bplwaj1r4xi8'); marker-start: url('#messageflow-start-white-black-att51rfxz5xb2bplwaj1r4xi8'); stroke-dasharray: 10, 12; stroke-linecap: round; stroke-linejoin: round;" + id="path97" /> + </g> + <polyline + points="890,340 650,340 650,308 " + class="djs-hit djs-hit-stroke" + style="fill: none; stroke-opacity: 0; stroke: white; stroke-width: 15px;" + id="polyline98" /> + <rect + x="644" + y="302" + width="252" + height="44" + class="djs-outline" + style="fill: none;" + id="rect98" /> + </g> + </g> +</svg> diff --git a/docs/src/.vuepress/public/photos/developer-documentation/event_based_gateway_inverted.svg b/docs/src/.vuepress/public/photos/developer-documentation/event_based_gateway_inverted.svg index d278f7db6..75e269ffe 100644 --- a/docs/src/.vuepress/public/photos/developer-documentation/event_based_gateway_inverted.svg +++ b/docs/src/.vuepress/public/photos/developer-documentation/event_based_gateway_inverted.svg @@ -1,18 +1,19 @@ <?xml version="1.0" encoding="UTF-8" standalone="no"?> <svg - xmlns:dc="http://purl.org/dc/elements/1.1/" - xmlns:cc="http://creativecommons.org/ns#" - xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" - xmlns="http://www.w3.org/2000/svg" - xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" - xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" - width="1073" - height="372" - viewBox="123 94 1073 372" - version="1.1" - id="svg417" - sodipodi:docname="event_based_gateway_inverted.svg" - inkscape:version="1.0.1 (3bc2e813f5, 2020-09-07)"> + width="1073" + height="372" + viewBox="123 94 1073 372" + version="1.1" + id="svg417" + sodipodi:docname="event_based_gateway_inverted.svg" + inkscape:version="1.3.2 (091e20e, 2023-11-25, custom)" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> <metadata id="metadata421"> <rdf:RDF> @@ -21,7 +22,7 @@ <dc:format>image/svg+xml</dc:format> <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> - <dc:title></dc:title> + <dc:title /> </cc:Work> </rdf:RDF> </metadata> @@ -34,17 +35,20 @@ guidetolerance="10" inkscape:pageopacity="0" inkscape:pageshadow="2" - inkscape:window-width="3840" - inkscape:window-height="2081" + inkscape:window-width="1920" + inkscape:window-height="1121" id="namedview419" showgrid="false" - inkscape:zoom="1.1239515" - inkscape:cx="536.5" - inkscape:cy="186" - inkscape:window-x="-9" - inkscape:window-y="-9" + inkscape:zoom="2.247903" + inkscape:cx="595.44384" + inkscape:cy="249.78836" + inkscape:window-x="-7" + inkscape:window-y="1613" inkscape:window-maximized="1" - inkscape:current-layer="svg417" /> + inkscape:current-layer="g327" + inkscape:showpageshadow="2" + inkscape:pagecheckerboard="0" + inkscape:deskcolor="#d1d1d1" /> <defs id="defs11"> <marker @@ -91,7 +95,11 @@ <filter style="color-interpolation-filters:sRGB;" inkscape:label="Invert" - id="filter1604"> + id="filter1604" + x="-0.005952381" + y="0" + width="1.0059533" + height="1.0340909"> <feColorMatrix type="hueRotate" values="180" @@ -105,7 +113,11 @@ <filter style="color-interpolation-filters:sRGB;" inkscape:label="Invert" - id="filter1610"> + id="filter1610" + x="-0.005952381" + y="0" + width="1.0059533" + height="1.0319149"> <feColorMatrix type="hueRotate" values="180" @@ -119,7 +131,11 @@ <filter style="color-interpolation-filters:sRGB;" inkscape:label="Invert" - id="filter1616"> + id="filter1616" + x="-0.0032467532" + y="-0.036585366" + width="1.0032468" + height="1.0365912"> <feColorMatrix type="hueRotate" values="180" @@ -133,7 +149,11 @@ <filter style="color-interpolation-filters:sRGB;" inkscape:label="Invert" - id="filter1622"> + id="filter1622" + x="-0.0048076923" + y="-0.0040322581" + width="1.0096154" + height="1.0080645"> <feColorMatrix type="hueRotate" values="180" @@ -147,7 +167,11 @@ <filter style="color-interpolation-filters:sRGB;" inkscape:label="Invert" - id="filter1628"> + id="filter1628" + x="-0.027272727" + y="-0.057692308" + width="1.0545455" + height="1.1153846"> <feColorMatrix type="hueRotate" values="180" @@ -161,7 +185,11 @@ <filter style="color-interpolation-filters:sRGB;" inkscape:label="Invert" - id="filter1634"> + id="filter1634" + x="-0.026785714" + y="-0.057692308" + width="1.0535714" + height="1.1153846"> <feColorMatrix type="hueRotate" values="180" @@ -175,7 +203,11 @@ <filter style="color-interpolation-filters:sRGB;" inkscape:label="Invert" - id="filter1640"> + id="filter1640" + x="-0.0022321429" + y="-0.0040322581" + width="1.0044643" + height="1.0080645"> <feColorMatrix type="hueRotate" values="180" @@ -1009,11 +1041,14 @@ <text lineHeight="1.2" class="djs-label" - style="font-family: Arial, sans-serif; font-size: 11px; font-weight: normal; fill: black;" - id="text301"><tspan - x="0" - y="9.899999999999999" - id="tspan299">Failure</tspan></text> + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:11px;font-family:Arial, sans-serif;-inkscape-font-specification:'Arial, sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#000000" + id="text301" + x="-3.1140134" + y="8.0074625"><tspan + sodipodi:role="line" + id="tspan3" + x="-3.1140134" + y="8.0074625">Timeout</tspan></text> </g> <rect class="djs-hit djs-hit-all" @@ -1092,11 +1127,14 @@ <text lineHeight="1.2" class="djs-label" - style="font-family: Arial, sans-serif; font-size: 11px; font-weight: normal; fill: black;" - id="text333"><tspan - x="0" - y="9.899999999999999" - id="tspan331">Option A</tspan></text> + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:11px;font-family:Arial, sans-serif;-inkscape-font-specification:'Arial, sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#000000" + id="text333" + x="0.44485906" + y="9.3420401"><tspan + sodipodi:role="line" + id="tspan1" + x="0.44485906" + y="9.3420401">Success</tspan></text> </g> <rect class="djs-hit djs-hit-all" @@ -1132,11 +1170,14 @@ <text lineHeight="1.2" class="djs-label" - style="font-family: Arial, sans-serif; font-size: 11px; font-weight: normal; fill: black;" - id="text347"><tspan - x="0" - y="9.899999999999999" - id="tspan345">Option B</tspan></text> + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:11px;font-family:Arial, sans-serif;-inkscape-font-specification:'Arial, sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#000000" + id="text347" + x="4.0037313" + y="8.0074625"><tspan + sodipodi:role="line" + id="tspan2" + x="4.0037313" + y="8.0074625">Failure</tspan></text> </g> <rect class="djs-hit djs-hit-all" From 9f503060792d8e735ad3a785f862bb581611b0e1 Mon Sep 17 00:00:00 2001 From: Hauke Hund <hauke.hund@hs-heilbronn.de> Date: Mon, 27 May 2024 10:46:59 +0200 Subject: [PATCH 08/14] all camunda links to 7.18 for HiGHmed DSF tutorial --- .../tutorial/exercise1-simpleProcess.md | 2 +- .../tutorial/exercise3-messageEvents.md | 8 ++++---- .../tutorial/exercise4-exclusiveGateways.md | 6 +++--- .../tutorial/exercise5-eventBasedGateways.md | 18 +++++++++--------- 4 files changed, 17 insertions(+), 17 deletions(-) diff --git a/docs/src/oldstable/tutorial/exercise1-simpleProcess.md b/docs/src/oldstable/tutorial/exercise1-simpleProcess.md index 79b0ff39e..7e2cb54a0 100644 --- a/docs/src/oldstable/tutorial/exercise1-simpleProcess.md +++ b/docs/src/oldstable/tutorial/exercise1-simpleProcess.md @@ -22,7 +22,7 @@ Java code for the `tutorial-process` project is located at `src/main/java`, FHIR The most imported Java class used to specify the process plugin for the DSF BPE server is a class that implements the `org.highmed.dsf.bpe.ProcessPluginDefinition` interface from the DSF [dsf-bpe-process-base](https://github.com/highmed/highmed-dsf/packages/503054) module. The DSF BPE server searches for classes implementing this interface using the Java [ServiceLoader](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/ServiceLoader.html) mechanism. For this tutorial the `TutorialProcessPluginDefinition` class implements this interface. It is appropriately specified in the `src/main/resources/META-INF/services/org.highmed.dsf.bpe`.ProcessPluginDefinition file. The `TutorialProcessPluginDefinition` class is used to specify name and version of the process plugin, what BPMN processes are to be deployed and what FHIR resources and required by the BPMN processes. For the implementation of service task and message events of the processes a special Spring context is used for every process plugin. The `TutorialProcessPluginDefinition` class specifies what via [Spring-Framework configuration class](https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#beans-java-basic-concepts) with Spring Beans are used for the process plugin specific Spring Context. For this plugin the `TutorialConfig` cass is used to define Spring Beans. -The business process engine used by the DSF BPE server is based on the OpenSource Camunda Process Engine 7. In order to specify what Java code should be executed for a BPMN [ServiceTask](https://docs.camunda.org/manual/7.21/reference/bpmn20/tasks/service-task/) you need to specify the fully-qualified Java class name in the ServiceTask inside the BPMN model. To be executable the Java class needs to extend the `org.highmed.dsf.bpe.delegate.AbstractServiceDelegate` from the DSF [dsf-bpe-process-base](https://github.com/highmed/highmed-dsf/packages/503054) module and the class needs to be defined as as Spring Bean. +The business process engine used by the DSF BPE server is based on the OpenSource Camunda Process Engine 7. In order to specify what Java code should be executed for a BPMN [ServiceTask](https://docs.camunda.org/manual/7.18/reference/bpmn20/tasks/service-task/) you need to specify the fully-qualified Java class name in the ServiceTask inside the BPMN model. To be executable the Java class needs to extend the `org.highmed.dsf.bpe.delegate.AbstractServiceDelegate` from the DSF [dsf-bpe-process-base](https://github.com/highmed/highmed-dsf/packages/503054) module and the class needs to be defined as as Spring Bean. #### Process Execution and FHIR Task Resources diff --git a/docs/src/oldstable/tutorial/exercise3-messageEvents.md b/docs/src/oldstable/tutorial/exercise3-messageEvents.md index 09b5bbb1b..192792ecf 100644 --- a/docs/src/oldstable/tutorial/exercise3-messageEvents.md +++ b/docs/src/oldstable/tutorial/exercise3-messageEvents.md @@ -19,7 +19,7 @@ In order to exchange information between different processes, for example at two ![Message Flow](/photos/guideline/tutorial/ex3.png) -Every time message flow is used in a BPMN process for the DSF, a corresponding FHIR [Task](http://hl7.org/fhir/R4/task.html) profile needs to be specified for every interaction. This profile specifies which process should be started or continued and what the message name is when correlating the appropriate [Message Start Event](https://docs.camunda.org/manual/7.21/reference/bpmn20/events/message-events/#message-start-event) or [Intermediate Message Catch Event](https://docs.camunda.org/manual/7.21/reference/bpmn20/events/message-events/#message-intermediate-catching-event). A *Business Key* and a *Correlation Key* are specified if different process instances need to be linked to a single execution, for example to be able to send a message back. +Every time message flow is used in a BPMN process for the DSF, a corresponding FHIR [Task](http://hl7.org/fhir/R4/task.html) profile needs to be specified for every interaction. This profile specifies which process should be started or continued and what the message name is when correlating the appropriate [Message Start Event](https://docs.camunda.org/manual/7.18/reference/bpmn20/events/message-events/#message-start-event) or [Intermediate Message Catch Event](https://docs.camunda.org/manual/7.18/reference/bpmn20/events/message-events/#message-intermediate-catching-event). A *Business Key* and a *Correlation Key* are specified if different process instances need to be linked to a single execution, for example to be able to send a message back. #### BPMN Process Definition Key vs. FHIR Task.instantiatesUri and ActivityDefinition.url / version @@ -48,7 +48,7 @@ The authorization extension needs to be configured at least once and has four su ##### message-name [1..1] -String value specifying the message name of [Message Start Event](https://docs.camunda.org/manual/7.21/reference/bpmn20/events/message-events/#message-start-event), [Intermediate Message Catch Event](https://docs.camunda.org/manual/7.21/reference/bpmn20/events/message-events/#message-intermediate-catching-event) or [Message Receive Task](https://docs.camunda.org/manual/7.21/reference/bpmn20/tasks/receive-task/) this authorization rule should match. Can only be specified once per authorization rule extension. +String value specifying the message name of [Message Start Event](https://docs.camunda.org/manual/7.18/reference/bpmn20/events/message-events/#message-start-event), [Intermediate Message Catch Event](https://docs.camunda.org/manual/7.18/reference/bpmn20/events/message-events/#message-intermediate-catching-event) or [Message Receive Task](https://docs.camunda.org/manual/7.18/reference/bpmn20/tasks/receive-task/) this authorization rule should match. Can only be specified once per authorization rule extension. ##### task-profile [1..1] @@ -122,9 +122,9 @@ The following example specifies that process execution can only be requested by ### Exercise Tasks --- -1. Modify the ``highmedorg_helloDic`` process in the ``hello-dic.bpmn`` file and replace the [End Event](https://docs.camunda.org/manual/7.21/reference/bpmn20/events/none-events/#none-end-event) with a [Message End Event](https://docs.camunda.org/manual/7.21/reference/bpmn20/events/message-events/#message-end-event). Configure input parameters ``instantiatesUri``, ``profile`` and ``messageName`` in the BPMN model for the [Message End Event](https://docs.camunda.org/manual/7.21/reference/bpmn20/events/message-events/#message-end-event). Set the message name of the [Message End Event](https://docs.camunda.org/manual/7.21/reference/bpmn20/events/message-events/#message-end-event) and configure it to be executed using the HelloCosMessage class. +1. Modify the ``highmedorg_helloDic`` process in the ``hello-dic.bpmn`` file and replace the [End Event](https://docs.camunda.org/manual/7.18/reference/bpmn20/events/none-events/#none-end-event) with a [Message End Event](https://docs.camunda.org/manual/7.18/reference/bpmn20/events/message-events/#message-end-event). Configure input parameters ``instantiatesUri``, ``profile`` and ``messageName`` in the BPMN model for the [Message End Event](https://docs.camunda.org/manual/7.18/reference/bpmn20/events/message-events/#message-end-event). Set the message name of the [Message End Event](https://docs.camunda.org/manual/7.18/reference/bpmn20/events/message-events/#message-end-event) and configure it to be executed using the HelloCosMessage class. Use http://highmed.org/fhir/StructureDefinition/task-hello-cos|#{version} as the profile and ``helloCos`` as the message name. Figure out what the appropriate ``instantiatesUri`` value is, based on the name (process definition key) of the process to be triggered. -2. Modify the ``highmedorg_helloCos`` process in the ``hello-cos.bpmn`` file and configure the message name of the [Message Start Event](https://docs.camunda.org/manual/7.21/reference/bpmn20/events/message-events/#message-start-event) with the same value as the message name of the [Message End Event](https://docs.camunda.org/manual/7.21/reference/bpmn20/events/message-events/#message-end-event) in the ``highmedorg_helloDic`` process. +2. Modify the ``highmedorg_helloCos`` process in the ``hello-cos.bpmn`` file and configure the message name of the [Message Start Event](https://docs.camunda.org/manual/7.18/reference/bpmn20/events/message-events/#message-start-event) with the same value as the message name of the [Message End Event](https://docs.camunda.org/manual/7.18/reference/bpmn20/events/message-events/#message-end-event) in the ``highmedorg_helloDic`` process. 3. Create a new [StructureDefinition](http://hl7.org/fhir/R4/structuredefinition.html) with a [Task](http://hl7.org/fhir/R4/task.html) profile for the ``helloCos`` message. 4. Create a new [ActivityDefinition](http://hl7.org/fhir/R4/activitydefinition.html) resource for the ``highmedorg_helloCos`` process and configure the authorization extension to allow the ``Test_DIC`` organization as the requester and the ``Test_COS`` organization as the recipient. 5. Add the ``highmedorg_helloCos`` process and its resources to the ``TutorialProcessPluginDefinition`` class. diff --git a/docs/src/oldstable/tutorial/exercise4-exclusiveGateways.md b/docs/src/oldstable/tutorial/exercise4-exclusiveGateways.md index ed344a25c..2be5fd382 100644 --- a/docs/src/oldstable/tutorial/exercise4-exclusiveGateways.md +++ b/docs/src/oldstable/tutorial/exercise4-exclusiveGateways.md @@ -11,11 +11,11 @@ Different execution paths in a process based on the state of process variables c --- #### Exclusive Gateways -Different sequence flows during the execution of a process instance can be modeled using BPMN [Exclusive Gateways](https://docs.camunda.org/manual/7.4/reference/bpmn20/gateways/exclusive-gateway/). For each outgoing sequence flow of the gateway, a BPMN [Condition Expression](https://docs.camunda.org/manual/7.21/user-guide/process-engine/expression-language/#conditions) can be added to the process model, deciding whether a sequence flow should be followed. Thereby, all condition decisions must be in an XOR relationship to each other. +Different sequence flows during the execution of a process instance can be modeled using BPMN [Exclusive Gateways](https://docs.camunda.org/manual/7.18/reference/bpmn20/gateways/exclusive-gateway/). For each outgoing sequence flow of the gateway, a BPMN [Condition Expression](https://docs.camunda.org/manual/7.18/user-guide/process-engine/expression-language/#conditions) can be added to the process model, deciding whether a sequence flow should be followed. Thereby, all condition decisions must be in an XOR relationship to each other. #### Condition Expressions -A BPMN [Condition Expression](https://docs.camunda.org/manual/7.21/user-guide/process-engine/expression-language/#conditions) uses the ``${..}`` notation. Within the curly braces all execution variables of a process instance can be accessed, e.g. the ones that were stored in a previous Java implementation of a BPMN [ServiceTask](https://docs.camunda.org/manual/7.21/reference/bpmn20/tasks/service-task/). For example, the BPMN [Condition Expression](https://docs.camunda.org/manual/7.21/user-guide/process-engine/expression-language/#conditions) ``${cohortSize > 100}`` checks whether the value in the execution variable *cohortSize* is greater than 100. +A BPMN [Condition Expression](https://docs.camunda.org/manual/7.18/user-guide/process-engine/expression-language/#conditions) uses the ``${..}`` notation. Within the curly braces all execution variables of a process instance can be accessed, e.g. the ones that were stored in a previous Java implementation of a BPMN [ServiceTask](https://docs.camunda.org/manual/7.18/reference/bpmn20/tasks/service-task/). For example, the BPMN [Condition Expression](https://docs.camunda.org/manual/7.18/user-guide/process-engine/expression-language/#conditions) ``${cohortSize > 100}`` checks whether the value in the execution variable *cohortSize* is greater than 100. #### Storing / Modifying Process Variables @@ -26,7 +26,7 @@ Via the ``DelegateExecution execution`` parameter of the ``doExecute`` method of boolean variable = (boolean) execution.getVariable("variable-name"); } ``` -For more details on process variables see the [Camunda documentation](https://docs.camunda.org/manual/7.21/user-guide/process-engine/variables/). +For more details on process variables see the [Camunda documentation](https://docs.camunda.org/manual/7.18/user-guide/process-engine/variables/). ### Exercise Tasks --- diff --git a/docs/src/oldstable/tutorial/exercise5-eventBasedGateways.md b/docs/src/oldstable/tutorial/exercise5-eventBasedGateways.md index 8370f1881..572b6f343 100644 --- a/docs/src/oldstable/tutorial/exercise5-eventBasedGateways.md +++ b/docs/src/oldstable/tutorial/exercise5-eventBasedGateways.md @@ -14,13 +14,13 @@ In the final exercise we will look at message flow between three organizations a If an existing and started process instance is waiting for a message from another organization, the corresponding FHIR [Task](http://hl7.org/fhir/R4/task.html) may never arrive. Either because the other organization decides to never send the "message" or because some technical problem prohibits the [Task](http://hl7.org/fhir/R4/task.html) resource from being posted to the DSF FHIR server. This would result in stale process instances that never finish. -In order to solve this problem we can add an [Event Based Gateway](https://docs.camunda.org/manual/7.21/reference/bpmn20/gateways/event-based-gateway/) to the process waiting for a response and then either handle a [Task](http://hl7.org/fhir/R4/task.html) resource with the response and finish the process in a success state or fire of an [Intermediate Timer Catch Event](https://docs.camunda.org/manual/7.21/reference/bpmn20/events/timer-events/#timer-intermediate-catching-event) after a defined wait period and finish the process in an error state. The following BPMN collaboration diagram shows how the process at the first organization would look like if two different message or no message could be received: +In order to solve this problem we can add an [Event Based Gateway](https://docs.camunda.org/manual/7.18/reference/bpmn20/gateways/event-based-gateway/) to the process waiting for a response and then either handle a [Task](http://hl7.org/fhir/R4/task.html) resource with the response and finish the process in a success state or fire of an [Intermediate Timer Catch Event](https://docs.camunda.org/manual/7.18/reference/bpmn20/events/timer-events/#timer-intermediate-catching-event) after a defined wait period and finish the process in an error state. The following BPMN collaboration diagram shows how the process at the first organization would look like if two different message or no message could be received: ![](/photos/guideline/tutorial/ex5.png) ##### Timer Events -For [Timer Events](https://docs.camunda.org/manual/7.21/reference/bpmn20/events/timer-events/) the duration until the timer fires is specified using the [ISO 8601 Durations](https://en.wikipedia.org/wiki/ISO_8601#Durations) format. Examples can be found in the [Camunda 7 documentation](https://docs.camunda.org/manual/7.21/reference/bpmn20/events/timer-events/#time-duration). +For [Timer Events](https://docs.camunda.org/manual/7.18/reference/bpmn20/events/timer-events/) the duration until the timer fires is specified using the [ISO 8601 Durations](https://en.wikipedia.org/wiki/ISO_8601#Durations) format. Examples can be found in the [Camunda 7 documentation](https://docs.camunda.org/manual/7.18/reference/bpmn20/events/timer-events/#time-duration). #### Matching Process Instances With Business Keys @@ -36,7 +36,7 @@ The authorization extension needs to be configured at least once and has four su ##### message-name [1..1] -String value specifying the message name of [Message Start Event](https://docs.camunda.org/manual/7.21/reference/bpmn20/events/message-events/#message-start-event), [Intermediate Message Catch Event](https://docs.camunda.org/manual/7.21/reference/bpmn20/events/message-events/#message-intermediate-catching-event) or [Message Receive Task](https://docs.camunda.org/manual/7.21/reference/bpmn20/tasks/receive-task/) this authorization rule should match. Can only be specified once per authorization rule extension. +String value specifying the message name of [Message Start Event](https://docs.camunda.org/manual/7.18/reference/bpmn20/events/message-events/#message-start-event), [Intermediate Message Catch Event](https://docs.camunda.org/manual/7.18/reference/bpmn20/events/message-events/#message-intermediate-catching-event) or [Message Receive Task](https://docs.camunda.org/manual/7.18/reference/bpmn20/tasks/receive-task/) this authorization rule should match. Can only be specified once per authorization rule extension. ##### task-profile [1..1] @@ -126,13 +126,13 @@ The following example specifies that process execution can only be requested by ### Exercise Tasks --- 1. Modify the ``HelloCosMessage`` and use the value from the [Task.input](http://hl7.org/fhir/R4/task.html) parameter of the ``helloDic`` [Task](http://hl7.org/fhir/R4/task.html) to send it to the ``highmedorg_helloCos`` process via a [Task.input](http://hl7.org/fhir/R4/task.html) parameter in the ``helloCos`` Task. Override the ``getAdditionalInputParameters`` to configure a [Task.input](http://hl7.org/fhir/R4/task.html) parameter to be send. -2. Modify the ``highmedorg_helloCos`` process to use a [Message End Event](https://docs.camunda.org/manual/7.21/reference/bpmn20/events/message-events/#message-end-event) to trigger the process in file ``hello-hrp.bpmn``. Figure out the values for the ``instantiatesUri``, ``profile`` and ``messageName`` input parameters of the [Message End Event](https://docs.camunda.org/manual/7.21/reference/bpmn20/events/message-events/#message-end-event) based on the [AcitvityDefinition](http://hl7.org/fhir/R4/activitydefinition.html) in file ``hello-hrp.xml``. +2. Modify the ``highmedorg_helloCos`` process to use a [Message End Event](https://docs.camunda.org/manual/7.18/reference/bpmn20/events/message-events/#message-end-event) to trigger the process in file ``hello-hrp.bpmn``. Figure out the values for the ``instantiatesUri``, ``profile`` and ``messageName`` input parameters of the [Message End Event](https://docs.camunda.org/manual/7.18/reference/bpmn20/events/message-events/#message-end-event) based on the [AcitvityDefinition](http://hl7.org/fhir/R4/activitydefinition.html) in file ``hello-hrp.xml``. 3. Modify the ``highmedorg_helloDic`` process: - - Change the [Message End Event](https://docs.camunda.org/manual/7.21/reference/bpmn20/events/message-events/#message-end-event) to an [Intermediate Message Throw Event](https://docs.camunda.org/manual/7.21/reference/bpmn20/events/message-events/#message-intermediate-throwing-event) - - Add an [Event Based Gateway](https://docs.camunda.org/manual/7.21/reference/bpmn20/gateways/event-based-gateway/) after the throw event - - Configure two cases for the [Event Based Gateway](https://docs.camunda.org/manual/7.21/reference/bpmn20/gateways/event-based-gateway/): - 1. An [Intermediate Message Catch Event](https://docs.camunda.org/manual/7.21/reference/bpmn20/events/message-events/#message-intermediate-catching-event) to catch the ``goodbyDic`` message from the ``highmedorg_helloHrp`` process. - 2. An [Intermediate Timer Catch Event](https://docs.camunda.org/manual/7.21/reference/bpmn20/events/timer-events/#timer-intermediate-catching-event) to end the process if no message is sent by the ``highmedorg_helloHrp`` process after two minutes. Make sure both cases finish with a process [End Event](https://docs.camunda.org/manual/7.21/reference/bpmn20/events/none-events/). + - Change the [Message End Event](https://docs.camunda.org/manual/7.18/reference/bpmn20/events/message-events/#message-end-event) to an [Intermediate Message Throw Event](https://docs.camunda.org/manual/7.18/reference/bpmn20/events/message-events/#message-intermediate-throwing-event) + - Add an [Event Based Gateway](https://docs.camunda.org/manual/7.18/reference/bpmn20/gateways/event-based-gateway/) after the throw event + - Configure two cases for the [Event Based Gateway](https://docs.camunda.org/manual/7.18/reference/bpmn20/gateways/event-based-gateway/): + 1. An [Intermediate Message Catch Event](https://docs.camunda.org/manual/7.18/reference/bpmn20/events/message-events/#message-intermediate-catching-event) to catch the ``goodbyDic`` message from the ``highmedorg_helloHrp`` process. + 2. An [Intermediate Timer Catch Event](https://docs.camunda.org/manual/7.18/reference/bpmn20/events/timer-events/#timer-intermediate-catching-event) to end the process if no message is sent by the ``highmedorg_helloHrp`` process after two minutes. Make sure both cases finish with a process [End Event](https://docs.camunda.org/manual/7.18/reference/bpmn20/events/none-events/). 4. Modify the process in file ``hello-hrp.bpmn`` and set the process definition key and version. Figure out the appropriate values based on the [AcitvityDefinition](http://hl7.org/fhir/R4/activitydefinition.html) in file ``hello-hrp.xml``. 5. Add the process in file ``hello-hrp.bpmn`` to the ``TutorialProcessPluginDefinition`` and configure the FHIR resources needed for the three processes. 6. Add the ``HelloCos``, ``HelloHrpMessage`` , ``HelloHrp`` and ``GoodbyeDicMessage`` classes as spring beans. From 82183cf9766eac90200f1b555efaf2edf47b43c6 Mon Sep 17 00:00:00 2001 From: Hauke Hund <hauke.hund@hs-heilbronn.de> Date: Mon, 27 May 2024 10:49:46 +0200 Subject: [PATCH 09/14] fixed link --- .../guides/accessing-task-resources-during-execution.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/developer-documentation/guides/accessing-task-resources-during-execution.md b/docs/src/developer-documentation/guides/accessing-task-resources-during-execution.md index 808b0fa4f..98f3fa352 100644 --- a/docs/src/developer-documentation/guides/accessing-task-resources-during-execution.md +++ b/docs/src/developer-documentation/guides/accessing-task-resources-during-execution.md @@ -6,7 +6,7 @@ icon: creative ### Accessing Task Resources During Execution If you want access to the [Task](../concepts/fhir/task.md) resources in your [Service](../concepts/dsf/service-delegates.md) / [Message](../concepts/dsf/message-delegates.md) Delegates, the `Variables` class will provide methods which return certain kinds of [Task](../concepts/fhir/task.md) resources. The most commonly used ones are the start [Task](../concepts/fhir/task.md), referring to the [Task](../concepts/fhir/task.md) / [Message Start Event](../concepts/bpmn/messaging.md#message-start-event) responsible for starting the process, and the latest [Task](../concepts/fhir/task.md), referring to most recently received [Task](../concepts/fhir/task.md) / Message. -In principle, this is sufficient to access all information in a [Task](basic-concepts-and-guides.md#task) resource, since you have the [Task](../concepts/fhir/task.md) resource's Java object, but very cumbersome. +In principle, this is sufficient to access all information in a [Task](../concepts/fhir/task.md) resource, since you have the [Task](../concepts/fhir/task.md) resource's Java object, but very cumbersome. Instead of navigating the [Task](../concepts/fhir/task.md) resource's element tree, you should first try to use the [ProcessPluginApi's](../concepts/dsf/process-api.md) `TaskHelper` in conjunction with the method above. The `TaskHelper` class offers specific methods related to [Task](../concepts/fhir/task.md) resources. The most common use case for this is retrieving data from a [Task's](../concepts/fhir/task.md) [Input Parameter](../concepts/fhir/task.md#task-input-parameters) or creating a new [Input Parameter](../concepts/fhir/task.md#task-input-parameters) for a [Message Delegate's](../concepts/dsf/message-delegates.md) `getAdditionalInputParameters` method. When retrieving data from a [Task's](../concepts/fhir/task.md) Input Parameter you first have to get to the [Input Parameter](../concepts/fhir/task.md#task-input-parameters) you are looking to extract data from. You can use one of the `TaskHelper's` getters for [Input Parameters](../concepts/fhir/task.md#task-input-parameters) to find the right one. The methods will try to match the provided [CodeSystem](../concepts/fhir/codesystem.md) and Code to any [Input Parameter](../concepts/fhir/task.md#task-input-parameters) of the provided [Task](../concepts/fhir/task.md) resource. Depending on the method you chose you will for example receive all matches or just the first one. To create new [Input Parameters](../concepts/fhir/task.md#task-input-parameters) to attach to a [Task](../concepts/fhir/task.md) resource, you may invoke the `TaskHelper#createInput` method. This is most often used when overriding the `getAdditionalInputParamters` method of you [Message Delegate](../concepts/dsf/message-delegates.md). \ No newline at end of file From 9dad86377f670f854c5e9d341a1264499294c208 Mon Sep 17 00:00:00 2001 From: Hauke Hund <hauke.hund@hs-heilbronn.de> Date: Mon, 27 May 2024 15:06:48 +0200 Subject: [PATCH 10/14] restructured developer documentation --- docs/src/.vuepress/theme.ts | 30 ++++++------- .../concepts => develop}/bpmn/conditions.md | 2 +- docs/src/develop/bpmn/gateways.md | 16 +++++++ docs/src/develop/bpmn/index.md | 17 ++++++++ .../concepts => develop}/bpmn/messaging.md | 0 .../bpmn/sequence-flow.md | 0 .../bpmn/service-tasks.md | 0 .../timer-intermediate-catching-events.md | 2 +- .../dsf/bpmn-process-execution.md | 3 +- .../src/develop/dsf/bpmn-process-variables.md | 10 +++++ docs/src/develop/dsf/draft-task-resources.md | 21 +++++++++ .../dsf/environment-variables.md | 2 +- .../dsf/message-correlation.md | 2 +- docs/src/develop/dsf/message-delegates.md | 15 +++++++ .../dsf/organization-identifiers.md | 2 +- docs/src/develop/dsf/process-plugin-api.md | 32 ++++++++++++++ .../dsf/process-plugin-definition.md} | 10 ++--- docs/src/develop/dsf/read-access-tag.md | 22 ++++++++++ .../dsf/requester-and-recipient.md} | 6 +-- docs/src/develop/dsf/service-delegates.md | 12 ++++++ .../dsf/spring-framework-integration.md} | 4 +- .../develop/dsf/versions-placeholders-urls.md | 38 ++++++++++++++++ docs/src/develop/fhir/activitydefinition.md | 23 ++++++++++ .../concepts => develop}/fhir/codesystem.md | 4 +- docs/src/develop/fhir/index.md | 15 +++++++ .../concepts => develop}/fhir/task.md | 6 +-- docs/src/develop/fhir/valueset.md | 10 +++++ .../accessing-bpmn-process-variables.md | 10 +++++ ...cessing-task-resources-during-execution.md | 12 ++++++ ...-task-input-parameters-to-task-profiles.md | 12 +++--- .../guides/configuring-the-read-access-tag.md | 8 ++-- .../guides/creating-an-activity-definition.md | 30 ++++++------- .../creating-codesystems-for-dsf-processes.md | 4 +- ...ng-task-resources-based-on-a-definition.md | 20 ++++----- .../creating-valuesets-for-dsf-processes.md | 10 ++--- ...-incoming-messages-and-missing-messages.md | 18 ++++++++ .../setting-targets-for-message-events.md | 2 +- .../starting-a-process-via-task-resources.md | 43 +++++++++++++++++++ docs/src/develop/index.md | 4 ++ .../concepts/bpmn/gateways.md | 16 ------- .../concepts/bpmn/intro.md | 6 --- .../about-version-placeholders-and-urls.md | 38 ---------------- .../concepts/dsf/bpmn-process-variables.md | 10 ----- .../concepts/dsf/draft-task-resources.md | 21 --------- .../concepts/dsf/message-delegates.md | 15 ------- .../concepts/dsf/process-api.md | 19 -------- .../concepts/dsf/read-access-tag.md | 22 ---------- .../concepts/dsf/service-delegates.md | 12 ------ .../concepts/fhir/activitydefinition.md | 23 ---------- .../concepts/fhir/introduction.md | 8 ---- .../concepts/fhir/valueset.md | 10 ----- .../accessing-bpmn-process-variables.md | 10 ----- ...cessing-task-resources-during-execution.md | 12 ------ ...-incoming-messages-and-missing-messages.md | 18 -------- .../starting-a-process-via-task-resources.md | 43 ------------------- 55 files changed, 394 insertions(+), 366 deletions(-) rename docs/src/{developer-documentation/concepts => develop}/bpmn/conditions.md (75%) create mode 100644 docs/src/develop/bpmn/gateways.md create mode 100644 docs/src/develop/bpmn/index.md rename docs/src/{developer-documentation/concepts => develop}/bpmn/messaging.md (100%) rename docs/src/{developer-documentation/concepts => develop}/bpmn/sequence-flow.md (100%) rename docs/src/{developer-documentation/concepts => develop}/bpmn/service-tasks.md (100%) rename docs/src/{developer-documentation/concepts => develop}/bpmn/timer-intermediate-catching-events.md (77%) rename docs/src/{developer-documentation/concepts => develop}/dsf/bpmn-process-execution.md (62%) create mode 100644 docs/src/develop/dsf/bpmn-process-variables.md create mode 100644 docs/src/develop/dsf/draft-task-resources.md rename docs/src/{developer-documentation/concepts => develop}/dsf/environment-variables.md (53%) rename docs/src/{developer-documentation/concepts => develop}/dsf/message-correlation.md (67%) create mode 100644 docs/src/develop/dsf/message-delegates.md rename docs/src/{developer-documentation/concepts => develop}/dsf/organization-identifiers.md (53%) create mode 100644 docs/src/develop/dsf/process-plugin-api.md rename docs/src/{developer-documentation/concepts/dsf/the-process-plugin-definition.md => develop/dsf/process-plugin-definition.md} (75%) create mode 100644 docs/src/develop/dsf/read-access-tag.md rename docs/src/{developer-documentation/concepts/dsf/examples-for-requester-and-recipient-elements.md => develop/dsf/requester-and-recipient.md} (98%) create mode 100644 docs/src/develop/dsf/service-delegates.md rename docs/src/{developer-documentation/concepts/dsf/spring-integration.md => develop/dsf/spring-framework-integration.md} (95%) create mode 100644 docs/src/develop/dsf/versions-placeholders-urls.md create mode 100644 docs/src/develop/fhir/activitydefinition.md rename docs/src/{developer-documentation/concepts => develop}/fhir/codesystem.md (82%) create mode 100644 docs/src/develop/fhir/index.md rename docs/src/{developer-documentation/concepts => develop}/fhir/task.md (81%) create mode 100644 docs/src/develop/fhir/valueset.md create mode 100644 docs/src/develop/guides/accessing-bpmn-process-variables.md create mode 100644 docs/src/develop/guides/accessing-task-resources-during-execution.md rename docs/src/{developer-documentation => develop}/guides/adding-task-input-parameters-to-task-profiles.md (81%) rename docs/src/{developer-documentation => develop}/guides/configuring-the-read-access-tag.md (94%) rename docs/src/{developer-documentation => develop}/guides/creating-an-activity-definition.md (89%) rename docs/src/{developer-documentation => develop}/guides/creating-codesystems-for-dsf-processes.md (74%) rename docs/src/{developer-documentation => develop}/guides/creating-task-resources-based-on-a-definition.md (68%) rename docs/src/{developer-documentation => develop}/guides/creating-valuesets-for-dsf-processes.md (62%) create mode 100644 docs/src/develop/guides/managing-mutiple-incoming-messages-and-missing-messages.md rename docs/src/{developer-documentation => develop}/guides/setting-targets-for-message-events.md (94%) create mode 100644 docs/src/develop/guides/starting-a-process-via-task-resources.md create mode 100644 docs/src/develop/index.md delete mode 100644 docs/src/developer-documentation/concepts/bpmn/gateways.md delete mode 100644 docs/src/developer-documentation/concepts/bpmn/intro.md delete mode 100644 docs/src/developer-documentation/concepts/dsf/about-version-placeholders-and-urls.md delete mode 100644 docs/src/developer-documentation/concepts/dsf/bpmn-process-variables.md delete mode 100644 docs/src/developer-documentation/concepts/dsf/draft-task-resources.md delete mode 100644 docs/src/developer-documentation/concepts/dsf/message-delegates.md delete mode 100644 docs/src/developer-documentation/concepts/dsf/process-api.md delete mode 100644 docs/src/developer-documentation/concepts/dsf/read-access-tag.md delete mode 100644 docs/src/developer-documentation/concepts/dsf/service-delegates.md delete mode 100644 docs/src/developer-documentation/concepts/fhir/activitydefinition.md delete mode 100644 docs/src/developer-documentation/concepts/fhir/introduction.md delete mode 100644 docs/src/developer-documentation/concepts/fhir/valueset.md delete mode 100644 docs/src/developer-documentation/guides/accessing-bpmn-process-variables.md delete mode 100644 docs/src/developer-documentation/guides/accessing-task-resources-during-execution.md delete mode 100644 docs/src/developer-documentation/guides/managing-mutiple-incoming-messages-and-missing-messages.md delete mode 100644 docs/src/developer-documentation/guides/starting-a-process-via-task-resources.md diff --git a/docs/src/.vuepress/theme.ts b/docs/src/.vuepress/theme.ts index 100519616..294952f58 100644 --- a/docs/src/.vuepress/theme.ts +++ b/docs/src/.vuepress/theme.ts @@ -37,8 +37,8 @@ export default hopeTheme({ }, { text: "Developer Documentation", - icon: "info", - link: "/developer-documentation/" + icon: "creative", + link: "/develop/" } ] }, @@ -855,41 +855,35 @@ export default hopeTheme({ children: ["introduction", "generalinformation/", "code/", "build/", "releases/", "tutorial/"], }, ], - "/developer-documentation/": [ + "/develop/": [ { text: "Developer Documentation", - icon: "info", - link: "/developer-documentation/", + icon: "creative", + link: "/develop/", children: [{ - text: "Concepts", - icon: "info", - prefix: "concepts/", - link: "concepts/", - children: [{ text: "BPMN", - icon: "info", + icon: "creative", prefix: "bpmn/", link: "bpmn/", - children: ["intro.md", "sequence-flow.md", "service-tasks.md", "gateways.md", "conditions.md", "messaging.md", "timer-intermediate-catching-events.md"], + children: ["conditions.md", "gateways.md", "messaging.md", "sequence-flow.md", "service-tasks.md", "timer-intermediate-catching-events.md"], }, { text: "FHIR", - icon: "info", + icon: "creative", prefix: "fhir/", link: "fhir/", - children: ["introduction.md", "task.md", "activitydefinition.md", "codesystem.md", "valueset.md"], + children: ["activitydefinition.md", "codesystem.md", "task.md", "valueset.md"], }, { text: "DSF", - icon: "info", + icon: "creative", prefix: "dsf/", link: "dsf/", - children: ["about-version-placeholders-and-urls.md", "bpmn-process-execution.md", "bpmn-process-variables.md", "draft-task-resources.md", "environment-variables.md", "examples-for-requester-and-recipient-elements.md", "message-correlation.md", "message-delegates.md", "organization-identifiers.md", "process-api.md", "read-access-tag.md", "service-delegates.md", "spring-integration.md", "the-process-plugin-definition.md"], - }] + children: ["versions-placeholders-urls.md", "bpmn-process-execution.md", "bpmn-process-variables.md", "draft-task-resources.md", "environment-variables.md", "requester-and-recipient.md", "message-correlation.md", "message-delegates.md", "organization-identifiers.md", "process-plugin-api.md", "read-access-tag.md", "service-delegates.md", "spring-framework-integration.md", "process-plugin-definition.md"], }, { text: "Guides", - icon: "info", + icon: "creative", prefix: "guides/", link: "guides/", children: ["accessing-bpmn-process-variables.md", "accessing-task-resources-during-execution.md", "adding-task-input-parameters-to-task-profiles.md", "configuring-the-read-access-tag.md", "creating-an-activity-definition.md", "creating-codesystems-for-dsf-processes.md", "creating-task-resources-based-on-a-definition.md", "creating-valuesets-for-dsf-processes.md", "managing-mutiple-incoming-messages-and-missing-messages.md", "setting-targets-for-message-events.md", "starting-a-process-via-task-resources.md"] diff --git a/docs/src/developer-documentation/concepts/bpmn/conditions.md b/docs/src/develop/bpmn/conditions.md similarity index 75% rename from docs/src/developer-documentation/concepts/bpmn/conditions.md rename to docs/src/develop/bpmn/conditions.md index 4ac23388d..41447df07 100644 --- a/docs/src/developer-documentation/concepts/bpmn/conditions.md +++ b/docs/src/develop/bpmn/conditions.md @@ -5,4 +5,4 @@ icon: creative ### Conditions -[Conditions](https://docs.camunda.org/manual/7.21/user-guide/process-engine/expression-language/#conditions) allow you to change the behaviour of BPMN processes during execution. There are two ways you are able to add decision logic to Conditions. The [Camunda Modeler](https://camunda.com/download/modeler/) refers to them as `Type`. You can find them in the ``Condition`` tab of certain BPMN elements. The first one is `Script`. This allows you to add arbitrary complexity to your decisions logic and is rarely used for process plugins. The more common Type is `Expression`. Expressions have the following syntax: `${expression}`. An example of a simple expression would be a boolean condition like `var == true`. For this to work during BPMN process execution, the variable you want to use for the boolean condition must be available in the BPMN process variables before [Sequence Flow](../../concepts/bpmn/sequence-flow.md) reaches the evaluation of the expression. You can learn more advanced features of Expressions [here](https://docs.camunda.org/manual/7.21/user-guide/process-engine/expression-language/). \ No newline at end of file +[Conditions](https://docs.camunda.org/manual/7.21/user-guide/process-engine/expression-language/#conditions) allow you to change the behaviour of BPMN processes during execution. There are two ways you are able to add decision logic to Conditions. The [Camunda Modeler](https://camunda.com/download/modeler/) refers to them as `Type`. You can find them in the ``Condition`` tab of certain BPMN elements. The first one is `Script`. This allows you to add arbitrary complexity to your decisions logic and is rarely used for process plugins. The more common Type is `Expression`. Expressions have the following syntax: `${expression}`. An example of a simple expression would be a boolean condition like `var == true`. For this to work during BPMN process execution, the variable you want to use for the boolean condition must be available in the BPMN process variables before [Sequence Flow](sequence-flow.md) reaches the evaluation of the expression. You can learn more advanced features of Expressions [here](https://docs.camunda.org/manual/7.21/user-guide/process-engine/expression-language/). \ No newline at end of file diff --git a/docs/src/develop/bpmn/gateways.md b/docs/src/develop/bpmn/gateways.md new file mode 100644 index 000000000..630b26ae0 --- /dev/null +++ b/docs/src/develop/bpmn/gateways.md @@ -0,0 +1,16 @@ +--- +title: Gateways +icon: creative +--- + +### Gateways + +[Gateways](https://docs.camunda.org/manual/7.21/reference/bpmn20/gateways/) allow you to control the [Sequence Flow](sequence-flow.md). Different types of gateways are useful for different scenarios. + +#### Exclusive Gateways + +[Exclusive Gateways](https://docs.camunda.org/manual/7.21/reference/bpmn20/gateways/exclusive-gateway/) allow you to decide which [Sequence Flow](sequence-flow.md) should be followed based on [conditions](https://docs.camunda.org/manual/7.21/user-guide/process-engine/expression-language/#conditions). [Conditions](https://docs.camunda.org/manual/7.21/user-guide/process-engine/expression-language/#conditions) are not part of the [Exclusive Gateways](https://docs.camunda.org/manual/7.21/reference/bpmn20/gateways/exclusive-gateway/) themselves. You set them through the sequence flow exiting the [Exclusive Gateway](https://docs.camunda.org/manual/7.21/reference/bpmn20/gateways/exclusive-gateway/). In the [Camunda Modeler](https://camunda.com/download/modeler/), you can add conditions to [Sequence Flow](sequence-flow.md) by selecting a [Sequence Flow](sequence-flow.md) and opening the `Condition` tab. You can find more information on how to use Conditions [here](conditions.md). + +#### Event-based Gateway + +The [Event-based Gateway](https://docs.camunda.org/manual/7.21/reference/bpmn20/gateways/event-based-gateway/) allows you model scenarios where you are expecting one out of a number of events to occur. \ No newline at end of file diff --git a/docs/src/develop/bpmn/index.md b/docs/src/develop/bpmn/index.md new file mode 100644 index 000000000..0a79690de --- /dev/null +++ b/docs/src/develop/bpmn/index.md @@ -0,0 +1,17 @@ +--- +title: BPMN +icon: creative +--- + +## Introduction + +The DSF uses BPMN 2.0 to model processes. Specifically, the [Camunda 7](https://docs.camunda.org/manual/7.21/) dialect from the [Camunda Modeler](https://camunda.com/de/download/modeler/). Modeling processes for the DSF requires this modeler or any other modeler which is able to produce the correct Camunda dialect. + +## Details + +- [Conditions](conditions.md) +- [Gateways](gateways.md) +- [Messaging](messaging.md) +- [Sequence Flow](sequence-flow.md) +- [Service Tasks](service-tasks.md) +- [Timer Intermediate Catching Events](timer-intermediate-catching-events.md) \ No newline at end of file diff --git a/docs/src/developer-documentation/concepts/bpmn/messaging.md b/docs/src/develop/bpmn/messaging.md similarity index 100% rename from docs/src/developer-documentation/concepts/bpmn/messaging.md rename to docs/src/develop/bpmn/messaging.md diff --git a/docs/src/developer-documentation/concepts/bpmn/sequence-flow.md b/docs/src/develop/bpmn/sequence-flow.md similarity index 100% rename from docs/src/developer-documentation/concepts/bpmn/sequence-flow.md rename to docs/src/develop/bpmn/sequence-flow.md diff --git a/docs/src/developer-documentation/concepts/bpmn/service-tasks.md b/docs/src/develop/bpmn/service-tasks.md similarity index 100% rename from docs/src/developer-documentation/concepts/bpmn/service-tasks.md rename to docs/src/develop/bpmn/service-tasks.md diff --git a/docs/src/developer-documentation/concepts/bpmn/timer-intermediate-catching-events.md b/docs/src/develop/bpmn/timer-intermediate-catching-events.md similarity index 77% rename from docs/src/developer-documentation/concepts/bpmn/timer-intermediate-catching-events.md rename to docs/src/develop/bpmn/timer-intermediate-catching-events.md index bb4a0eb80..49ab4a8fc 100644 --- a/docs/src/developer-documentation/concepts/bpmn/timer-intermediate-catching-events.md +++ b/docs/src/develop/bpmn/timer-intermediate-catching-events.md @@ -5,4 +5,4 @@ icon: creative ### Timer Intermediate Catching Events -A [Timer Intermediate Catching Event](https://docs.camunda.org/manual/7.21/reference/bpmn20/events/timer-events/#timer-intermediate-catching-event) allows you to model stopwatch behavior. A timer is started once the BPMN execution arrives at the event. The duration until the timer runs out is specified using the [ISO 8601 Durations](http://en.wikipedia.org/wiki/ISO_8601#Durations) format. Examples can be found [here](https://docs.camunda.org/manual/7.21/reference/bpmn20/events/timer-events/#time-duration). After running out, the BPMN process executes the [Sequence Flow](../../concepts/bpmn/sequence-flow.md) following the [Timer Intermediate Catching Event](https://docs.camunda.org/manual/7.21/reference/bpmn20/events/timer-events/#timer-intermediate-catching-event). \ No newline at end of file +A [Timer Intermediate Catching Event](https://docs.camunda.org/manual/7.21/reference/bpmn20/events/timer-events/#timer-intermediate-catching-event) allows you to model stopwatch behavior. A timer is started once the BPMN execution arrives at the event. The duration until the timer runs out is specified using the [ISO 8601 Durations](http://en.wikipedia.org/wiki/ISO_8601#Durations) format. Examples can be found [here](https://docs.camunda.org/manual/7.21/reference/bpmn20/events/timer-events/#time-duration). After running out, the BPMN process executes the [Sequence Flow](sequence-flow.md) following the [Timer Intermediate Catching Event](https://docs.camunda.org/manual/7.21/reference/bpmn20/events/timer-events/#timer-intermediate-catching-event). \ No newline at end of file diff --git a/docs/src/developer-documentation/concepts/dsf/bpmn-process-execution.md b/docs/src/develop/dsf/bpmn-process-execution.md similarity index 62% rename from docs/src/developer-documentation/concepts/dsf/bpmn-process-execution.md rename to docs/src/develop/dsf/bpmn-process-execution.md index 643f371fc..8884106e0 100644 --- a/docs/src/developer-documentation/concepts/dsf/bpmn-process-execution.md +++ b/docs/src/develop/dsf/bpmn-process-execution.md @@ -3,7 +3,6 @@ title: BPMN Process Execution icon: creative --- - ### BPMN Process Execution -The BPMN process execution is the in-memory representation of a running BPMN process. BPMN processes have their executions structured as a tree hierarchy. Each BPMN process starts with the [process instance](https://docs.camunda.org/manual/7.21/user-guide/process-engine/process-engine-concepts/#process-instances) as its root level execution. If, for example, this root execution reaches a parallel gateway with two paths, it would spawn two child executions under itself for them to process all tasks along their paths on their own. Executions can access all the BPMN elements from the BPMN model as well as the [BPMN process variables](../../concepts/dsf/bpmn-process-variables.md). You have access to this representation in your Java code through the `execution` parameter when overriding certain methods in [Service](../../concepts/dsf/service-delegates.md) / [Message](../../concepts/dsf/message-delegates.md) Delegates like `doExecute` or `getAdditionalInputParameters`. \ No newline at end of file +The BPMN process execution is the in-memory representation of a running BPMN process. BPMN processes have their executions structured as a tree hierarchy. Each BPMN process starts with the [process instance](https://docs.camunda.org/manual/7.21/user-guide/process-engine/process-engine-concepts/#process-instances) as its root level execution. If, for example, this root execution reaches a parallel gateway with two paths, it would spawn two child executions under itself for them to process all tasks along their paths on their own. Executions can access all the BPMN elements from the BPMN model as well as the [BPMN process variables](bpmn-process-variables.md). You have access to this representation in your Java code through the `execution` parameter when overriding certain methods in [Service](service-delegates.md) / [Message](message-delegates.md) Delegates like `doExecute` or `getAdditionalInputParameters`. \ No newline at end of file diff --git a/docs/src/develop/dsf/bpmn-process-variables.md b/docs/src/develop/dsf/bpmn-process-variables.md new file mode 100644 index 000000000..6170e1b1e --- /dev/null +++ b/docs/src/develop/dsf/bpmn-process-variables.md @@ -0,0 +1,10 @@ +--- +title: BPMN Process Variables +icon: creative +--- + +### BPMN Process Variables + +BPMN process variables hold additional information which has to be available during BPMN process execution. Variables can be directly related to BPMN elements like the boolean value for [Conditions](../bpmn/conditions.md), but do not have to be. BPMN process variables are stored as key-value pairs with the key being the variable name. They are accessible during the entirety of the execution to all [Service](service-delegates.md) / [Message](message-delegates.md) Delegates. + +You can learn how to access to the BPMN process variables [here](../guides/accessing-bpmn-process-variables.md). \ No newline at end of file diff --git a/docs/src/develop/dsf/draft-task-resources.md b/docs/src/develop/dsf/draft-task-resources.md new file mode 100644 index 000000000..c1bcaa28c --- /dev/null +++ b/docs/src/develop/dsf/draft-task-resources.md @@ -0,0 +1,21 @@ +--- +title: Draft Task Resources +icon: creative +--- + +### Draft Task Resources + +[Task](../fhir/task.md) resources with status `draft` are used to create the DSF FHIR server's functionality of starting processes via its web interface. They are stored in `.../tutorial-process/src/main/resources/fhir/Task`. Compared to regular [Task](../fhir/task.md) resources used to start BPMN processes, this type of [Task](../fhir/task.md) resource requires the status `draft` instead the usual `requested`. It also replaces the value for `authoredOn` with the placeholder `#{date}`, the values of organization identifiers with the placeholder `#{organization}` and all instances of version numbers with `#{version}`. Additionally, it requires setting the `Task.identifier` element. It should look something like this: + +```xml +<identifier> + <system value="http://dsf.dev/sid/task-identifier" /> + <value value="http://dsf.dev/bpe/Process/processKey/#{version}/task-name" /> +</identifier> +``` +`processKey` should be the same one used in [URLs](versions-placeholders-urls.md#urls). +`task-name` can be any String you wish to identify this task with. E.g. you can use the file name of the Draft Task. + +For a complete example you can take a look at the Draft Task Resource in one of the solution branches and compare it to the one needed for cURL. The [Task](../fhir/task.md) resource created for cURL can be found at `.../tutorial-process/src/main/resources/example-task.xml`. + +You might also want to check out [this guide](../guides/creating-task-resources-based-on-a-definition.md) if you do not know how to create [Task](../fhir/task.md) resources in general. \ No newline at end of file diff --git a/docs/src/developer-documentation/concepts/dsf/environment-variables.md b/docs/src/develop/dsf/environment-variables.md similarity index 53% rename from docs/src/developer-documentation/concepts/dsf/environment-variables.md rename to docs/src/develop/dsf/environment-variables.md index 2ce877cc5..fcea6697c 100644 --- a/docs/src/developer-documentation/concepts/dsf/environment-variables.md +++ b/docs/src/develop/dsf/environment-variables.md @@ -5,6 +5,6 @@ icon: creative ### Environment Variables -Environment variables offer a way to make configuration data available at the start of a [BPMN process execution](../../concepts/dsf/bpmn-process-execution.md). They are the same for all running process instances. They can be defined by adding a member variable with the [Spring-Framework @Value](https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#beans-value-annotations) annotation to the configuration class `TutorialConfig`. The value of the annotation uses the `${..}` notation and follows the form `${some.property:defaultValue}`, where each dot in the property name corresponds to an underscore in the equivalent environment variable. Environment variables are always written upper-case. The property `some.property` therefore corresponds to the environment variable `SOME_PROPERTY`. +Environment variables offer a way to make configuration data available at the start of a [BPMN process execution](bpmn-process-execution.md). They are the same for all running process instances. They can be defined by adding a member variable with the [Spring-Framework @Value](https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#beans-value-annotations) annotation to the configuration class `TutorialConfig`. The value of the annotation uses the `${..}` notation and follows the form `${some.property:defaultValue}`, where each dot in the property name corresponds to an underscore in the equivalent environment variable. Environment variables are always written upper-case. The property `some.property` therefore corresponds to the environment variable `SOME_PROPERTY`. The DSF provides a feature to automatically generate documentation of environment variables during the Maven build process. You can use the `@ProcessDocumentation` annotation to automatically generate Markdown documentation for all fields with this annotation. You simply have to add [dsf-tools-documentation-generator](https://mvnrepository.com/artifact/dev.dsf/dsf-tools-documentation-generator) as a maven plugin. You can take a look at the `pom.xml` for the `tutorial-process` submodule [here](https://github.com/datasharingframework/dsf-process-tutorial/blob/main/tutorial-process/pom.xml) to see how you can add it to your own project. Keep in mind to point the `<workingPackage>` field to the package you want documentation for. \ No newline at end of file diff --git a/docs/src/developer-documentation/concepts/dsf/message-correlation.md b/docs/src/develop/dsf/message-correlation.md similarity index 67% rename from docs/src/developer-documentation/concepts/dsf/message-correlation.md rename to docs/src/develop/dsf/message-correlation.md index 4e91e1515..23b18e3e3 100644 --- a/docs/src/developer-documentation/concepts/dsf/message-correlation.md +++ b/docs/src/develop/dsf/message-correlation.md @@ -7,4 +7,4 @@ icon: creative In order for messages to be able to be sent back and forth between organizations with potentially multiple of the same process plugin instances running at the same time and still arriving at the correct process instance, we need some mechanism to map messages to their rightful process instance. This mechanism is called Message Correlation and requires attaching a unique identifier to every process instance. This identifier is called the `business-key`. The `business-key` will get attached to every outgoing message automatically. -It is possible that the `business-key` is insufficient to map messages to the correct process instance. This happens when you use subprocesses in your BPMN model which all expect messages to be sent to them, not the parent process. To solve this issue, [Task](../../concepts/fhir/task.md) resources also come with an [Input Parameter](../../concepts/fhir/task.md#task-input-parameters) called `correlation-key`. This is a secondary identifier you can attach to all messages if you need them to arrive at a specific subprocess. You can learn more about how `correlation-keys` are used by studying the [Ping-Pong Process](https://github.com/datasharingframework/dsf-process-ping-pong). \ No newline at end of file +It is possible that the `business-key` is insufficient to map messages to the correct process instance. This happens when you use subprocesses in your BPMN model which all expect messages to be sent to them, not the parent process. To solve this issue, [Task](../fhir/task.md) resources also come with an [Input Parameter](../fhir/task.md#task-input-parameters) called `correlation-key`. This is a secondary identifier you can attach to all messages if you need them to arrive at a specific subprocess. You can learn more about how `correlation-keys` are used by studying the [Ping-Pong Process](https://github.com/datasharingframework/dsf-process-ping-pong). \ No newline at end of file diff --git a/docs/src/develop/dsf/message-delegates.md b/docs/src/develop/dsf/message-delegates.md new file mode 100644 index 000000000..61a1a06f1 --- /dev/null +++ b/docs/src/develop/dsf/message-delegates.md @@ -0,0 +1,15 @@ +--- +title: Message Delegates +icon: creative +--- + +### Message Delegates + +Message Delegates are the Java representation of the [Message Events](../bpmn/messaging.md) in your BPMN model. You link a Message Delegate to a certain [Message Event](../bpmn/messaging.md) by selecting the Message Event in the [Camunda Modeler](https://camunda.com/download/modeler/) and adding a Java class to the `Implementation` field. Make sure you use the fully qualified class name. Like this: +``` +org.package.myClass +``` + +You will only need Message Delegates for [Message Send Events](../bpmn/messaging.md). Incoming messages will be resolved to the correct [BPMN process execution](bpmn-process-execution.md) automatically using [Message Correlation](message-correlation.md) and the message inputs will be added to that execution's [process variables](bpmn-process-variables.md). + +To make a Message Delegate for [Message Send Events](../bpmn/messaging.md), your Java class needs to extend `AbstractTaskMessageSend`. Most of the time, you will not be adding any processing logic to your Message Delegates, therefore you usually won't be overwriting the `doExecute` method like with [Service Delegates](service-delegates.md). Instead, you most likely want to aggregate the information you processed in earlier steps and attach it to a message. For this you need to overwrite the `getAdditionalInputParamters` method. The DSF translates BPMN messages into FHIR [Task](../fhir/task.md) resources to execute the communication modeled by your BPMN diagrams. The information you are sending to another BPMN process is specified in the Task.input elements a.k.a. [Input Parameters](../fhir/task.md#task-input-parameters), hence the name of the method. The constructor of your delegate class should also forward a `ProcessPluginApi` instance to its superclass constructor. You can learn more about the `ProcessPluginApi` [here](process-plugin-api.md). diff --git a/docs/src/developer-documentation/concepts/dsf/organization-identifiers.md b/docs/src/develop/dsf/organization-identifiers.md similarity index 53% rename from docs/src/developer-documentation/concepts/dsf/organization-identifiers.md rename to docs/src/develop/dsf/organization-identifiers.md index 265f75958..70d143150 100644 --- a/docs/src/developer-documentation/concepts/dsf/organization-identifiers.md +++ b/docs/src/develop/dsf/organization-identifiers.md @@ -7,4 +7,4 @@ icon: creative DSF FHIR server instances always have something called an `organization identifer`. It uniquely identifies the organization the DSF FHIR server instance belongs to for its [Allow-List mechanism](https://dsf.dev/intro/info/allowList.html). It is configured as an [environment variable](https://dsf.dev/stable/maintain/fhir/configuration.html#dev-dsf-fhir-server-organization-identifier-value). You can make a GET request to `https://domain/fhir/Organization` to get a list of all organizations for the DSF FHIR server instance running under `domain`. The results will also include the `organization identifier` of each organization. #### Organization Identifiers in Task Resources -[Task](../../concepts/fhir/task.md) resources require you to reference an organization via its identifier as the `Task.requester` and `Task.restriction.recipient` elements. The exact values for these elements depend on the [ActivityDefinition](../../concepts/fhir/activitydefinition.md) the [Task](../../concepts/fhir/task.md) resource should conform to. As a general rule, you will want to put the identifier of your own organization as the `Task.requester` and `Task.restriction.recipient` elements for [Task](../../concepts/fhir/task.md) resources which initially start processes. All other cases depend on the context of the message being sent during process execution. \ No newline at end of file +[Task](../fhir/task.md) resources require you to reference an organization via its identifier as the `Task.requester` and `Task.restriction.recipient` elements. The exact values for these elements depend on the [ActivityDefinition](../fhir/activitydefinition.md) the [Task](../fhir/task.md) resource should conform to. As a general rule, you will want to put the identifier of your own organization as the `Task.requester` and `Task.restriction.recipient` elements for [Task](../fhir/task.md) resources which initially start processes. All other cases depend on the context of the message being sent during process execution. \ No newline at end of file diff --git a/docs/src/develop/dsf/process-plugin-api.md b/docs/src/develop/dsf/process-plugin-api.md new file mode 100644 index 000000000..5d1381a5a --- /dev/null +++ b/docs/src/develop/dsf/process-plugin-api.md @@ -0,0 +1,32 @@ +--- +title: Process Plugin API +icon: creative +--- + +### Process Plugin API v1 Maven Module + +The [DSF Process Plugin API module](https://mvnrepository.com/artifact/dev.dsf/dsf-bpe-process-api-v1) consists of a set of utility classes designed to provide easy access to solutions for process plugin use cases. This includes for example the `Variables` class, which provides access to the [BPMN process variables](bpmn-process-variables.md). + +Maven Dependency: + +```xml +<dependencies> + <dependency> + <groupId>dev.dsf</groupId> + <artifactId>dsf-bpe-process-api-v1</artifactId> + <version>${dsf.version}</version> + <scope>provided</scope> + </dependency> +</dependencies> +``` + +#### Process Plugin Api +When creating [Service Delegates](service-delegates.md) or [Message Delegates](message-delegates.md) you wil notice that you need to provide a constructor which expects a `ProcessPluginApi` object and forward it to the superclasses' constructor. +This API instance provides a variety of utility classes: +- `ProxyConfig`**:** forward proxy configuration +- `EndpointProvider`**:** access to Endpoint resources +- `FhirContext`**:** HAPI FHIR Context for parsing/serializing +- `FhirWebserviceClientProvider`**:** Webservice client to access DSF FHIR server +- `MailService`**:** for sending automatic E-Mails (if configured) +- `OrganizationProvider`**:** access to Organization resources +- `Variables`**:** access to BPMN execution variables \ No newline at end of file diff --git a/docs/src/developer-documentation/concepts/dsf/the-process-plugin-definition.md b/docs/src/develop/dsf/process-plugin-definition.md similarity index 75% rename from docs/src/developer-documentation/concepts/dsf/the-process-plugin-definition.md rename to docs/src/develop/dsf/process-plugin-definition.md index 06297175a..a13bdbe26 100644 --- a/docs/src/developer-documentation/concepts/dsf/the-process-plugin-definition.md +++ b/docs/src/develop/dsf/process-plugin-definition.md @@ -1,16 +1,16 @@ --- -title: The Process Plugin Definition +title: Process Plugin Definition icon: creative --- -### The Process Plugin Definition +### Process Plugin Definition In order for the DSF BPE server to load your plugin you need to provide it with the following information: -* A plugin [version](../../concepts/dsf/about-version-placeholders-and-urls.md#version-pattern) +* A plugin [version](versions-placeholders-urls.md#version-pattern) * A release date * A plugin name * The BPMN model files -* The FHIR resources grouped by BPMN process ID. Your plugin may have any number of BPMN models. Each has their own BPMN process ID and FHIR resources specific to that BPMN process (think [Task](../../concepts/fhir/task.md) resources needed for messages specific to that BPMN model) -* The Class holding your [Spring Configuration](../../concepts/dsf/spring-integration.md) +* The FHIR resources grouped by BPMN process ID. Your plugin may have any number of BPMN models. Each has their own BPMN process ID and FHIR resources specific to that BPMN process (think [Task](../fhir/task.md) resources needed for messages specific to that BPMN model) +* The Class holding your [Spring Framework Configuration](spring-framework-integration.md) You will provide this information by implementing the `dev.dsf.bpe.ProcessPluginDefinition` interface. The DSF BPE server then searches for classes implementing this interface using the Java [ServiceLoader](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/ServiceLoader.html) mechanism. Therefore, you will have to register your interface implementation in the `src/main/resources/META-INF/services/dev.dsf.bpe.ProcessPluginDefinition` file. For this tutorial, the class implementing the `ProcessPluginDefinition` interface, `TutorialProcessPluginDefinition`, has already been added to the file. You can use it as a reference for later when you want to create your own plugin. \ No newline at end of file diff --git a/docs/src/develop/dsf/read-access-tag.md b/docs/src/develop/dsf/read-access-tag.md new file mode 100644 index 000000000..4a69b6dc5 --- /dev/null +++ b/docs/src/develop/dsf/read-access-tag.md @@ -0,0 +1,22 @@ +--- +title: Read Access Tag +icon: creative +--- + +### Read Access Tag + +Axiomatically, nobody is allowed to write FHIR resources (except [Task](../fhir/task.md)) to the DSF FHIR server unless it is your own organization. By default, the same applies to reading FHIR resources (again except [Task](../fhir/task.md)). But since the DSF is often used to offer medical data in form of FHIR resources, you will find yourself wanting other organizations to be allowed to read the resources you are offering. The `Resource.meta.tag` element is used define access rules for all FHIR resources in the DSF, with the exception of [Task](../fhir/task.md) resources. We will explain the reason for this exception shortly. For example, allowing read access for all organizations, you would use the following `system` and `code` in your FHIR resource: + +```xml +<meta> + <tag> + <system value="http://dsf.dev/fhir/CodeSystem/read-access-tag" /> + <code value="ALL" /> + </tag> +</meta> +``` +You can find all codes for the Read Access Tag in its [CodeSystem](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/CodeSystem/dsf-read-access-tag-1.0.0.xml). + +The read access rules for [Task](../fhir/task.md) resources are defined through the `requester` and `recipient` elements of the [dsf-extension-process-authorization](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-extension-process-authorization-1.0.0.xml) in your plugin's [ActivityDefinitions](../fhir/activitydefinition.md). Therefore, no `read-access-tag` is needed. + +It is also possible to restrict read access of FHIR resources to organizations with a specific role in a parent organization or a specific identifier. If you want to find out more, you may look at the [guide on configuring the Read Access Tag](../guides/configuring-the-read-access-tag.md). diff --git a/docs/src/developer-documentation/concepts/dsf/examples-for-requester-and-recipient-elements.md b/docs/src/develop/dsf/requester-and-recipient.md similarity index 98% rename from docs/src/developer-documentation/concepts/dsf/examples-for-requester-and-recipient-elements.md rename to docs/src/develop/dsf/requester-and-recipient.md index 64d0164f8..fbbd79c3b 100644 --- a/docs/src/developer-documentation/concepts/dsf/examples-for-requester-and-recipient-elements.md +++ b/docs/src/develop/dsf/requester-and-recipient.md @@ -1,11 +1,11 @@ --- -title: Examples for Requester and Recipient Elements +title: Requester and Recipient Elements icon: creative --- -### Examples for Requester and Recipient Elements +### Requester and Recipient Elements -Below you will find a set of examples for each Coding used by `requester` and `recipient` elements from the [dsf-extension-process-authorization](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-extension-process-authorization-1.0.0.xml). CodeSystems referenced in the examples can be found [here](https://github.com/datasharingframework/dsf/tree/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/CodeSystem). Use this collection as a reference point when creating your own [ActivityDefinitions](../../concepts/fhir/activitydefinition.md). +Below you will find a set of examples for each Coding used by `requester` and `recipient` elements from the [dsf-extension-process-authorization](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-extension-process-authorization-1.0.0.xml). CodeSystems referenced in the examples can be found [here](https://github.com/datasharingframework/dsf/tree/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/CodeSystem). Use this collection as a reference point when creating your own [ActivityDefinitions](../fhir/activitydefinition.md). #### Requester The `requester` element uses one of the following Codings: diff --git a/docs/src/develop/dsf/service-delegates.md b/docs/src/develop/dsf/service-delegates.md new file mode 100644 index 000000000..278b51e34 --- /dev/null +++ b/docs/src/develop/dsf/service-delegates.md @@ -0,0 +1,12 @@ +--- +title: Service Delegates +icon: creative +--- + +### Service Delegates + +Service Delegates are the Java representation of the [Service Tasks](../bpmn/service-tasks.md) in your BPMN model. You link a Service Delegate to a certain [Service Task](../bpmn/service-tasks.md) by selecting the [Service Task](../bpmn/service-tasks.md) in the [Camunda Modeler](https://camunda.com/download/modeler/) and adding a Java class to the `Implementation` field. Make sure you use the fully qualified class name. Like this: +``` +org.package.myClass +``` +All that is left is for your Java class to extend `AbstractServiceDelegate` and override the `doExecute` method. This is the place where you can put your actual business logic. The method will be called when the [BPMN process execution](bpmn-process-execution.md) arrives at the [Service Task](../bpmn/service-tasks.md) your Service Delegate is linked to. The constructor of your delegate class should also forward a `ProcessPluginApi` instance to its superclass constructor. You can learn more about the `ProcessPluginApi` [here](process-plugin-api.md). \ No newline at end of file diff --git a/docs/src/developer-documentation/concepts/dsf/spring-integration.md b/docs/src/develop/dsf/spring-framework-integration.md similarity index 95% rename from docs/src/developer-documentation/concepts/dsf/spring-integration.md rename to docs/src/develop/dsf/spring-framework-integration.md index 74fe000f0..55f96f342 100644 --- a/docs/src/developer-documentation/concepts/dsf/spring-integration.md +++ b/docs/src/develop/dsf/spring-framework-integration.md @@ -1,9 +1,9 @@ --- -title: Spring Integration +title: Spring Framework Integration icon: creative --- -### Spring Integration +### Spring Framework Integration Since the DSF also employs the use of the [Spring Framework](https://spring.io/projects/spring-framework) you will also have to provide some Spring functionality. When deployed, every process plugin exists in its own [Spring context](https://docs.spring.io/spring-framework/reference/core/beans/introduction.html). To make the process plugin work, you have to provide [Spring Beans](https://docs.spring.io/spring-framework/reference/core/beans/definition.html) with `prototype` [scope](https://docs.spring.io/spring-framework/reference/core/beans/factory-scopes.html) for all classes which either extend or implement the following classes/interfaces (as of version 1.4.0): - `AbstractTaskMessageSend` diff --git a/docs/src/develop/dsf/versions-placeholders-urls.md b/docs/src/develop/dsf/versions-placeholders-urls.md new file mode 100644 index 000000000..0381ec629 --- /dev/null +++ b/docs/src/develop/dsf/versions-placeholders-urls.md @@ -0,0 +1,38 @@ +--- +title: Versions, Placeholders and URLs +icon: creative +--- + +### Versions, Placeholders and URLs + +#### Version Pattern + +Process plugin versions have to obey the pattern: +``` +\d+\.\d+\.\d+\.\d+ Example: 1.2.3.4 +``` + +The first two numbers (`1.2`) are used in FHIR resources and signal changes which break compatibility with previous process versions. For example, altering FHIR resources usually results in a breaking change. The latter two (`3.4`) signal changes which do not break compatibility with previous process versions. Specifically, the 4th number is reserved for bug-fixes and the 3rd number includes all other non-breaking changes. + +#### Placeholders + +To avoid specifying the version and release date in multiple files, the placeholders `#{version}` and `#{date}` can be used within FHIR resources and BPMN models. They are replaced with the values returned by the methods `ProcessPluginDefinition#getResourceVersion` and `ProcessPluginDefinition#getReleaseDate` respectively during deployment of a process plugin by the DSF BPE server. There is also a placeholder for the organization the DSF instance is running in: `#{organization}`, typically use in [Draft Task Resources](draft-task-resources.md). + +#### URLs + +BPMN models have an ID call process definition key. The BPMN process definition key needs to be specified following the pattern: +``` +^[-a-zA-Z0-9]+_[-a-zA-Z0-9]+$ Example: domainorg_processKey +``` +In addition, the BPMN model needs to specify a version. You should be using the ``#{version}`` [placeholder](#placeholders) for this as well. The DSF will also reference this process in URL form in FHIR resources: +``` +http://domain.org/bpe/Process/processKey|1.2 +``` + +As you can see, the version in the URL ``|1.2`` only uses the resource version and omits the code base version. As mentioned in [Version Pattern](#version-pattern), this means that only changes to the first two version numbers are significant to signal compatibility when communicating with other process plugin instances. The process definition key and URL are also related to each other. The DSF will try to match BPMN models to FHIR resources by transforming the URL into a process definition key. That is why it is important you obey the pattern above. + +You will use the above URL as your instantiatesCanonical value for [Task](../fhir/task.md) profile definitions as well as references to [Task](../fhir/task.md) profiles in other resources. You will also use it as the URL value for your [ActivityDefinitions](../fhir/activitydefinition.md). In this case though, you have to split up the URL into two parts. You will separate the version (``|1.2``) from the URL and use it as a value for the `ActivityDefinition.version` element. Since it refers to the plugin's resource version, you should also use the `#{version}` [placeholder](#placeholders) here instead. Going by the example from above, you will be left with a URL that looks like this: +``` +http://domain.org/bpe/Process/processKey +``` +This will be the value for your `ActivityDefinition.url` element with `#{version}` as the value for your `ActivityDefinition.version` element. \ No newline at end of file diff --git a/docs/src/develop/fhir/activitydefinition.md b/docs/src/develop/fhir/activitydefinition.md new file mode 100644 index 000000000..97e0956a3 --- /dev/null +++ b/docs/src/develop/fhir/activitydefinition.md @@ -0,0 +1,23 @@ +--- +title: ActivityDefinition +icon: creative +--- + +### ActivityDefinition + +[ActivityDefinitions](http://hl7.org/fhir/R4/activitydefinition.html) are used by the DSF to advertise which processes are available at any given instance and who is allowed to request and who is allowed to execute a process. The DSF defined elements for this purpose in the [dsf-activity-definition](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-activity-definition-1.0.0.xml) profile. + + +The most important elements in ActivityDefinitions are: +- `message-name` +- `task-profile` +- `requester` +- `recipient` + +The `message-name` element contains the name of the [BPMN message start event](../bpmn/messaging.md#message-start-event) or [BPMN message intermediate catching event](../bpmn/messaging.md#message-intermediate-catching-event) which expects a [Task](task.md) resource complying to the profile defined by `task-profile`. + +The `requester` and `recipient` elements define the organisation(s) or person(s) who are allowed to request or receive the message specified by `message-name`. The receiving DSF instance is the one who will execute the process connected to the message. + +You will have to create your own [ActivityDefinitions](activitydefinition.md) when developing a process plugin. If you are fluent in reading XML FHIR definitions and translating them into XML resources, you can take a look at the DSF's profile for ActivityDefinitions [here](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-activity-definition-1.0.0.xml). ActivityDefinitions also reference other resource definitions. Depending on the resource, you will find them in one of [these folders](https://github.com/datasharingframework/dsf/tree/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir). If you are not as comfortable with these requirements you might want to check out the guide on [creating ActivityDefinitions](../guides/creating-an-activity-definition.md). + +You can also find examples for all possible `requester` and `recipient` elements [here](../dsf/requester-and-recipient.md). \ No newline at end of file diff --git a/docs/src/developer-documentation/concepts/fhir/codesystem.md b/docs/src/develop/fhir/codesystem.md similarity index 82% rename from docs/src/developer-documentation/concepts/fhir/codesystem.md rename to docs/src/develop/fhir/codesystem.md index 6787445c9..e40a365f2 100644 --- a/docs/src/developer-documentation/concepts/fhir/codesystem.md +++ b/docs/src/develop/fhir/codesystem.md @@ -5,8 +5,8 @@ icon: creative ### CodeSystem -[CodeSystems](https://www.hl7.org/fhir/R4/codesystem.html) usually represent a set of concepts which can be assigned to a code (think LOINC). If you want to use a Code in a resource, you will usually include them in a [ValueSet](../../concepts/fhir/valueset.md). +[CodeSystems](https://www.hl7.org/fhir/R4/codesystem.html) usually represent a set of concepts which can be assigned to a code (think LOINC). If you want to use a Code in a resource, you will usually include them in a [ValueSet](valueset.md). Plugin development for the DSF requires the use of [CodeSystems](https://www.hl7.org/fhir/R4/codesystem.html) in two major ways: 1. Using existing [DSF CodeSystems](https://github.com/datasharingframework/dsf/tree/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/CodeSystem) in other FHIR resources like the [dsf-extension-process-authorization](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-extension-process-authorization-1.0.0.xml). -2. Creating your own CodeSystem to add additional [Input Parameters](../../concepts/fhir/task.md#task-input-parameters) to your [Task](../../concepts/fhir/task.md) profiles. \ No newline at end of file +2. Creating your own CodeSystem to add additional [Input Parameters](task.md#task-input-parameters) to your [Task](task.md) profiles. \ No newline at end of file diff --git a/docs/src/develop/fhir/index.md b/docs/src/develop/fhir/index.md new file mode 100644 index 000000000..719581424 --- /dev/null +++ b/docs/src/develop/fhir/index.md @@ -0,0 +1,15 @@ +--- +title: FHIR +icon: creative +--- + +## Introduction + +The DSF uses a variety of [FHIR resources](https://dsf.dev/intro/info/basics.html#why-are-we-using-fhir-and-bpmn). The DSF uses XML as the format for FHIR resources. The most important resources for plugin development are [ActivityDefinitions](activitydefinition.md), [CodeSystems](codesystem.md), [Tasks](task.md) and [ValueSets](valueset.md). There is also a catalog of DSF-specific FHIR resources including CodeSystems, ValueSets and Extensions. For now, you can find them in the official DSF GitHub repository [here](https://github.com/datasharingframework/dsf/tree/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir). + +## Details + +- [ActivityDefinition](activitydefinition.md) +- [CodeSystem](codesystem.md) +- [Task](task.md) +- [ValueSet](valueset.md) \ No newline at end of file diff --git a/docs/src/developer-documentation/concepts/fhir/task.md b/docs/src/develop/fhir/task.md similarity index 81% rename from docs/src/developer-documentation/concepts/fhir/task.md rename to docs/src/develop/fhir/task.md index 85e6dab5e..a647fc46c 100644 --- a/docs/src/developer-documentation/concepts/fhir/task.md +++ b/docs/src/develop/fhir/task.md @@ -5,7 +5,7 @@ icon: creative ### Task -The [FHIR Task](https://www.hl7.org/fhir/R4/task.html) resource enables the DSF's distributed communication. Whenever a BPMN process instance communicates with a different process instance, the DSF will create a Task resource based on parameters you set in the BPMN model and during execution. It will then automatically send the Task resource to the recipient to start or continue whatever process the Task resource referred to. All Task resources used in the DSF derive from the [dsf-task-base](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-task-base-1.0.0.xml). This profile includes a splicing for `Task.input` with three additional [Input Parameters](../../concepts/fhir/task.md#task-input-parameters): +The [FHIR Task](https://www.hl7.org/fhir/R4/task.html) resource enables the DSF's distributed communication. Whenever a BPMN process instance communicates with a different process instance, the DSF will create a Task resource based on parameters you set in the BPMN model and during execution. It will then automatically send the Task resource to the recipient to start or continue whatever process the Task resource referred to. All Task resources used in the DSF derive from the [dsf-task-base](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-task-base-1.0.0.xml). This profile includes a splicing for `Task.input` with three additional [Input Parameters](task.md#task-input-parameters): - `message-name` - `business-key` - `correlation-key` @@ -14,6 +14,6 @@ When creating your own plugin, you will want to create your own profiles based o #### Task Input Parameters -Task Input Parameters allow you to add additional information to [Task](task.md#task) resources. For example, if your particular data exchange requires additional medical data, you would add a slice to your Task profile in the same way the [dsf-task-base](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-task-base-1.0.0.xml) adds slices to the original [FHIR Task](https://www.hl7.org/fhir/R4/task.html) resource. Notice that this also requires creating a [CodeSystem](../../concepts/fhir/codesystem.md) and including it in a [ValueSet](../../concepts/fhir/valueset.md) to be able to use it in the Task resource. +Task Input Parameters allow you to add additional information to [Task](task.md#task) resources. For example, if your particular data exchange requires additional medical data, you would add a slice to your Task profile in the same way the [dsf-task-base](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-task-base-1.0.0.xml) adds slices to the original [FHIR Task](https://www.hl7.org/fhir/R4/task.html) resource. Notice that this also requires creating a [CodeSystem](codesystem.md) and including it in a [ValueSet](valueset.md) to be able to use it in the Task resource. -If these instructions are insufficient you can check out the guide on [how to add Task Input Parameters](../../guides/adding-task-input-parameters-to-task-profiles.md). \ No newline at end of file +If these instructions are insufficient you can check out the guide on [how to add Task Input Parameters](../guides/adding-task-input-parameters-to-task-profiles.md). \ No newline at end of file diff --git a/docs/src/develop/fhir/valueset.md b/docs/src/develop/fhir/valueset.md new file mode 100644 index 000000000..6be03a3fb --- /dev/null +++ b/docs/src/develop/fhir/valueset.md @@ -0,0 +1,10 @@ +--- +title: ValueSet +icon: creative +--- + +### ValueSet + +[ValueSets](https://www.hl7.org/fhir/R4/valueset.html) bind codes from [CodeSystems](codesystem.md) to coded elements like `code`, `Coding` or `CodeableConcept`. + +[ValueSets](https://www.hl7.org/fhir/R4/valueset.html) are mostly needed to use the [Concepts](https://www.hl7.org/fhir/R4/codesystem-definitions.html#CodeSystem.concept) from [CodeSystems](codesystem.md) in your [Task](task.md) profiles. \ No newline at end of file diff --git a/docs/src/develop/guides/accessing-bpmn-process-variables.md b/docs/src/develop/guides/accessing-bpmn-process-variables.md new file mode 100644 index 000000000..f03bee5d0 --- /dev/null +++ b/docs/src/develop/guides/accessing-bpmn-process-variables.md @@ -0,0 +1,10 @@ +--- +title: Accessing BPMN Process Variables +icon: creative +--- + +### Accessing BPMN Process Variables + +After creating a [Service Delegate](../dsf/service-delegates.md) or [Message Delegate](../dsf/message-delegates.md), you might want to retrieve data from or store data in the [BPMN process variables](../dsf/bpmn-process-variables.md). You can achieve this either through the [BPMN process execution](../dsf/bpmn-process-execution.md) or via the `Variables` class. *It is very much recommended to use the latter method*. + +The `Variables` class provides lots of utility methods to read or write certain types of [BPMN process variables](../dsf/bpmn-process-variables.md). If for some reason you need to fall back on the [BPMN process execution](../dsf/bpmn-process-execution.md) to solve your problem, we would like to learn how the current API of the `Variables` class is limiting you. Contact us, and we might turn it into a feature request ([Contribute](https://dsf.dev/stable/contribute)). diff --git a/docs/src/develop/guides/accessing-task-resources-during-execution.md b/docs/src/develop/guides/accessing-task-resources-during-execution.md new file mode 100644 index 000000000..196e16381 --- /dev/null +++ b/docs/src/develop/guides/accessing-task-resources-during-execution.md @@ -0,0 +1,12 @@ +--- +title: Accessing Task Resources During Execution +icon: creative +--- + +### Accessing Task Resources During Execution + +If you want access to the [Task](../fhir/task.md) resources in your [Service](../dsf/service-delegates.md) / [Message](../dsf/message-delegates.md) Delegates, the `Variables` class will provide methods which return certain kinds of [Task](../fhir/task.md) resources. The most commonly used ones are the start [Task](../fhir/task.md), referring to the [Task](../fhir/task.md) / [Message Start Event](../bpmn/messaging.md#message-start-event) responsible for starting the process, and the latest [Task](../fhir/task.md), referring to most recently received [Task](../fhir/task.md) / Message. +In principle, this is sufficient to access all information in a [Task](../fhir/task.md) resource, since you have the [Task](../fhir/task.md) resource's Java object, but very cumbersome. +Instead of navigating the [Task](../fhir/task.md) resource's element tree, you should first try to use the [ProcessPluginApi's](../dsf/process-plugin-api.md) `TaskHelper` in conjunction with the method above. The `TaskHelper` class offers specific methods related to [Task](../fhir/task.md) resources. +The most common use case for this is retrieving data from a [Task's](../fhir/task.md) [Input Parameter](../fhir/task.md#task-input-parameters) or creating a new [Input Parameter](../fhir/task.md#task-input-parameters) for a [Message Delegate's](../dsf/message-delegates.md) `getAdditionalInputParameters` method. When retrieving data from a [Task's](../fhir/task.md) Input Parameter you first have to get to the [Input Parameter](../fhir/task.md#task-input-parameters) you are looking to extract data from. You can use one of the `TaskHelper's` getters for [Input Parameters](../fhir/task.md#task-input-parameters) to find the right one. The methods will try to match the provided [CodeSystem](../fhir/codesystem.md) and Code to any [Input Parameter](../fhir/task.md#task-input-parameters) of the provided [Task](../fhir/task.md) resource. Depending on the method you chose you will for example receive all matches or just the first one. +To create new [Input Parameters](../fhir/task.md#task-input-parameters) to attach to a [Task](../fhir/task.md) resource, you may invoke the `TaskHelper#createInput` method. This is most often used when overriding the `getAdditionalInputParamters` method of you [Message Delegate](../dsf/message-delegates.md). \ No newline at end of file diff --git a/docs/src/developer-documentation/guides/adding-task-input-parameters-to-task-profiles.md b/docs/src/develop/guides/adding-task-input-parameters-to-task-profiles.md similarity index 81% rename from docs/src/developer-documentation/guides/adding-task-input-parameters-to-task-profiles.md rename to docs/src/develop/guides/adding-task-input-parameters-to-task-profiles.md index 3fded3631..7a625d5f4 100644 --- a/docs/src/developer-documentation/guides/adding-task-input-parameters-to-task-profiles.md +++ b/docs/src/develop/guides/adding-task-input-parameters-to-task-profiles.md @@ -5,9 +5,9 @@ icon: creative ### Adding Task Input Parameters to Task Profiles -When adding a new [Input Parameter](../concepts/fhir/task.md#task-input-parameters) to a [Task](../concepts/fhir/task.md) profile, you are essentially adding a new slice to `Task.input`. [Slicing](https://www.hl7.org/fhir/R4/profiling.html#slicing) is part of [profiling](https://www.hl7.org/fhir/R4/profiling.html) in FHIR. Profiling lets you create your own FHIR definitions based on pre-existing FHIR definitions. A slicing defines constraints on element lists like `Task.input` e.g. by only allowing the elements to be of certain types. +When adding a new [Input Parameter](../fhir/task.md#task-input-parameters) to a [Task](../fhir/task.md) profile, you are essentially adding a new slice to `Task.input`. [Slicing](https://www.hl7.org/fhir/R4/profiling.html#slicing) is part of [profiling](https://www.hl7.org/fhir/R4/profiling.html) in FHIR. Profiling lets you create your own FHIR definitions based on pre-existing FHIR definitions. A slicing defines constraints on element lists like `Task.input` e.g. by only allowing the elements to be of certain types. For example, you might have a list of fruits in a `FruitBasket` resource. Constraining that list to only include fruits of type `Apple`, `Banana` and `Orange` would be considered [slicing](https://www.hl7.org/fhir/R4/profiling.html#slicing). -This guide will not cover how slicing works in general, only for the case presented by the DSF FHIR resource context. Our goal will be to add a new [Input Parameter](../concepts/fhir/task.md#task-input-parameters) of type `example-input` to the `task-start-dic-process.xml` profile which will be used to submit `integer` values to our `dicProcess`. +This guide will not cover how slicing works in general, only for the case presented by the DSF FHIR resource context. Our goal will be to add a new [Input Parameter](../fhir/task.md#task-input-parameters) of type `example-input` to the `task-start-dic-process.xml` profile which will be used to submit `integer` values to our `dicProcess`. Let us start out by adding a slice to `task-start-dic-process.xml`. Since there is already a slicing defined on `Task.input` by `task-start-dic-process.xml`'s `baseDefinition`, we have to check out this resource first. As a part of the [differential](https://www.hl7.org/fhir/R4/profiling.html#snapshot) statement, slicing also uses [Element Definitions](https://www.hl7.org/fhir/R4/elementdefinition.html). The slicing for `Task.input` is defined in this part of the `baseDefinition`: @@ -54,7 +54,7 @@ Let us revisit `task-start-dic-process.xml` and start adding a slice called `exa We have now defined a slice on `Task.input` with the name and id of `example-input` and cardinality of `1..1`. You might want a different cardinality for your use case. We recommend you also take a look at the documentation for [ElementDefinition.id](https://www.hl7.org/fhir/R4/elementdefinition.html#id) and [ElementDefinition.path](https://www.hl7.org/fhir/R4/elementdefinition.html#path). They explain how to create the proper values for these elements. Cardinality is also part of the [element definition](https://www.hl7.org/fhir/R4/elementdefinition.html) hierarchy (see [ElementDefinition.min](https://www.hl7.org/fhir/R4/elementdefinition-definitions.html#ElementDefinition.min) and [ElementDefinition.max](https://www.hl7.org/fhir/R4/elementdefinition-definitions.html#ElementDefinition.max)). -Next up, we need to define the binding for `Task.input:example-input.type`. Because `Task.input.type` is a `CodeableConcept` which uses codings from a [ValueSet](../concepts/fhir/valueset.md), the [discriminator](https://www.hl7.org/fhir/R4/profiling.html#discriminator) requires us to use `required` as the binding strength: +Next up, we need to define the binding for `Task.input:example-input.type`. Because `Task.input.type` is a `CodeableConcept` which uses codings from a [ValueSet](../fhir/valueset.md), the [discriminator](https://www.hl7.org/fhir/R4/profiling.html#discriminator) requires us to use `required` as the binding strength: ```xml <StructureDefinition xmlns="http://hl7.org/fhir"> ... @@ -76,7 +76,7 @@ Next up, we need to define the binding for `Task.input:example-input.type`. Beca </differential> </StructureDefinition> ``` -As you can see, we referenced a [ValueSet](../concepts/fhir/valueset.md) in this binding. When adding an actual slice for your use case, you will have to reference an existing [ValueSet](../concepts/fhir/valueset.md) resource or create a new one. A guide on how to create them can be found [here](../guides/creating-valuesets-for-dsf-processes.md). +As you can see, we referenced a [ValueSet](../fhir/valueset.md) in this binding. When adding an actual slice for your use case, you will have to reference an existing [ValueSet](../fhir/valueset.md) resource or create a new one. A guide on how to create them can be found [here](../guides/creating-valuesets-for-dsf-processes.md). Since the [discriminator](https://www.hl7.org/fhir/R4/profiling.html#discriminator) requires `Task.input.coding.code` and `Task.input.coding.system` to be present, we will make `Task.input.coding` mandatory as well: ```xml @@ -144,7 +144,7 @@ In the beginning we mentioned how `Task.input.type.coding.system` and `Task.inpu ``` *Notice that we also made the two elements mandatory because they are required by the discriminator.* -For the `type.coding.system` element we referenced a [CodeSystem](../concepts/fhir/codesystem.md). The `type.coding.code` element uses a code from this [CodeSystem](../concepts/fhir/codesystem.md) called `example-input`. This is the mechanism by which you actually "name" your [Input Parameter](../concepts/fhir/task.md#task-input-parameters). The `type.coding.code` value will identify your [Input Parameter](../concepts/fhir/task.md#task-input-parameters) when you use it in an actual [Task](../concepts/fhir/task.md#task-input-parameters) resource. Here is how this would look like: +For the `type.coding.system` element we referenced a [CodeSystem](../fhir/codesystem.md). The `type.coding.code` element uses a code from this [CodeSystem](../fhir/codesystem.md) called `example-input`. This is the mechanism by which you actually "name" your [Input Parameter](../fhir/task.md#task-input-parameters). The `type.coding.code` value will identify your [Input Parameter](../fhir/task.md#task-input-parameters) when you use it in an actual [Task](../fhir/task.md#task-input-parameters) resource. Here is how this would look like: ```xml <Task xmlns="http://hl7.org/fhir"> @@ -161,7 +161,7 @@ For the `type.coding.system` element we referenced a [CodeSystem](../concepts/fh </Task> ``` -When adding an actual slice for your use case, you will also need to reference an existing [CodeSystem](../concepts/fhir/codesystem.md) resource or create a new one to reference. A guide on how to create them can be found [here](../guides/creating-codesystems-for-dsf-processes.md). +When adding an actual slice for your use case, you will also need to reference an existing [CodeSystem](../fhir/codesystem.md) resource or create a new one to reference. A guide on how to create them can be found [here](../guides/creating-codesystems-for-dsf-processes.md). `Task.input.value[x]` is the actual value you will submit using your Input Parameter. You can make it any of [these](https://www.hl7.org/fhir/R4/datatypes.html#open) data types. This is because `Type.input.value[x]` refers to `*` instead of any particular type in its [definition](https://www.hl7.org/fhir/R4/task-definitions.html#Task.input.value_x_). Let us define it as an `integer` type`: diff --git a/docs/src/developer-documentation/guides/configuring-the-read-access-tag.md b/docs/src/develop/guides/configuring-the-read-access-tag.md similarity index 94% rename from docs/src/developer-documentation/guides/configuring-the-read-access-tag.md rename to docs/src/develop/guides/configuring-the-read-access-tag.md index 983d7cdba..28a0bdf35 100644 --- a/docs/src/developer-documentation/guides/configuring-the-read-access-tag.md +++ b/docs/src/develop/guides/configuring-the-read-access-tag.md @@ -5,7 +5,7 @@ icon: creative ### Configuring the Read Access Tag -To start off, you want to take a look at the [CodeSystem](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/CodeSystem/dsf-read-access-tag-1.0.0.xml) defined for the [Read Access Tag](../concepts/dsf/read-access-tag.md) and choose one of the codes from it: +To start off, you want to take a look at the [CodeSystem](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/CodeSystem/dsf-read-access-tag-1.0.0.xml) defined for the [Read Access Tag](../dsf/read-access-tag.md) and choose one of the codes from it: ```xml <CodeSystem xmlns="http://hl7.org/fhir"> ... @@ -34,7 +34,7 @@ To start off, you want to take a look at the [CodeSystem](https://github.com/dat </CodeSystem> ``` -The codes `LOCAL` and `ALL` are trivial. Their [Read Access Tag](../concepts/dsf/read-access-tag.md) would look like this: +The codes `LOCAL` and `ALL` are trivial. Their [Read Access Tag](../dsf/read-access-tag.md) would look like this: ```xml <meta> <tag> @@ -134,7 +134,7 @@ The most important part of it is the `differential` statement. It uses [element </StructureDefinition> ``` -All extensions for the [Read Access Tag](../concepts/dsf/read-access-tag.md) CodeSystem are defined on the `meta.tag.extension` element through the extension's `context` element: +All extensions for the [Read Access Tag](../dsf/read-access-tag.md) CodeSystem are defined on the `meta.tag.extension` element through the extension's `context` element: ```xml <context> <type value="element" /> @@ -344,7 +344,7 @@ Instead of `Identifier`, the `value[x]` element is now defined as a `Coding` typ </meta> ``` -A `Coding` has to belong to some [CodeSystem](../concepts/fhir/codesystem.md). The DSF has a CodeSystem called [dsf-organization-role](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/CodeSystem/dsf-organization-role-1.0.0.xml). Before creating your own CodeSystem, it is worth taking a look at it to see if an appropriate role already exists for your organization. For demonstration purposes, we will be using the `DIC` role: +A `Coding` has to belong to some [CodeSystem](../fhir/codesystem.md). The DSF has a CodeSystem called [dsf-organization-role](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/CodeSystem/dsf-organization-role-1.0.0.xml). Before creating your own CodeSystem, it is worth taking a look at it to see if an appropriate role already exists for your organization. For demonstration purposes, we will be using the `DIC` role: ```xml <meta> <tag> diff --git a/docs/src/developer-documentation/guides/creating-an-activity-definition.md b/docs/src/develop/guides/creating-an-activity-definition.md similarity index 89% rename from docs/src/developer-documentation/guides/creating-an-activity-definition.md rename to docs/src/develop/guides/creating-an-activity-definition.md index f83c866bf..5e485da52 100644 --- a/docs/src/developer-documentation/guides/creating-an-activity-definition.md +++ b/docs/src/develop/guides/creating-an-activity-definition.md @@ -17,14 +17,14 @@ It is divided into steps for each of the main components of ActivityDefinitions: *We will assume you know how to translate [ElementDefinitions](https://www.hl7.org/fhir/R4/elementdefinition.html) to actual elements in a FHIR resource. If you do not, you might want to check out the guide on [creating Task resources](../guides/creating-task-resources-based-on-a-definition.md) first.* #### 1. Read Access Tag -Let us start out with an empty [ActivityDefinition](../concepts/fhir/activitydefinition.md): +Let us start out with an empty [ActivityDefinition](../fhir/activitydefinition.md): ```xml <ActivityDefinition xmlns="http://hl7.org/fhir"> </ActivityDefinition> ``` -The first element in DSF FHIR resources is always the [Read Access Tag](../concepts/dsf/read-access-tag.md). It describes who is allowed to read this resource through the DSF FHIR server's REST API. You can learn more complex configurations of the [Read Access Tag](../concepts/dsf/read-access-tag.md) in [this guide](../concepts/dsf/read-access-tag.md). In this case, we will allow read access to everyone: +The first element in DSF FHIR resources is always the [Read Access Tag](../dsf/read-access-tag.md). It describes who is allowed to read this resource through the DSF FHIR server's REST API. You can learn more complex configurations of the [Read Access Tag](../dsf/read-access-tag.md) in [this guide](../dsf/read-access-tag.md). In this case, we will allow read access to everyone: ```xml <ActivityDefinition xmlns="http://hl7.org/fhir"> @@ -38,7 +38,7 @@ The first element in DSF FHIR resources is always the [Read Access Tag](../conce ``` #### 2. Extension: Process Authorization -This part of your ActivityDefinition will tell the DSF who is allowed to request and receive messages ([Task](../concepts/fhir/task.md) resources) for your BPMN process. If your plugin contains more than one BPMN process, you will have to create one [ActivityDefinition](../concepts/fhir/activitydefinition.md) for each BPMN process. It is important to note that you need to include authorization rules for **ALL** messages received in your BPMN process. This includes the message starting your BPMN process initially. You can find the extension [here](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-extension-process-authorization-1.0.0.xml). Let us continue by adding the [extension element](http://hl7.org/fhir/R4/extensibility.html#extension) with the correct URL. You can get the value for the URL from the `Extension.url` element: +This part of your ActivityDefinition will tell the DSF who is allowed to request and receive messages ([Task](../fhir/task.md) resources) for your BPMN process. If your plugin contains more than one BPMN process, you will have to create one [ActivityDefinition](../fhir/activitydefinition.md) for each BPMN process. It is important to note that you need to include authorization rules for **ALL** messages received in your BPMN process. This includes the message starting your BPMN process initially. You can find the extension [here](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-extension-process-authorization-1.0.0.xml). Let us continue by adding the [extension element](http://hl7.org/fhir/R4/extensibility.html#extension) with the correct URL. You can get the value for the URL from the `Extension.url` element: ```xml <ActivityDefinition xmlns="http://hl7.org/fhir"> ... @@ -104,14 +104,14 @@ After these initial element definitions come the elements relevant for your proc </StructureDefinition> ``` -This section tells us that we need to include exactly one extension element from the `message-name` slice in our [ActivityDefinition](../concepts/fhir/activitydefinition.md). The extension element will have a URL value of `message-name`. If you remember the `discriminator` configuration, this URL value identifies the element to belong to the `message-name` slice on `Extension.extension`. Lastly, the extension element includes a `valueString` element. In case you are wondering how `value[x]` turned into `valueString`, FHIR does not allow using `value[x]` as actual element. The value in `value[x]` is always strictly bound to some kind of type. FHIR uses the `value[x].type.code` value to determine this type and replaces `[x]` with an uppercase version of `element.type.code`. This results in the following extension element we will add to our [ActivityDefinition](../concepts/fhir/activitydefinition.md): +This section tells us that we need to include exactly one extension element from the `message-name` slice in our [ActivityDefinition](../fhir/activitydefinition.md). The extension element will have a URL value of `message-name`. If you remember the `discriminator` configuration, this URL value identifies the element to belong to the `message-name` slice on `Extension.extension`. Lastly, the extension element includes a `valueString` element. In case you are wondering how `value[x]` turned into `valueString`, FHIR does not allow using `value[x]` as actual element. The value in `value[x]` is always strictly bound to some kind of type. FHIR uses the `value[x].type.code` value to determine this type and replaces `[x]` with an uppercase version of `element.type.code`. This results in the following extension element we will add to our [ActivityDefinition](../fhir/activitydefinition.md): ```xml <extension url="message-name"> <valueString value="myMessage"/> </extension> ``` -For your use case, you have to replace `myMessage` with the name of the [BPMN message event](../concepts/bpmn/messaging.md) that is expecting this message. +For your use case, you have to replace `myMessage` with the name of the [BPMN message event](../bpmn/messaging.md) that is expecting this message. <details> <summary>This is how your ActivityDefinition should look like so far</summary> @@ -161,7 +161,7 @@ The next slice is called `task-profile`: </StructureDefinition> ``` -This section has almost the same structure as `message-name`. The only difference is the value for `value[x].type.code`. This means that instead of `valueString`, we will have to use a `valueCanonical` element for `task-profile.value[x]`. Canonical values referring to [Task](../concepts/fhir/task.md) profiles in ActivityDefinitions have to conform to the rules outlined by the documentation on [URLs](../concepts/dsf/about-version-placeholders-and-urls.md#urls). From the definition above, we will create the following extension element and add it to our [ActivityDefinition](../concepts/fhir/activitydefinition.md): +This section has almost the same structure as `message-name`. The only difference is the value for `value[x].type.code`. This means that instead of `valueString`, we will have to use a `valueCanonical` element for `task-profile.value[x]`. Canonical values referring to [Task](../fhir/task.md) profiles in ActivityDefinitions have to conform to the rules outlined by the documentation on [URLs](../dsf/versions-placeholders-urls.md#urls). From the definition above, we will create the following extension element and add it to our [ActivityDefinition](../fhir/activitydefinition.md): ```xml <extension url="task-profile"> <valueCanonical value="http://dsf.dev/fhir/StructureDefinition/my-task|#{version}"/> @@ -230,7 +230,7 @@ The next slice is `requester`: </differential> </StructureDefinition> ``` -Instead of a `string` or `canonical` type for `value[x]` we now have a `Coding` type. See the [FHIR documentation on Codings](https://www.hl7.org/fhir/R4/datatypes.html#Coding) for more in-depth information. `Codings` are elements which contain, among other things, a `code` and the `system` the code belongs to. In the same way we transformed `value[x]` into `valueString` or `valueCanonical` before, we will also have to turn `value[x]` into `valueCoding`. To use `Codings` in `valueCoding` elements, they are usually bound to the element through a [ValueSet](../concepts/fhir/valueset.md). This is the responsibility of the `binding` element. You can also see that `value[x].type.profile` lists a number of profiles. Instead of defining the elements in the same file, they were defined in different files for better readability. Depending on your use case, you have to pick one of the profiles. +Instead of a `string` or `canonical` type for `value[x]` we now have a `Coding` type. See the [FHIR documentation on Codings](https://www.hl7.org/fhir/R4/datatypes.html#Coding) for more in-depth information. `Codings` are elements which contain, among other things, a `code` and the `system` the code belongs to. In the same way we transformed `value[x]` into `valueString` or `valueCanonical` before, we will also have to turn `value[x]` into `valueCoding`. To use `Codings` in `valueCoding` elements, they are usually bound to the element through a [ValueSet](../fhir/valueset.md). This is the responsibility of the `binding` element. You can also see that `value[x].type.profile` lists a number of profiles. Instead of defining the elements in the same file, they were defined in different files for better readability. Depending on your use case, you have to pick one of the profiles. Here is what they mean: - `local-all`: All local requests will be allowed. Local requests are identified by matching the requester's certificate to a thumbprint which was internally marked by the DSF FHIR server as belonging to a local organization. - `local-organization`: All local requests made from an organization with a specific `organization-identifier` will be allowed. @@ -240,9 +240,9 @@ Here is what they mean: can be found [here](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/CodeSystem/dsf-practitioner-role-1.0.0.xml). This allows for more granularity when defining authorization rules within an organization and can be integrated into local user management via [OpenID Connect](https://dsf.dev/stable/maintain/fhir/access-control.html). -As you can see, there are no `practitioner` versions of `remote` authorization rules. From the perspective of the receiving DSF instance, remote requests are always issued by an organization. They do not hold any information about the local user management of the requesting organization. You can also find examples of all Codings from above [here](../concepts/dsf/examples-for-requester-and-recipient-elements.md). +As you can see, there are no `practitioner` versions of `remote` authorization rules. From the perspective of the receiving DSF instance, remote requests are always issued by an organization. They do not hold any information about the local user management of the requesting organization. You can also find examples of all Codings from above [here](../dsf/requester-and-recipient.md). -It is also good to keep in mind that you are allowed to add any number of `requester` elements into your [ActivityDefinition](../concepts/fhir/activitydefinition.md). Let us start out by adding a `requester` element like we did for previous elements: +It is also good to keep in mind that you are allowed to add any number of `requester` elements into your [ActivityDefinition](../fhir/activitydefinition.md). Let us start out by adding a `requester` element like we did for previous elements: ```xml <extension url="requester"> @@ -368,7 +368,7 @@ It defines an extension called `organization-practitioner` which is identified t </differential> ``` -This extension does not reference any other files. This means we reached the "deepest" level. So now we can start working our way back up again from here, by translating this definition into actual extension elements, then inserting it into the Coding we selected, translating the rest of the element definitions from the Coding resource and adding everything to our [ActivityDefinition](../concepts/fhir/activitydefinition.md). +This extension does not reference any other files. This means we reached the "deepest" level. So now we can start working our way back up again from here, by translating this definition into actual extension elements, then inserting it into the Coding we selected, translating the rest of the element definitions from the Coding resource and adding everything to our [ActivityDefinition](../fhir/activitydefinition.md). We will start with the `Extension.url` element, since the `Extension` element is the parent element for all slices on the `Extension.extension` elements: ```xml @@ -453,7 +453,7 @@ Now might be a good time to look at the [differential](#coding-differential) fro </valueCoding> </extension> ``` -Now we are finished with the `requester` extension and can add it to our [ActivityDefinition](../concepts/fhir/activitydefinition.md) under the [dsf-extension-process-authorization](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-extension-process-authorization-1.0.0.xml). +Now we are finished with the `requester` extension and can add it to our [ActivityDefinition](../fhir/activitydefinition.md) under the [dsf-extension-process-authorization](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-extension-process-authorization-1.0.0.xml). <details> <summary>This is how your ActivityDefinition should look like so far</summary> @@ -593,11 +593,11 @@ The last element defined in the [process authorization extension](https://github #### 3. BPE Managed Elements -Some elements of [ActivityDefinitions](../concepts/fhir/activitydefinition.md) are managed by the DSF BPE and replaced with certain values at appropriate times. +Some elements of [ActivityDefinitions](../fhir/activitydefinition.md) are managed by the DSF BPE and replaced with certain values at appropriate times. The following elements are managed by the DSF BPE: -- `ActivityDefinition.version` should use the [placeholder](../concepts/dsf/about-version-placeholders-and-urls.md#placeholders) `#{version}` -- `ActivityDefinition.date` is not required, but should you decide to include it, use the [placeholder](../concepts/dsf/about-version-placeholders-and-urls.md#placeholders) `#{date}` +- `ActivityDefinition.version` should use the [placeholder](../dsf/versions-placeholders-urls.md#placeholders) `#{version}` +- `ActivityDefinition.date` is not required, but should you decide to include it, use the [placeholder](../dsf/versions-placeholders-urls.md#placeholders) `#{date}` - `ActivityDefinition.status` must have a value of `unknown` <details> @@ -663,7 +663,7 @@ The following elements are managed by the DSF BPE: #### 4. Regular Elements -The only required elements in this set are `ActivityDefinition.url` and `ActivityDefinition.kind`. Check out the documentation on [URLs](../concepts/dsf/about-version-placeholders-and-urls.md#urls) on how to choose the correct value for `ActivityDefinition.url`. `ActivityDefinition.kind` must have the value `Task`. +The only required elements in this set are `ActivityDefinition.url` and `ActivityDefinition.kind`. Check out the documentation on [URLs](../dsf/versions-placeholders-urls.md#urls) on how to choose the correct value for `ActivityDefinition.url`. `ActivityDefinition.kind` must have the value `Task`. All other elements can technically be omitted. Still, we recommend you include the following elements: - `AcitivityDefinition.name` - `AcitivityDefinition.title` diff --git a/docs/src/developer-documentation/guides/creating-codesystems-for-dsf-processes.md b/docs/src/develop/guides/creating-codesystems-for-dsf-processes.md similarity index 74% rename from docs/src/developer-documentation/guides/creating-codesystems-for-dsf-processes.md rename to docs/src/develop/guides/creating-codesystems-for-dsf-processes.md index d939acc41..5ab6d87f1 100644 --- a/docs/src/developer-documentation/guides/creating-codesystems-for-dsf-processes.md +++ b/docs/src/develop/guides/creating-codesystems-for-dsf-processes.md @@ -5,7 +5,7 @@ icon: creative ### Creating CodeSystems for DSF Processes -You might find yourself in a situation where you need to create a [CodeSystem](../concepts/fhir/codesystem.md). For example, when defining the type of an [Input Parameter](../concepts/fhir/task.md#task-input-parameters). [CodeSystems](../concepts/fhir/codesystem.md) for the DSF differ from regular [CodeSystems](../concepts/fhir/codesystem.md) in that some element's values are managed by the DSF BPE server. You can use the following XML as a template: +You might find yourself in a situation where you need to create a [CodeSystem](../fhir/codesystem.md). For example, when defining the type of an [Input Parameter](../fhir/task.md#task-input-parameters). [CodeSystems](../fhir/codesystem.md) for the DSF differ from regular [CodeSystems](../fhir/codesystem.md) in that some element's values are managed by the DSF BPE server. You can use the following XML as a template: ```xml <CodeSystem xmlns="http://hl7.org/fhir"> <meta> @@ -39,4 +39,4 @@ You might find yourself in a situation where you need to create a [CodeSystem](. ``` Replace dummy values with appropriate values of your own. Do not change elements managed by the DSF BPE server. You can add as many codes as you like by defining more `concept` elements. -The DSF BPE server will read your [CodeSystem](../concepts/fhir/codesystem.md) from `tutorial-process/src/main/resources/fhir/CodeSystem`. \ No newline at end of file +The DSF BPE server will read your [CodeSystem](../fhir/codesystem.md) from `tutorial-process/src/main/resources/fhir/CodeSystem`. \ No newline at end of file diff --git a/docs/src/developer-documentation/guides/creating-task-resources-based-on-a-definition.md b/docs/src/develop/guides/creating-task-resources-based-on-a-definition.md similarity index 68% rename from docs/src/developer-documentation/guides/creating-task-resources-based-on-a-definition.md rename to docs/src/develop/guides/creating-task-resources-based-on-a-definition.md index 220b519dd..6306ab128 100644 --- a/docs/src/developer-documentation/guides/creating-task-resources-based-on-a-definition.md +++ b/docs/src/develop/guides/creating-task-resources-based-on-a-definition.md @@ -5,18 +5,18 @@ icon: creative ### Creating Task Resources Based on a Definition -This short guide should help you understand how you can create [Task](../concepts/fhir/task.md) resources for use in [Starting A Process Via Task Resources](../guides/starting-a-process-via-task-resources.md). We will employ the use of the free version of [Forge](https://simplifier.net/forge?utm_source=firely-forge) to help with visualization. You are invited to create a free account and follow along, but we will include screenshots of relevant views either way. Remember that the free version of Forge [must not be used commercially](https://simplifier.net/pricing). As an example, we will create a [Task](../concepts/fhir/task.md) resource from the `task-start-dic-process.xml` profile. +This short guide should help you understand how you can create [Task](../fhir/task.md) resources for use in [Starting A Process Via Task Resources](../guides/starting-a-process-via-task-resources.md). We will employ the use of the free version of [Forge](https://simplifier.net/forge?utm_source=firely-forge) to help with visualization. You are invited to create a free account and follow along, but we will include screenshots of relevant views either way. Remember that the free version of Forge [must not be used commercially](https://simplifier.net/pricing). As an example, we will create a [Task](../fhir/task.md) resource from the `task-start-dic-process.xml` profile. #### 1st Step: Removing Placeholders `task-start-dic-process.xml` includes placeholders for the `version` and `date` elements. For the duration of this guide, you can either remove or comment these elements, so Forge does not try to perform type checking on them, which would result in an error and Forge not loading the file. #### 2nd Step: Differential Chain -If the resource profile is only available as a [differential](https://www.hl7.org/fhir/R4/profiling.html#snapshot), like in our case, we will want to aggregate the changes made to the base resource (in this case [Task](../concepts/fhir/task.md)) by all profiles to make it more readable. To do this, we first need all the profiles involved. We already have `task-start-dic-process.xml` in our `StructureDefinition` folder. It lists a resource called `task-base` in its `baseDefinition` element. This resource is part of the DSF and can be found [here](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-task-base-1.0.0.xml). Put it into the `StructureDefinition` folder. Since `task-base` has the original FHIR Task as its `baseDefinition` element, we are done with this chain. In forge, you should now be able to open the `StructureDefinition` folder and select the `task-start-dic-process.xml` profile. It should look something like this: +If the resource profile is only available as a [differential](https://www.hl7.org/fhir/R4/profiling.html#snapshot), like in our case, we will want to aggregate the changes made to the base resource (in this case [Task](../fhir/task.md)) by all profiles to make it more readable. To do this, we first need all the profiles involved. We already have `task-start-dic-process.xml` in our `StructureDefinition` folder. It lists a resource called `task-base` in its `baseDefinition` element. This resource is part of the DSF and can be found [here](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-task-base-1.0.0.xml). Put it into the `StructureDefinition` folder. Since `task-base` has the original FHIR Task as its `baseDefinition` element, we are done with this chain. In forge, you should now be able to open the `StructureDefinition` folder and select the `task-start-dic-process.xml` profile. It should look something like this: ![Forge overview](/photos/developer-documentation/forge_overview.png) #### 3rd Step: Building the Task Resource -We will now go through each element one by one and include it into our [Task](../concepts/fhir/task.md) resource, provided it is mandatory (cardinality at least `1..1`) according to the profile. It is important that you not use any placeholders like `#{version}` for resources not read by the DSF BPE server. This is the case if we want a [Task](../concepts/fhir/task.md) resource for use with [cURL](../guides/starting-a-process-via-task-resources.md#using-curl). But, placeholders should be used in [Draft Task Resources](../concepts/dsf/draft-task-resources.md) instead of actual values wherever possible, since those are read by the DSF BPE server. This guide will create a [Task](../concepts/fhir/task.md) resource without placeholders. We will start out with the base element for all [Task](../concepts/fhir/task.md) resources: +We will now go through each element one by one and include it into our [Task](../fhir/task.md) resource, provided it is mandatory (cardinality at least `1..1`) according to the profile. It is important that you not use any placeholders like `#{version}` for resources not read by the DSF BPE server. This is the case if we want a [Task](../fhir/task.md) resource for use with [cURL](../guides/starting-a-process-via-task-resources.md#using-curl). But, placeholders should be used in [Draft Task Resources](../dsf/draft-task-resources.md) instead of actual values wherever possible, since those are read by the DSF BPE server. This guide will create a [Task](../fhir/task.md) resource without placeholders. We will start out with the base element for all [Task](../fhir/task.md) resources: ```xml <Task xmlns="http://hl7.org/fhir"> @@ -32,7 +32,7 @@ Before we start adding any elements listed in Forge's element tree, we have to i </Task> ``` -The first element which can be found in the element tree is the `instantiatesCanonical` element. To add it, we will create an XML element with the same name and the value according to [URLs](../concepts/dsf/about-version-placeholders-and-urls.md#urls): +The first element which can be found in the element tree is the `instantiatesCanonical` element. To add it, we will create an XML element with the same name and the value according to [URLs](../dsf/versions-placeholders-urls.md#urls): ```xml <Task xmlns="http://hl7.org/fhir"> <meta> @@ -43,7 +43,7 @@ The first element which can be found in the element tree is the `instantiatesCan ``` We can continue this process for all primitive elements like these. Just make sure you pay attention to use the correct data type (e.g. proper coding value for elements with `coding` type). -By now your [Task](../concepts/fhir/task.md) resources should look something like this: +By now your [Task](../fhir/task.md) resources should look something like this: <details> <summary>Suggested solution</summary> @@ -97,7 +97,7 @@ Then, we will add primitive elements to `requester` like we did before for `Task ``` *Important to note here that the value for the `status` will always be `requested` for Tasks being posted using cURL and the `type` element for `requester` and `recipient` will always have the value `Organization` in the DSF context.* -Next, we will add the `identifier` element and its primitive sub-elements just like we started out doing it for the `requester` element. The `identifier.value` in this case will be `dic.dsf.test`. To understand why, take a look at the topic on [organization identifiers](../concepts/dsf/organization-identifiers.md): +Next, we will add the `identifier` element and its primitive sub-elements just like we started out doing it for the `requester` element. The `identifier.value` in this case will be `dic.dsf.test`. To understand why, take a look at the topic on [organization identifiers](../dsf/organization-identifiers.md): ```xml <Task xmlns="http://hl7.org/fhir"> <meta> @@ -118,7 +118,7 @@ Next, we will add the `identifier` element and its primitive sub-elements just l ``` *Notice that `requester.identifier.system` has a `Fixed value` annotation. You can see what the value is supposed to be by clicking on the `system` element in Forge or looking at the XML for the right Task profile. The right side will have all information about that element, including the actual value for `Fixed value`.* -You should now be able to fill out all elements in your [Task](../concepts/fhir/task.md) resource until you reach the [slicing](https://www.hl7.org/fhir/R4/profiling.html#slicing) for `Task.input`. Your [Task](../concepts/fhir/task.md) resource should look something like this: +You should now be able to fill out all elements in your [Task](../fhir/task.md) resource until you reach the [slicing](https://www.hl7.org/fhir/R4/profiling.html#slicing) for `Task.input`. Your [Task](../fhir/task.md) resource should look something like this: <details> <summary>Suggested solution</summary> @@ -156,7 +156,7 @@ You should now be able to fill out all elements in your [Task](../concepts/fhir/ ![Forge slice message name](/photos/developer-documentation/forge_slice_message_name.png) -If we were to continue including slices to the [Task](../concepts/fhir/task.md) resource like we did so far, we would add a `message-name` element to our XML like this: +If we were to continue including slices to the [Task](../fhir/task.md) resource like we did so far, we would add a `message-name` element to our XML like this: ```xml <Task xmlns="http://hl7.org/fhir"> @@ -169,7 +169,7 @@ If we were to continue including slices to the [Task](../concepts/fhir/task.md) </Task> ``` -This approach however, would not work. FHIR processors do not use the name of the slice to map entries in your [Task](../concepts/fhir/task.md) resource to the correct slice. They use [discriminators](https://www.hl7.org/fhir/R4/profiling.html#discriminator). Discriminators define the elements a processor needs to distinguish slices by. You can see how the discriminator is configured by selecting the `input` element in Forge. In our case, a processor would look at the values for `input.type.coding.system` and `input.type.coding.code` to determine which slice this element belongs to. This only works because `input.type.coding.system` and `input.type.coding.code` are present in all slices and have a `Fixed value`. You can learn more about discriminators [here](https://www.hl7.org/fhir/R4/profiling.html#discriminator). All this means is that we effectively ignore the name of the slice as an element and start adding elements like we did before: +This approach however, would not work. FHIR processors do not use the name of the slice to map entries in your [Task](../fhir/task.md) resource to the correct slice. They use [discriminators](https://www.hl7.org/fhir/R4/profiling.html#discriminator). Discriminators define the elements a processor needs to distinguish slices by. You can see how the discriminator is configured by selecting the `input` element in Forge. In our case, a processor would look at the values for `input.type.coding.system` and `input.type.coding.code` to determine which slice this element belongs to. This only works because `input.type.coding.system` and `input.type.coding.code` are present in all slices and have a `Fixed value`. You can learn more about discriminators [here](https://www.hl7.org/fhir/R4/profiling.html#discriminator). All this means is that we effectively ignore the name of the slice as an element and start adding elements like we did before: ```xml <Task xmlns="http://hl7.org/fhir"> @@ -186,7 +186,7 @@ This approach however, would not work. FHIR processors do not use the name of th </Task> ``` -Now you should be able to add all remaining mandatory elements to your [Task](../concepts/fhir/task.md) resource on your own. In the end, it should look something like this: +Now you should be able to add all remaining mandatory elements to your [Task](../fhir/task.md) resource on your own. In the end, it should look something like this: <details> <summary>Suggested solution</summary> diff --git a/docs/src/developer-documentation/guides/creating-valuesets-for-dsf-processes.md b/docs/src/develop/guides/creating-valuesets-for-dsf-processes.md similarity index 62% rename from docs/src/developer-documentation/guides/creating-valuesets-for-dsf-processes.md rename to docs/src/develop/guides/creating-valuesets-for-dsf-processes.md index 3e9398d41..f273196ec 100644 --- a/docs/src/developer-documentation/guides/creating-valuesets-for-dsf-processes.md +++ b/docs/src/develop/guides/creating-valuesets-for-dsf-processes.md @@ -5,8 +5,8 @@ icon: creative ### Creating ValueSets for DSF Processes -You might find yourself in the situation where you need to create a [ValueSet](../concepts/fhir/valueset.md). For example, when adding [Input Parameters](../concepts/fhir/task.md#task-input-parameters) to DSF [Task](../concepts/fhir/task.md) resources, you will also have to reference a [ValueSet](../concepts/fhir/valueset.md) resource in your binding for `Task.input.type` to be able to set the type of your [Input Parameter](../concepts/fhir/task.md#task-input-parameters). [ValueSets](../concepts/fhir/valueset.md) for the DSF differ from regular [ValueSets](../concepts/fhir/valueset.md) in that some element's values are managed by the DSF BPE server. You can use the following template for your -[ValueSet](../concepts/fhir/valueset.md): +You might find yourself in the situation where you need to create a [ValueSet](../fhir/valueset.md). For example, when adding [Input Parameters](../fhir/task.md#task-input-parameters) to DSF [Task](../fhir/task.md) resources, you will also have to reference a [ValueSet](../fhir/valueset.md) resource in your binding for `Task.input.type` to be able to set the type of your [Input Parameter](../fhir/task.md#task-input-parameters). [ValueSets](../fhir/valueset.md) for the DSF differ from regular [ValueSets](../fhir/valueset.md) in that some element's values are managed by the DSF BPE server. You can use the following template for your +[ValueSet](../fhir/valueset.md): ```xml <ValueSet xmlns="http://hl7.org/fhir"> <meta> @@ -36,7 +36,7 @@ You might find yourself in the situation where you need to create a [ValueSet](. </compose> </ValueSet> ``` -Replace dummy values with appropriate values of your own. Do not change elements managed by the DSF BPE server. The `compose` element defines the codes included in this [ValueSet](../concepts/fhir/valueset.md). It holds at least one `include` element. Each `include` element refers to a [CodeSystem](../concepts/fhir/codesystem.md) and contains a list of `concept` elements which in turn contain the actual `code` element. Using one code from `my-code-system` and one code from `my-other-code-system` would result in the following `compose` element: +Replace dummy values with appropriate values of your own. Do not change elements managed by the DSF BPE server. The `compose` element defines the codes included in this [ValueSet](../fhir/valueset.md). It holds at least one `include` element. Each `include` element refers to a [CodeSystem](../fhir/codesystem.md) and contains a list of `concept` elements which in turn contain the actual `code` element. Using one code from `my-code-system` and one code from `my-other-code-system` would result in the following `compose` element: ```xml <ValueSet xmlns="http://hl7.org/fhir"> ... @@ -58,6 +58,6 @@ Replace dummy values with appropriate values of your own. Do not change elements </compose> </ValueSet> ``` -The DSF BPE server will read your [ValueSet](../concepts/fhir/valueset.md) from `tutorial-process/src/main/resources/fhir/ValueSet`. +The DSF BPE server will read your [ValueSet](../fhir/valueset.md) from `tutorial-process/src/main/resources/fhir/ValueSet`. -You might also want to check out [this guide](../guides/creating-codesystems-for-dsf-processes.md) on how to create [CodeSystems](../concepts/fhir/codesystem.md). \ No newline at end of file +You might also want to check out [this guide](../guides/creating-codesystems-for-dsf-processes.md) on how to create [CodeSystems](../fhir/codesystem.md). \ No newline at end of file diff --git a/docs/src/develop/guides/managing-mutiple-incoming-messages-and-missing-messages.md b/docs/src/develop/guides/managing-mutiple-incoming-messages-and-missing-messages.md new file mode 100644 index 000000000..a0c8f6120 --- /dev/null +++ b/docs/src/develop/guides/managing-mutiple-incoming-messages-and-missing-messages.md @@ -0,0 +1,18 @@ +--- +title: Managing Multiple Incoming Messages and Missing Messages +icon: creative +--- + +### Managing Multiple Incoming Messages and Missing Messages + +If an already running process instance is waiting for a message from another organization, the corresponding FHIR [Task](../fhir/task.md) may never arrive. Either because the other organization decides to never send the message or because some technical problem prohibits the [Task](../fhir/task.md) resource from being posted to the DSF FHIR server. This would result in stale process instances that never finish. + +At the same time, you might also expect to receive one out of a number of different message types at once. + +In order to solve both problems we can add an [Event Based Gateway](../bpmn/gateways.md#event-based-gateway) to the process waiting for a response and then either handle a [Task](../fhir/task.md) resource with the response and finish the process in a success state or trigger a [Timer Intermediate Catching Event](../bpmn/timer-intermediate-catching-events.md) after a defined wait period and finish the process in an error state. The following BPMN collaboration diagram shows how the process at the first organization would look like if we wanted to react to multiple different messages or missing messages: + +<picture> + <source media="(prefers-color-scheme: dark)" srcset="/photos/developer-documentation/event_based_gateway_inverted.svg"> + <source media="(prefers-color-scheme: light)" srcset="/photos/developer-documentation/event_based_gateway.svg"> + <img alt="BPMN collaboration diagram with an Event Based Gateway" src="/photos/developer-documentation/event_based_gateway.svg"> +</picture> diff --git a/docs/src/developer-documentation/guides/setting-targets-for-message-events.md b/docs/src/develop/guides/setting-targets-for-message-events.md similarity index 94% rename from docs/src/developer-documentation/guides/setting-targets-for-message-events.md rename to docs/src/develop/guides/setting-targets-for-message-events.md index d3d3961ee..68db0b1e0 100644 --- a/docs/src/developer-documentation/guides/setting-targets-for-message-events.md +++ b/docs/src/develop/guides/setting-targets-for-message-events.md @@ -9,6 +9,6 @@ Setting a target for a message event requires a `Target` object. To create one, #### 1. Adding the target in the message event implementation In your message event implementation (the class extending `AbstractTaskMessageSend`), you can override `AbstractTaskMessageSend#doExecute`, add your targets and then call the super-method. #### 2. Adding the target in a service task right before the message event -This is the preferred method of this tutorial but both methods will work perfectly fine. For our use cases, we usually prefer this one since there is enough complexity to warrant putting it into a separate BPMN [Service Task](../concepts/bpmn/service-tasks.md). +This is the preferred method of this tutorial but both methods will work perfectly fine. For our use cases, we usually prefer this one since there is enough complexity to warrant putting it into a separate BPMN [Service Task](../bpmn/service-tasks.md). In both cases you can access methods to create and set `targets` through the `Variables` instance. diff --git a/docs/src/develop/guides/starting-a-process-via-task-resources.md b/docs/src/develop/guides/starting-a-process-via-task-resources.md new file mode 100644 index 000000000..baa36a7bb --- /dev/null +++ b/docs/src/develop/guides/starting-a-process-via-task-resources.md @@ -0,0 +1,43 @@ +--- +title: Starting a Process via Task Resources +icon: creative +--- + +### Starting a Process via Task Resources + +To start a BPMN process, you need to create new a [Task](../fhir/task.md) resource in the DSF FHIR server by sending an HTTP request according to the [FHIR RESTful API](https://www.hl7.org/fhir/R4/http.html). Specifically, you need to [create](https://www.hl7.org/fhir/R4/http.html#create) +a resource for the first time. Also, remember that the [Task](../fhir/task.md) resource you are sending needs to comply to the [Task](../fhir/task.md) profile of the process you want to start and the [ActivityDefinition's](../fhir/activitydefinition.md) authorization rules. +There are two major ways of making this HTTP request: +1. Using cURL +2. Using the DSF FHIR server's web interface + +#### Using cURL +In order to use cURL, you will have to create an appropriate [Task](../fhir/task.md) resource to post to the DSF FHIR server. There already is a file called `example-task.xml` located in `tutorial-process/src/main/resources/fhir`. You can use this as your starting point. You can try to follow [this guide](../guides/creating-task-resources-based-on-a-definition.md), or you can check the solution branches for this file if you need ideas on how to fill it out properly. + +Below are some cURL command skeletons. Replace all <>-Placeholders with appropriate values. Host name depends on the instance you want to address. + +##### Linux: +```shell +curl https://<instance-host-name>/fhir/Task \ +--cacert <path/to/ca-certificate-file.pem> \ +--cert <path/to/client-certificate-file.pem>:password \ +--key <path/to/client-private-key-file.pem> \ +-H "Content-Type: application/fhir+xml" \ +-H "Accept: application/fhir+xml" \ +-d @<path/to/example-task.xml> +``` +##### Windows CMD: +```shell +curl https://<instance-host-name>/fhir/Task ^ +--cacert <path/to/ca-certificate-file.pem> ^ +--cert <path/to/client-certificate-file.pem>:password ^ +--key <path/to/client-private-key-file.pem> ^ +-H "Content-Type: application/fhir+xml" ^ +-H "Accept: application/fhir+xml" ^ +-d @<path/to/example-task.xml> +``` +*This may throw an error depending on which version of cURL Windows is using. If this is the case for you after making sure you entered everything correctly, you can try using Git's version of cURL instead by adding it to the very top of your system's PATH environment variable. Git's cURL is usually situated in C:\Program Files\Git\mingw64\bin.* + +#### Using the DSF FHIR Server's Web Interface + +When visiting the web interface of a DSF FHIR server instance (e.g. https://instance-name/fhir), you can query the DSF FHIR server using the [FHIR RESTful API](https://www.hl7.org/fhir/R4/http.html) to return a list of all [Draft Task Resources](../dsf/draft-task-resources.md). These [Task](../fhir/task.md) resources act like a template you can use to instantiate [Task](../fhir/task.md) resources which start BPMN processes. Instead of querying the DSF FHIR server manually, you can use a predefined bookmark to navigate to the query URL. You can find a list of Bookmarks in the top right corner of the web interface. Simply select the bookmark referencing `?_sort=_profile,identifier&status=draft` under the `Task` section, and you will be taken to the list of all [Draft Task Resources](../dsf/draft-task-resources.md). Once there, you can select the one which starts your BPMN process. It will take you to a detailed view of the resource where you will also have the chance to fill any [Task Input Parameters](../fhir/task.md#task-input-parameters) you might need to specify. If everything is filled out correctly, you may start your process by clicking `Start Process`. Keep in mind that, for [Draft Task Resources](../dsf/draft-task-resources.md) to be available, you need to include them in your mapping for your BPMN process ID in `ProcessPluginDefinition#getFhirResourcesByProcessId`. Take a look at [the Process Plugin Definition](../dsf/process-plugin-definition.md) if you need a reminder. \ No newline at end of file diff --git a/docs/src/develop/index.md b/docs/src/develop/index.md new file mode 100644 index 000000000..2f367396e --- /dev/null +++ b/docs/src/develop/index.md @@ -0,0 +1,4 @@ +--- +title: Developer Documentation +icon: creative +--- \ No newline at end of file diff --git a/docs/src/developer-documentation/concepts/bpmn/gateways.md b/docs/src/developer-documentation/concepts/bpmn/gateways.md deleted file mode 100644 index 5b17a4205..000000000 --- a/docs/src/developer-documentation/concepts/bpmn/gateways.md +++ /dev/null @@ -1,16 +0,0 @@ ---- -title: Gateways -icon: creative ---- - -### Gateways - -[Gateways](https://docs.camunda.org/manual/7.21/reference/bpmn20/gateways/) allow you to control the [Sequence Flow](../../concepts/bpmn/sequence-flow.md). Different types of gateways will be useful for different scenarios. - -#### Exclusive Gateways - -[Exclusive Gateways](https://docs.camunda.org/manual/7.21/reference/bpmn20/gateways/exclusive-gateway/) allow you to decide which [Sequence Flow](../../concepts/bpmn/sequence-flow.md) should be followed based on [conditions](https://docs.camunda.org/manual/7.21/user-guide/process-engine/expression-language/#conditions). [Conditions](https://docs.camunda.org/manual/7.21/user-guide/process-engine/expression-language/#conditions) are not part of the [Exclusive Gateways](https://docs.camunda.org/manual/7.21/reference/bpmn20/gateways/exclusive-gateway/) themselves. You set them through the sequence Flow Exiting the [Exclusive Gateway](https://docs.camunda.org/manual/7.21/reference/bpmn20/gateways/exclusive-gateway/). In the [Camunda Modeler](https://camunda.com/download/modeler/), you can add conditions to [Sequence Flow](../../concepts/bpmn/sequence-flow.md) by selecting a [Sequence Flow](../../concepts/bpmn/sequence-flow.md) and opening the `Condition` tab. You can find more information on how to use Conditions [here](../../concepts/bpmn/conditions.md). - -#### Event-based Gateway - -The [Event-based Gateway](https://docs.camunda.org/manual/7.21/reference/bpmn20/gateways/event-based-gateway/) allows you model scenarios where you are expecting one out of a number of events to occur. \ No newline at end of file diff --git a/docs/src/developer-documentation/concepts/bpmn/intro.md b/docs/src/developer-documentation/concepts/bpmn/intro.md deleted file mode 100644 index aa901e9da..000000000 --- a/docs/src/developer-documentation/concepts/bpmn/intro.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: Introduction -icon: creative ---- - -The DSF uses BPMN 2.0 to model processes. Specifically, the [Camunda 7](https://docs.camunda.org/manual/7.21/) dialect from the [Camunda Modeler](https://camunda.com/de/download/modeler/). Modeling processes for the DSF requires this modeler or any other modeler which is able to produce the correct Camunda dialect. \ No newline at end of file diff --git a/docs/src/developer-documentation/concepts/dsf/about-version-placeholders-and-urls.md b/docs/src/developer-documentation/concepts/dsf/about-version-placeholders-and-urls.md deleted file mode 100644 index 8ca7c542d..000000000 --- a/docs/src/developer-documentation/concepts/dsf/about-version-placeholders-and-urls.md +++ /dev/null @@ -1,38 +0,0 @@ ---- -title: About Versions, Placeholders und URLs -icon: creative ---- - -### About Versions, Placeholders and URLs - -#### Version Pattern - -Process plugin versions have to obey the pattern: -``` -\d+\.\d+\.\d+\.\d+ Example: 1.0.1.2 -``` - -The first two numbers (`1.0`) are used in FHIR resources and signal changes which break compatibility with previous process versions. For example, altering FHIR resources usually results in a breaking change. The latter two (`1.2`) signal changes which do not break compatibility with previous process versions. Specifically, the 4th number is reserved for bug-fixes and the 3rd number includes all other non-breaking changes. - -#### Placeholders - -To avoid the need to specify the version and release date, the placeholders `#{version}` and `#{date}` can be used when creating FHIR resources or even in BPMN models. They are replaced with the values returned by the methods `ProcessPluginDefinition#getResourceVersion` and `ProcessPluginDefinition#getReleaseDate` respectively during deployment of a process plugin by the DSF BPE server. There is also a placeholder for the organization the DSF instance is running in: `#{organization}`. You would typically use this placeholder in [Draft Task Resources](draft-task-resources.md) but like the other placeholders, it can be used anywhere as long as the file gets loaded by the [BPE](https://dsf.dev/intro/info/architecture.html#business-process-engine-bpe). - -#### URLs - -BPMN models have an ID we call process definition key. The BPMN process definition key needs to be specified following the pattern: -``` -^[-a-zA-Z0-9]+_[-a-zA-Z0-9]+$ Example: domainorg_processKey -``` -In addition, the BPMN model needs to specify a version. You should be using the ``#{version}`` [placeholder](../../concepts/dsf/about-version-placeholders-and-urls.md#placeholders) for this as well. The DSF will also reference this process in URL form in FHIR resources: -``` -http://domain.org/bpe/Process/processKey|1.0 -``` - -As you can see, the version in the URL ``|1.0`` only uses the resource version and omits the code base version. As mentioned in [Version Pattern](about-version-placeholders-and-urls.md#version-pattern), this means that only changes to the first two version numbers are significant to signal compatibility when communicating with other process plugin instances. The process definition key and URL are also related to each other. The DSF will try to match BPMN models to FHIR resources by transforming the URL into a process definition key. That is why it is important you obey the pattern above. - -You will use the above URL as your instantiatesCanonical value for [Task](../../concepts/fhir/task.md) profile definitions as well as references to [Task](../../concepts/fhir/task.md) profiles in other resources. You will also use it as the URL value for your [ActivityDefinitions](../../concepts/fhir/activitydefinition.md). In this case though, you have to split up the URL into two parts. You will separate the version (``|1.0``) from the URL and use it as a value for the `ActivityDefinition.version` element. Since it refers to the plugin's resource version, you should also use the `#{version}` [placeholder](about-version-placeholders-and-urls.md#placeholders) here instead. Going by the example from above, you will be left with a URL that looks like this: -``` -http://domain.org/bpe/Process/processKey -``` -This will be the value for your `ActivityDefinition.url` element with `#{version}` as the value for your `ActivityDefinition.version` element. \ No newline at end of file diff --git a/docs/src/developer-documentation/concepts/dsf/bpmn-process-variables.md b/docs/src/developer-documentation/concepts/dsf/bpmn-process-variables.md deleted file mode 100644 index ce456d542..000000000 --- a/docs/src/developer-documentation/concepts/dsf/bpmn-process-variables.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -title: BPMN Process Variables -icon: creative ---- - -### BPMN Process Variables - -BPMN process variables hold additional information which has to be available during BPMN process execution. Variables can be directly related to BPMN elements like the boolean value for [Conditions](../../concepts/bpmn/conditions.md), but do not have to be. BPMN process variables are stored as key-value pairs with the key being the variable name. They are accessible during the entirety of the execution to all [Service](../../concepts/dsf/service-delegates.md) / [Message](../../concepts/dsf/message-delegates.md) Delegates. - -You can learn how to access to the BPMN process variables [here](../../guides/accessing-bpmn-process-variables.md). \ No newline at end of file diff --git a/docs/src/developer-documentation/concepts/dsf/draft-task-resources.md b/docs/src/developer-documentation/concepts/dsf/draft-task-resources.md deleted file mode 100644 index 4f0444422..000000000 --- a/docs/src/developer-documentation/concepts/dsf/draft-task-resources.md +++ /dev/null @@ -1,21 +0,0 @@ ---- -title: Draft Task Resources -icon: creative ---- - -### Draft Task Resources - -[Task](../../concepts/fhir/task.md) resources with status `draft` are used to create the DSF FHIR server's functionality of starting processes via its web interface. They are stored in `.../tutorial-process/src/main/resources/fhir/Task`. Compared to regular [Task](../../concepts/fhir/task.md) resources used to start BPMN processes, this type of [Task](../../concepts/fhir/task.md) resource requires the status `draft` instead the usual `requested`. It also replaces the value for `authoredOn` with the placeholder `#{date}`, the values of organization identifiers with the placeholder `#{organization}` and all instances of version numbers with `#{version}`. Additionally, it requires setting the `Task.identifier` element. It should look something like this: - -```xml -<identifier> - <system value="http://dsf.dev/sid/task-identifier" /> - <value value="http://dsf.dev/bpe/Process/processKey/#{version}/task-name" /> -</identifier> -``` -`processKey` should be the same one used in [URLs](../../concepts/dsf/about-version-placeholders-and-urls.md#urls). -`task-name` can be any String you wish to identify this task with. E.g. you can use the file name of the Draft Task. - -For a complete example you can take a look at the Draft Task Resource in one of the solution branches and compare it to the one needed for cURL. The [Task](../../concepts/fhir/task.md) resource created for cURL can be found at `.../tutorial-process/src/main/resources/example-task.xml`. - -You might also want to check out [this guide](../../guides/creating-task-resources-based-on-a-definition.md) if you do not know how to create [Task](../../concepts/fhir/task.md) resources in general. \ No newline at end of file diff --git a/docs/src/developer-documentation/concepts/dsf/message-delegates.md b/docs/src/developer-documentation/concepts/dsf/message-delegates.md deleted file mode 100644 index a5aada5d0..000000000 --- a/docs/src/developer-documentation/concepts/dsf/message-delegates.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -title: Message Delegates -icon: creative ---- - -### Message Delegates - -Message Delegates are the Java representation of the [Message Events](../../concepts/bpmn/messaging.md) in your BPMN model. You link a Message Delegate to a certain [Message Event](../../concepts/bpmn/messaging.md) by selecting the Message Event in the [Camunda Modeler](https://camunda.com/download/modeler/) and adding a Java class to the `Implementation` field. Make sure you use the fully qualified class name. Like this: -``` -org.package.myClass -``` - -You will only need Message Delegates for [Message Send Events](../../concepts/bpmn/messaging.md). Incoming messages will be resolved to the correct [BPMN process execution](../../concepts/dsf/bpmn-process-execution.md) automatically using [Message Correlation](../../concepts/dsf/message-correlation.md) and the message inputs will be added to that execution's [process variables](../../concepts/dsf/bpmn-process-variables.md). - -To make a Message Delegate for [Message Send Events](../../concepts/bpmn/messaging.md), your Java class needs to extend `AbstractTaskMessageSend`. Most of the time, you will not be adding any processing logic to your Message Delegates, therefore you usually won't be overwriting the `doExecute` method like with [Service Delegates](../../concepts/dsf/service-delegates.md). Instead, you most likely want to aggregate the information you processed in earlier steps and attach it to a message. For this you need to overwrite the `getAdditionalInputParamters` method. The DSF translates BPMN messages into FHIR [Task](../../concepts/fhir/task.md) resources to execute the communication modeled by your BPMN diagrams. The information you are sending to another BPMN process is specified in the Task.input elements a.k.a. [Input Parameters](../../concepts/fhir/task.md#task-input-parameters), hence the name of the method. The constructor of your delegate class should also forward a `ProcessPluginApi` instance to its superclass constructor. You can learn more about the `ProcessPluginApi` [here](../../concepts/dsf/process-api.md). diff --git a/docs/src/developer-documentation/concepts/dsf/process-api.md b/docs/src/developer-documentation/concepts/dsf/process-api.md deleted file mode 100644 index 24774372e..000000000 --- a/docs/src/developer-documentation/concepts/dsf/process-api.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -title: DSF Process API Package -icon: creative ---- - -### DSF Process API Package - -The [DSF Process API package](https://mvnrepository.com/artifact/dev.dsf/dsf-bpe-process-api-v1) consists of a set of utility classes designed to provide easy access to solutions for process plugin use cases. This includes for example the `Variables` class, which provides access to the [BPMN process variables](../../concepts/dsf/bpmn-process-variables.md). - -#### Process Plugin Api -When creating [Service Delegates](../../concepts/dsf/service-delegates.md) or [Message Delegates](../../concepts/dsf/message-delegates.md) you wil notice that you need to provide a constructor which expects a `ProcessPluginApi` object and forward it to the superclasses' constructor. -This API instance provides a variety of utility classes: -- `ProxyConfig`**:** forward proxy configuration -- `EndpointProvider`**:** access to Endpoint resources -- `FhirContext`**:** HAPI FHIR Context for parsing/serializing -- `FhirWebserviceClientProvider`**:** Webservice client to access DSF FHIR server -- `MailService`**:** for sending automatic E-Mails (if configured) -- `OrganizationProvider`**:** access to Organization resources -- `Variables`**:** access to BPMN execution variables \ No newline at end of file diff --git a/docs/src/developer-documentation/concepts/dsf/read-access-tag.md b/docs/src/developer-documentation/concepts/dsf/read-access-tag.md deleted file mode 100644 index 98c947241..000000000 --- a/docs/src/developer-documentation/concepts/dsf/read-access-tag.md +++ /dev/null @@ -1,22 +0,0 @@ ---- -title: Read Access Tag -icon: creative ---- - -### Read Access Tag - -Axiomatically, nobody is allowed to write FHIR resources (except [Task](../../concepts/fhir/task.md)) to the DSF FHIR server unless it is your own organization. By default, the same applies to reading FHIR resources (again except [Task](../../concepts/fhir/task.md)). But since the DSF is often used to offer medical data in form of FHIR resources, you will find yourself wanting other organizations to be allowed to read the resources you are offering. The `Resource.meta.tag` element is used define access rules for all FHIR resources in the DSF, with the exception of [Task](../../concepts/fhir/task.md) resources. We will explain the reason for this exception shortly. For example, allowing read access for all organizations, you would use the following `system` and `code` in your FHIR resource: - -```xml -<meta> - <tag> - <system value="http://dsf.dev/fhir/CodeSystem/read-access-tag" /> - <code value="ALL" /> - </tag> -</meta> -``` -You can find all codes for the Read Access Tag in its [CodeSystem](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/CodeSystem/dsf-read-access-tag-1.0.0.xml). - -The read access rules for [Task](../../concepts/fhir/task.md) resources are defined through the `requester` and `recipient` elements of the [dsf-extension-process-authorization](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-extension-process-authorization-1.0.0.xml) in your plugin's [ActivityDefinitions](../../concepts/fhir/activitydefinition.md). Therefore, no `read-access-tag` is needed. - -It is also possible to restrict read access of FHIR resources to organizations with a specific role in a parent organization or a specific identifier. If you want to find out more, you may look at the [guide on configuring the Read Access Tag](../../guides/configuring-the-read-access-tag.md). diff --git a/docs/src/developer-documentation/concepts/dsf/service-delegates.md b/docs/src/developer-documentation/concepts/dsf/service-delegates.md deleted file mode 100644 index e39c4bd69..000000000 --- a/docs/src/developer-documentation/concepts/dsf/service-delegates.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -title: Service Delegates -icon: creative ---- - -### Service Delegates - -Service Delegates are the Java representation of the [Service Tasks](../../concepts/bpmn/service-tasks.md) in your BPMN model. You link a Service Delegate to a certain [Service Task](../../concepts/bpmn/service-tasks.md) by selecting the [Service Task](../../concepts/bpmn/service-tasks.md) in the [Camunda Modeler](https://camunda.com/download/modeler/) and adding a Java class to the `Implementation` field. Make sure you use the fully qualified class name. Like this: -``` -org.package.myClass -``` -All that is left is for your Java class to extend `AbstractServiceDelegate` and override the `doExecute` method. This is the place where you can put your actual business logic. The method will be called when the [BPMN process execution](../../concepts/dsf/bpmn-process-execution.md) arrives at the [Service Task](../../concepts/bpmn/service-tasks.md) your Service Delegate is linked to. The constructor of your delegate class should also forward a `ProcessPluginApi` instance to its superclass constructor. You can learn more about the `ProcessPluginApi` [here](../../concepts/dsf/process-api.md). \ No newline at end of file diff --git a/docs/src/developer-documentation/concepts/fhir/activitydefinition.md b/docs/src/developer-documentation/concepts/fhir/activitydefinition.md deleted file mode 100644 index 4a5bf5e1b..000000000 --- a/docs/src/developer-documentation/concepts/fhir/activitydefinition.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -title: ActivityDefinition -icon: creative ---- - -### ActivityDefinition - -[ActivityDefinitions](http://hl7.org/fhir/R4/activitydefinition.html) are used by the DSF to advertise which processes are available at any given instance and who is allowed to request and who is allowed to execute a process. The DSF defined elements for this purpose in the [dsf-activity-definition](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-activity-definition-1.0.0.xml) profile. - - -The most important elements in ActivityDefinitions are: -- `message-name` -- `task-profile` -- `requester` -- `recipient` - -The `message-name` element contains the name of the [BPMN message start event](../../concepts/bpmn/messaging.md#message-start-event) or [BPMN message intermediate catching event](../../concepts/bpmn/messaging.md#message-intermediate-catching-event) which expects a [Task](../../concepts/fhir/task.md) resource complying to the profile defined by `task-profile`. - -The `requester` and `recipient` elements define the organisation(s) or person(s) who are allowed to request or receive the message specified by `message-name`. The receiving DSF instance is the one who will execute the process connected to the message. - -You will have to create your own [ActivityDefinitions](../../concepts/fhir/activitydefinition.md) when developing a process plugin. If you are fluent in reading XML FHIR definitions and translating them into XML resources, you can take a look at the DSF's profile for ActivityDefinitions [here](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-activity-definition-1.0.0.xml). ActivityDefinitions also reference other resource definitions. Depending on the resource, you will find them in one of [these folders](https://github.com/datasharingframework/dsf/tree/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir). If you are not as comfortable with these requirements you might want to check out the guide on [creating ActivityDefinitions](../../guides/creating-an-activity-definition.md). - -You can also find examples for all possible `requester` and `recipient` elements [here](../../concepts/dsf/examples-for-requester-and-recipient-elements.md). \ No newline at end of file diff --git a/docs/src/developer-documentation/concepts/fhir/introduction.md b/docs/src/developer-documentation/concepts/fhir/introduction.md deleted file mode 100644 index 19d3e9b23..000000000 --- a/docs/src/developer-documentation/concepts/fhir/introduction.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -title: Introduction -icon: creative ---- - -## FHIR Introduction - -The DSF uses a variety of [FHIR resources](https://dsf.dev/intro/info/basics.html#why-are-we-using-fhir-and-bpmn). The DSF uses XML as the format for FHIR resources. The most important resources for plugin development are [ActivityDefinitions](../../concepts/fhir/activitydefinition.md), [Tasks](../../concepts/fhir/task.md), [CodeSystems](../../concepts/fhir/codesystem.md) and [ValueSets](../../concepts/fhir/valueset.md). There is also a catalogue of DSF-specific FHIR resources including CodeSystems, ValueSets and Extensions. For now, you can find them in the official DSF GitHub repository [here](https://github.com/datasharingframework/dsf/tree/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir). diff --git a/docs/src/developer-documentation/concepts/fhir/valueset.md b/docs/src/developer-documentation/concepts/fhir/valueset.md deleted file mode 100644 index 918ec2ffe..000000000 --- a/docs/src/developer-documentation/concepts/fhir/valueset.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -title: ValueSet -icon: creative ---- - -### ValueSet - -[ValueSets](https://www.hl7.org/fhir/R4/valueset.html) bind codes from [CodeSystems](../../concepts/fhir/codesystem.md) to coded elements like `code`, `Coding` or `CodeableConcept`. - -[ValueSets](https://www.hl7.org/fhir/R4/valueset.html) are mostly needed to use the [Concepts](https://www.hl7.org/fhir/R4/codesystem-definitions.html#CodeSystem.concept) from [CodeSystems](../../concepts/fhir/codesystem.md) in your [Task](../../concepts/fhir/task.md) profiles. \ No newline at end of file diff --git a/docs/src/developer-documentation/guides/accessing-bpmn-process-variables.md b/docs/src/developer-documentation/guides/accessing-bpmn-process-variables.md deleted file mode 100644 index 97e355c9f..000000000 --- a/docs/src/developer-documentation/guides/accessing-bpmn-process-variables.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -title: Accessing BPMN Process Variables -icon: creative ---- - -### Accessing BPMN Process Variables - -After creating a [Service Delegate](../concepts/dsf/service-delegates.md) or [Message Delegate](../concepts/dsf/message-delegates.md), you might want to retrieve data from or store data in the [BPMN process variables](../concepts/dsf/bpmn-process-variables.md).You can achieve this either through the [BPMN process execution](../concepts/dsf/bpmn-process-execution.md) or via the `Variables` class. -*It is very much recommended you use the latter method*. -The `Variables` class provides lots of utility methods to read or write certain types of [BPMN process variables](../concepts/dsf/bpmn-process-variables.md). If for some reason you need to fall back on the [BPMN process execution](../concepts/dsf/bpmn-process-execution.md) to solve your problem, we would like to learn how the current API of the `Variables` class is limiting you. Contact us, and we might turn it into a feature request ([Contribute](https://dsf.dev/stable/contribute)). diff --git a/docs/src/developer-documentation/guides/accessing-task-resources-during-execution.md b/docs/src/developer-documentation/guides/accessing-task-resources-during-execution.md deleted file mode 100644 index 98f3fa352..000000000 --- a/docs/src/developer-documentation/guides/accessing-task-resources-during-execution.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -title: Accessing Task Resources During Execution -icon: creative ---- - -### Accessing Task Resources During Execution - -If you want access to the [Task](../concepts/fhir/task.md) resources in your [Service](../concepts/dsf/service-delegates.md) / [Message](../concepts/dsf/message-delegates.md) Delegates, the `Variables` class will provide methods which return certain kinds of [Task](../concepts/fhir/task.md) resources. The most commonly used ones are the start [Task](../concepts/fhir/task.md), referring to the [Task](../concepts/fhir/task.md) / [Message Start Event](../concepts/bpmn/messaging.md#message-start-event) responsible for starting the process, and the latest [Task](../concepts/fhir/task.md), referring to most recently received [Task](../concepts/fhir/task.md) / Message. -In principle, this is sufficient to access all information in a [Task](../concepts/fhir/task.md) resource, since you have the [Task](../concepts/fhir/task.md) resource's Java object, but very cumbersome. -Instead of navigating the [Task](../concepts/fhir/task.md) resource's element tree, you should first try to use the [ProcessPluginApi's](../concepts/dsf/process-api.md) `TaskHelper` in conjunction with the method above. The `TaskHelper` class offers specific methods related to [Task](../concepts/fhir/task.md) resources. -The most common use case for this is retrieving data from a [Task's](../concepts/fhir/task.md) [Input Parameter](../concepts/fhir/task.md#task-input-parameters) or creating a new [Input Parameter](../concepts/fhir/task.md#task-input-parameters) for a [Message Delegate's](../concepts/dsf/message-delegates.md) `getAdditionalInputParameters` method. When retrieving data from a [Task's](../concepts/fhir/task.md) Input Parameter you first have to get to the [Input Parameter](../concepts/fhir/task.md#task-input-parameters) you are looking to extract data from. You can use one of the `TaskHelper's` getters for [Input Parameters](../concepts/fhir/task.md#task-input-parameters) to find the right one. The methods will try to match the provided [CodeSystem](../concepts/fhir/codesystem.md) and Code to any [Input Parameter](../concepts/fhir/task.md#task-input-parameters) of the provided [Task](../concepts/fhir/task.md) resource. Depending on the method you chose you will for example receive all matches or just the first one. -To create new [Input Parameters](../concepts/fhir/task.md#task-input-parameters) to attach to a [Task](../concepts/fhir/task.md) resource, you may invoke the `TaskHelper#createInput` method. This is most often used when overriding the `getAdditionalInputParamters` method of you [Message Delegate](../concepts/dsf/message-delegates.md). \ No newline at end of file diff --git a/docs/src/developer-documentation/guides/managing-mutiple-incoming-messages-and-missing-messages.md b/docs/src/developer-documentation/guides/managing-mutiple-incoming-messages-and-missing-messages.md deleted file mode 100644 index 5cf1241df..000000000 --- a/docs/src/developer-documentation/guides/managing-mutiple-incoming-messages-and-missing-messages.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -title: Managing Multiple Incoming Messages and Missing Messages -icon: creative ---- - -### Managing Multiple Incoming Messages and Missing Messages - -If an already running process instance is waiting for a message from another organization, the corresponding FHIR [Task](../concepts/fhir/task.md) may never arrive. Either because the other organization decides to never send the message or because some technical problem prohibits the [Task](../concepts/fhir/task.md) resource from being posted to the DSF FHIR server. This would result in stale process instances that never finish. - -At the same time, you might also expect to receive one out of a number of different message types at once. - -In order to solve both problems we can add an [Event Based Gateway](../concepts/bpmn/gateways.md#event-based-gateway) to the process waiting for a response and then either handle a [Task](../concepts/fhir/task.md) resource with the response and finish the process in a success state or trigger a [Timer Intermediate Catching Event](../concepts/bpmn/timer-intermediate-catching-events.md) after a defined wait period and finish the process in an error state. The following BPMN collaboration diagram shows how the process at the first organization would look like if we wanted to react to multiple different messages or missing messages: - -<picture> - <source media="(prefers-color-scheme: dark)" srcset="/photos/developer-documentation/event_based_gateway_inverted.svg"> - <source media="(prefers-color-scheme: light)" srcset="/photos/developer-documentation/event_based_gateway.svg"> - <img alt="BPMN collaboration diagram with an Event Based Gateway" src="/photos/developer-documentation/event_based_gateway.svg"> -</picture> diff --git a/docs/src/developer-documentation/guides/starting-a-process-via-task-resources.md b/docs/src/developer-documentation/guides/starting-a-process-via-task-resources.md deleted file mode 100644 index c16336561..000000000 --- a/docs/src/developer-documentation/guides/starting-a-process-via-task-resources.md +++ /dev/null @@ -1,43 +0,0 @@ ---- -title: Starting a Process via Task Resources -icon: creative ---- - -### Starting a Process via Task Resources - -To start a BPMN process, you need to create new a [Task](../concepts/fhir/task.md) resource in the DSF FHIR server by sending an HTTP request according to the [FHIR RESTful API](https://www.hl7.org/fhir/R4/http.html). Specifically, you need to [create](https://www.hl7.org/fhir/R4/http.html#create) -a resource for the first time. Also, remember that the [Task](../concepts/fhir/task.md) resource you are sending needs to comply to the [Task](../concepts/fhir/task.md) profile of the process you want to start and the [ActivityDefinition's](../concepts/fhir/activitydefinition.md) authorization rules. -There are two major ways of making this HTTP request: -1. Using cURL -2. Using the DSF FHIR server's web interface - -#### Using cURL -In order to use cURL, you will have to create an appropriate [Task](../concepts/fhir/task.md) resource to post to the DSF FHIR server. There already is a file called `example-task.xml` located in `tutorial-process/src/main/resources/fhir`. You can use this as your starting point. You can try to follow [this guide](../guides/creating-task-resources-based-on-a-definition.md), or you can check the solution branches for this file if you need ideas on how to fill it out properly. - -Below are some cURL command skeletons. Replace all <>-Placeholders with appropriate values. Host name depends on the instance you want to address. - -##### Linux: -```shell -curl https://<instance-host-name>/fhir/Task \ ---cacert <path/to/ca-certificate-file.pem> \ ---cert <path/to/client-certificate-file.pem>:password \ ---key <path/to/client-private-key-file.pem> \ --H "Content-Type: application/fhir+xml" \ --H "Accept: application/fhir+xml" \ --d @<path/to/example-task.xml> -``` -##### Windows CMD: -```shell -curl https://<instance-host-name>/fhir/Task ^ ---cacert <path/to/ca-certificate-file.pem> ^ ---cert <path/to/client-certificate-file.pem>:password ^ ---key <path/to/client-private-key-file.pem> ^ --H "Content-Type: application/fhir+xml" ^ --H "Accept: application/fhir+xml" ^ --d @<path/to/example-task.xml> -``` -*This may throw an error depending on which version of cURL Windows is using. If this is the case for you after making sure you entered everything correctly, you can try using Git's version of cURL instead by adding it to the very top of your system's PATH environment variable. Git's cURL is usually situated in C:\Program Files\Git\mingw64\bin.* - -#### Using the DSF FHIR Server's Web Interface - -When visiting the web interface of a DSF FHIR server instance (e.g. https://instance-name/fhir), you can query the DSF FHIR server using the [FHIR RESTful API](https://www.hl7.org/fhir/R4/http.html) to return a list of all [Draft Task Resources](../concepts/dsf/draft-task-resources.md). These [Task](../concepts/fhir/task.md) resources act like a template you can use to instantiate [Task](../concepts/fhir/task.md) resources which start BPMN processes. Instead of querying the DSF FHIR server manually, you can use a predefined bookmark to navigate to the query URL. You can find a list of Bookmarks in the top right corner of the web interface. Simply select the bookmark referencing `?_sort=_profile,identifier&status=draft` under the `Task` section, and you will be taken to the list of all [Draft Task Resources](../concepts/dsf/draft-task-resources.md). Once there, you can select the one which starts your BPMN process. It will take you to a detailed view of the resource where you will also have the chance to fill any [Task Input Parameters](../concepts/fhir/task.md#task-input-parameters) you might need to specify. If everything is filled out correctly, you may start your process by clicking `Start Process`. Keep in mind that, for [Draft Task Resources](../concepts/dsf/draft-task-resources.md) to be available, you need to include them in your mapping for your BPMN process ID in `ProcessPluginDefinition#getFhirResourcesByProcessId`. Take a look at [the Process Plugin Definition](../concepts/dsf/the-process-plugin-definition.md) if you need a reminder. \ No newline at end of file From 817a7abb7fe43ce0e54fa83eefcc6feb955cb913 Mon Sep 17 00:00:00 2001 From: Hauke Hund <hauke.hund@hs-heilbronn.de> Date: Mon, 27 May 2024 16:29:07 +0200 Subject: [PATCH 11/14] added index.md files, renamed some files --- docs/src/.vuepress/theme.ts | 4 +- docs/src/develop/bpmn/index.md | 2 - docs/src/develop/dsf/index.md | 20 +++++++++ docs/src/develop/dsf/read-access-tag.md | 2 +- .../develop/dsf/requester-and-recipient.md | 2 +- docs/src/develop/fhir/activitydefinition.md | 2 +- docs/src/develop/fhir/index.md | 2 - ...tag.md => configuring-read-access-tags.md} | 4 +- ...on.md => creating-activity-definitions.md} | 4 +- docs/src/develop/guides/index.md | 17 +++++++ docs/src/develop/index.md | 45 ++++++++++++++++++- 11 files changed, 90 insertions(+), 14 deletions(-) create mode 100644 docs/src/develop/dsf/index.md rename docs/src/develop/guides/{configuring-the-read-access-tag.md => configuring-read-access-tags.md} (99%) rename docs/src/develop/guides/{creating-an-activity-definition.md => creating-activity-definitions.md} (99%) create mode 100644 docs/src/develop/guides/index.md diff --git a/docs/src/.vuepress/theme.ts b/docs/src/.vuepress/theme.ts index 294952f58..5471478a4 100644 --- a/docs/src/.vuepress/theme.ts +++ b/docs/src/.vuepress/theme.ts @@ -879,14 +879,14 @@ export default hopeTheme({ icon: "creative", prefix: "dsf/", link: "dsf/", - children: ["versions-placeholders-urls.md", "bpmn-process-execution.md", "bpmn-process-variables.md", "draft-task-resources.md", "environment-variables.md", "requester-and-recipient.md", "message-correlation.md", "message-delegates.md", "organization-identifiers.md", "process-plugin-api.md", "read-access-tag.md", "service-delegates.md", "spring-framework-integration.md", "process-plugin-definition.md"], + children: ["bpmn-process-execution.md", "bpmn-process-variables.md", "draft-task-resources.md", "environment-variables.md", "message-correlation.md", "message-delegates.md", "organization-identifiers.md", "process-plugin-api.md", "process-plugin-definition.md", "read-access-tag.md", "requester-and-recipient.md", "service-delegates.md", "spring-framework-integration.md", "versions-placeholders-urls.md"], }, { text: "Guides", icon: "creative", prefix: "guides/", link: "guides/", - children: ["accessing-bpmn-process-variables.md", "accessing-task-resources-during-execution.md", "adding-task-input-parameters-to-task-profiles.md", "configuring-the-read-access-tag.md", "creating-an-activity-definition.md", "creating-codesystems-for-dsf-processes.md", "creating-task-resources-based-on-a-definition.md", "creating-valuesets-for-dsf-processes.md", "managing-mutiple-incoming-messages-and-missing-messages.md", "setting-targets-for-message-events.md", "starting-a-process-via-task-resources.md"] + children: ["accessing-bpmn-process-variables.md", "accessing-task-resources-during-execution.md", "adding-task-input-parameters-to-task-profiles.md", "configuring-read-access-tags.md", "creating-activity-definitions.md", "creating-codesystems-for-dsf-processes.md", "creating-task-resources-based-on-a-definition.md", "creating-valuesets-for-dsf-processes.md", "managing-mutiple-incoming-messages-and-missing-messages.md", "setting-targets-for-message-events.md", "starting-a-process-via-task-resources.md"] }] } ], diff --git a/docs/src/develop/bpmn/index.md b/docs/src/develop/bpmn/index.md index 0a79690de..d74ae074d 100644 --- a/docs/src/develop/bpmn/index.md +++ b/docs/src/develop/bpmn/index.md @@ -4,11 +4,9 @@ icon: creative --- ## Introduction - The DSF uses BPMN 2.0 to model processes. Specifically, the [Camunda 7](https://docs.camunda.org/manual/7.21/) dialect from the [Camunda Modeler](https://camunda.com/de/download/modeler/). Modeling processes for the DSF requires this modeler or any other modeler which is able to produce the correct Camunda dialect. ## Details - - [Conditions](conditions.md) - [Gateways](gateways.md) - [Messaging](messaging.md) diff --git a/docs/src/develop/dsf/index.md b/docs/src/develop/dsf/index.md new file mode 100644 index 000000000..f70d7104e --- /dev/null +++ b/docs/src/develop/dsf/index.md @@ -0,0 +1,20 @@ +--- +title: DSF +icon: creative +--- + +## Details +- [BPMN Process Execution](bpmn-process-execution.md) +- [BPMN Process Variables](bpmn-process-variables.md) +- [Draft Task Resources](draft-task-resources.md) +- [Environment Variables](environment-variables.md) +- [Message Correlation](message-correlation.md) +- [Message Delegates](message-delegates.md) +- [Organization Identifiers](organization-identifiers.md) +- [Process Plugin API](process-plugin-api.md) +- [Process Plugin Definition](process-plugin-definition.md) +- [Read Access Tag](read-access-tag.md) +- [Requester and Recipient](requester-and-recipient.md) +- [Service Delegates](service-delegates.md) +- [Spring Framework Integration](spring-framework-integration.md) +- [Versions, Placeholders and URLs](versions-placeholders-urls.md) \ No newline at end of file diff --git a/docs/src/develop/dsf/read-access-tag.md b/docs/src/develop/dsf/read-access-tag.md index 4a69b6dc5..47a02b2c1 100644 --- a/docs/src/develop/dsf/read-access-tag.md +++ b/docs/src/develop/dsf/read-access-tag.md @@ -19,4 +19,4 @@ You can find all codes for the Read Access Tag in its [CodeSystem](https://githu The read access rules for [Task](../fhir/task.md) resources are defined through the `requester` and `recipient` elements of the [dsf-extension-process-authorization](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-extension-process-authorization-1.0.0.xml) in your plugin's [ActivityDefinitions](../fhir/activitydefinition.md). Therefore, no `read-access-tag` is needed. -It is also possible to restrict read access of FHIR resources to organizations with a specific role in a parent organization or a specific identifier. If you want to find out more, you may look at the [guide on configuring the Read Access Tag](../guides/configuring-the-read-access-tag.md). +It is also possible to restrict read access of FHIR resources to organizations with a specific role in a parent organization or a specific identifier. If you want to find out more, you may look at the [guide on configuring the Read Access Tag](../guides/configuring-read-access-tags.md). diff --git a/docs/src/develop/dsf/requester-and-recipient.md b/docs/src/develop/dsf/requester-and-recipient.md index fbbd79c3b..8407bb318 100644 --- a/docs/src/develop/dsf/requester-and-recipient.md +++ b/docs/src/develop/dsf/requester-and-recipient.md @@ -1,5 +1,5 @@ --- -title: Requester and Recipient Elements +title: Requester and Recipient icon: creative --- diff --git a/docs/src/develop/fhir/activitydefinition.md b/docs/src/develop/fhir/activitydefinition.md index 97e0956a3..5cd27ca91 100644 --- a/docs/src/develop/fhir/activitydefinition.md +++ b/docs/src/develop/fhir/activitydefinition.md @@ -18,6 +18,6 @@ The `message-name` element contains the name of the [BPMN message start event](. The `requester` and `recipient` elements define the organisation(s) or person(s) who are allowed to request or receive the message specified by `message-name`. The receiving DSF instance is the one who will execute the process connected to the message. -You will have to create your own [ActivityDefinitions](activitydefinition.md) when developing a process plugin. If you are fluent in reading XML FHIR definitions and translating them into XML resources, you can take a look at the DSF's profile for ActivityDefinitions [here](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-activity-definition-1.0.0.xml). ActivityDefinitions also reference other resource definitions. Depending on the resource, you will find them in one of [these folders](https://github.com/datasharingframework/dsf/tree/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir). If you are not as comfortable with these requirements you might want to check out the guide on [creating ActivityDefinitions](../guides/creating-an-activity-definition.md). +You will have to create your own [ActivityDefinitions](activitydefinition.md) when developing a process plugin. If you are fluent in reading XML FHIR definitions and translating them into XML resources, you can take a look at the DSF's profile for ActivityDefinitions [here](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-activity-definition-1.0.0.xml). ActivityDefinitions also reference other resource definitions. Depending on the resource, you will find them in one of [these folders](https://github.com/datasharingframework/dsf/tree/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir). If you are not as comfortable with these requirements you might want to check out the guide on [creating ActivityDefinitions](../guides/creating-activity-definitions.md). You can also find examples for all possible `requester` and `recipient` elements [here](../dsf/requester-and-recipient.md). \ No newline at end of file diff --git a/docs/src/develop/fhir/index.md b/docs/src/develop/fhir/index.md index 719581424..47e4a6cda 100644 --- a/docs/src/develop/fhir/index.md +++ b/docs/src/develop/fhir/index.md @@ -4,11 +4,9 @@ icon: creative --- ## Introduction - The DSF uses a variety of [FHIR resources](https://dsf.dev/intro/info/basics.html#why-are-we-using-fhir-and-bpmn). The DSF uses XML as the format for FHIR resources. The most important resources for plugin development are [ActivityDefinitions](activitydefinition.md), [CodeSystems](codesystem.md), [Tasks](task.md) and [ValueSets](valueset.md). There is also a catalog of DSF-specific FHIR resources including CodeSystems, ValueSets and Extensions. For now, you can find them in the official DSF GitHub repository [here](https://github.com/datasharingframework/dsf/tree/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir). ## Details - - [ActivityDefinition](activitydefinition.md) - [CodeSystem](codesystem.md) - [Task](task.md) diff --git a/docs/src/develop/guides/configuring-the-read-access-tag.md b/docs/src/develop/guides/configuring-read-access-tags.md similarity index 99% rename from docs/src/develop/guides/configuring-the-read-access-tag.md rename to docs/src/develop/guides/configuring-read-access-tags.md index 28a0bdf35..404f2286e 100644 --- a/docs/src/develop/guides/configuring-the-read-access-tag.md +++ b/docs/src/develop/guides/configuring-read-access-tags.md @@ -1,9 +1,9 @@ --- -title: Configuring the Read Access Tag +title: Configuring Read Access Tags icon: creative --- -### Configuring the Read Access Tag +### Configuring Read Access Tags To start off, you want to take a look at the [CodeSystem](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/CodeSystem/dsf-read-access-tag-1.0.0.xml) defined for the [Read Access Tag](../dsf/read-access-tag.md) and choose one of the codes from it: ```xml diff --git a/docs/src/develop/guides/creating-an-activity-definition.md b/docs/src/develop/guides/creating-activity-definitions.md similarity index 99% rename from docs/src/develop/guides/creating-an-activity-definition.md rename to docs/src/develop/guides/creating-activity-definitions.md index 5e485da52..40a7cfb2e 100644 --- a/docs/src/develop/guides/creating-an-activity-definition.md +++ b/docs/src/develop/guides/creating-activity-definitions.md @@ -1,9 +1,9 @@ --- -title: Creating an ActivityDefinition +title: Creating ActivityDefinitions icon: creative --- -### Creating an ActivityDefinition +### Creating ActivityDefinitions This guide will teach you how to create an ActivityDefinition based on the [dsf-activity-definition](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-activity-definition-1.0.0.xml) profile for your process plugin. It is divided into steps for each of the main components of ActivityDefinitions: diff --git a/docs/src/develop/guides/index.md b/docs/src/develop/guides/index.md new file mode 100644 index 000000000..2841de106 --- /dev/null +++ b/docs/src/develop/guides/index.md @@ -0,0 +1,17 @@ +--- +title: Guides +icon: creative +--- + +## Details +- [Accessing BPMN Process Variables](accessing-bpmn-process-variables.md) +- [Accessing Task Resources During Execution](accessing-task-resources-during-execution.md) +- [Adding Task Input Parameters to Task Profiles](adding-task-input-parameters-to-task-profiles.md) +- [Configuring Read Access Tags](configuring-read-access-tags.md) +- [Creating ActivityDefinitions](creating-activity-definitions.md) +- [Creating CodeSystems for DSF Processes](creating-codesystems-for-dsf-processes.md) +- [Creating Task Resources Based on a Definition](creating-task-resources-based-on-a-definition.md) +- [Creating ValueSets for DSF Processes](creating-valuesets-for-dsf-processes.md) +- [Managing Multiple Incoming Messages and Missing Messages](managing-mutiple-incoming-messages-and-missing-messages.md) +- [Setting Targets for Message Events](setting-targets-for-message-events.md) +- [Starting a Process via Task Resources](starting-a-process-via-task-resources.md) \ No newline at end of file diff --git a/docs/src/develop/index.md b/docs/src/develop/index.md index 2f367396e..ca799dea6 100644 --- a/docs/src/develop/index.md +++ b/docs/src/develop/index.md @@ -1,4 +1,47 @@ --- title: Developer Documentation icon: creative ---- \ No newline at end of file +--- + +## BPMN +- [Conditions](bpmn/conditions.md) +- [Gateways](bpmn/gateways.md) +- [Messaging](bpmn/messaging.md) +- [Sequence Flow](bpmn/sequence-flow.md) +- [Service Tasks](bpmn/service-tasks.md) +- [Timer Intermediate Catching Events](bpmn/timer-intermediate-catching-events.md) + +## FHIR +- [ActivityDefinition](fhir/activitydefinition.md) +- [Codesystem](fhir/codesystem.md) +- [Task](fhir/task.md) +- [ValueSet](fhir/valueset.md) + +## DSF +- [BPMN Process Execution](dsf/bpmn-process-execution.md) +- [BPMN Process Variables](dsf/bpmn-process-variables.md) +- [Draft Task Resources](dsf/draft-task-resources.md) +- [Environment Variables](dsf/environment-variables.md) +- [Message Correlation](dsf/message-correlation.md) +- [Message Delegates](dsf/message-delegates.md) +- [Organization Identifiers](dsf/organization-identifiers.md) +- [Process Plugin API](dsf/process-plugin-api.md) +- [Process Plugin Definition](dsf/process-plugin-definition.md) +- [Read Access Tag](dsf/read-access-tag.md) +- [Requester and Recipient](dsf/requester-and-recipient.md) +- [Service Delegates](dsf/service-delegates.md) +- [Spring Framework Integration](dsf/spring-framework-integration.md) +- [Versions, Placeholders and URLs](dsf/versions-placeholders-urls.md) + +## Guides +- [Accessing BPMN Process Variables](guides/accessing-bpmn-process-variables.md) +- [Accessing Task Resources During Execution](guides/accessing-task-resources-during-execution.md) +- [Adding Task Input Parameters to Task Profiles](guides/adding-task-input-parameters-to-task-profiles.md) +- [Configuring Read Access Tags](guides/configuring-read-access-tags.md) +- [Creating ActivityDefinitions](guides/creating-activity-definitions.md) +- [Creating CodeSystems for DSF Processes](guides/creating-codesystems-for-dsf-processes.md) +- [Creating Task Resources Based on a Definition](guides/creating-task-resources-based-on-a-definition.md) +- [Creating ValueSets for DSF Processes](guides/creating-valuesets-for-dsf-processes.md) +- [Managing Multiple Incoming Messages and Missing Messages](guides/managing-mutiple-incoming-messages-and-missing-messages.md) +- [Setting Targets for Message Events](guides/setting-targets-for-message-events.md) +- [Starting a Process via Task Resources](guides/starting-a-process-via-task-resources.md) \ No newline at end of file From d3fbf415af12d4212553fb8c8d3557bdbe8e9a30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20B=C3=B6hringer?= <jan.boehringer@hs-heilbronn.de> Date: Wed, 28 May 2025 11:18:25 +0200 Subject: [PATCH 12/14] added api v1 process plugin development doc --- .../api-v1/bpmn/conditions.md | 8 + .../api-v1/bpmn/gateways.md | 16 + .../process-development/api-v1/bpmn/index.md | 15 + .../api-v1/bpmn/messaging.md | 24 + .../api-v1/bpmn/sequence-flow.md | 7 + .../api-v1/bpmn/service-tasks.md | 8 + .../timer-intermediate-catching-events.md | 8 + .../api-v1/bpmn/user-tasks.md | 8 + .../api-v1/dsf/bpmn-process-execution.md | 8 + .../api-v1/dsf/bpmn-process-variables.md | 10 + .../api-v1/dsf/draft-task-resources.md | 21 + .../api-v1/dsf/environment-variables.md | 10 + .../process-development/api-v1/dsf/index.md | 20 + .../api-v1/dsf/message-correlation.md | 10 + .../api-v1/dsf/message-delegates.md | 15 + .../api-v1/dsf/organization-identifiers.md | 10 + .../api-v1/dsf/process-plugin-api.md | 32 + .../api-v1/dsf/process-plugin-definition.md | 16 + .../api-v1/dsf/read-access-tag.md | 22 + .../api-v1/dsf/requester-and-recipient.md | 250 ++++++ .../api-v1/dsf/service-delegates.md | 12 + .../dsf/spring-framework-integration.md | 14 + .../api-v1/dsf/versions-placeholders-urls.md | 38 + .../api-v1/fhir/activitydefinition.md | 23 + .../api-v1/fhir/codesystem.md | 12 + .../process-development/api-v1/fhir/index.md | 13 + .../process-development/api-v1/fhir/task.md | 19 + .../api-v1/fhir/valueset.md | 10 + .../accessing-bpmn-process-variables.md | 10 + ...cessing-task-resources-during-execution.md | 12 + ...-task-input-parameters-to-task-profiles.md | 210 +++++ .../guides/configuring-read-access-tags.md | 415 ++++++++++ .../guides/creating-activity-definitions.md | 750 ++++++++++++++++++ .../creating-codesystems-for-dsf-processes.md | 42 + ...ng-task-resources-based-on-a-definition.md | 231 ++++++ .../creating-valuesets-for-dsf-processes.md | 63 ++ .../api-v1/guides/index.md | 17 + ...-incoming-messages-and-missing-messages.md | 18 + .../setting-targets-for-message-events.md | 14 + .../starting-a-process-via-task-resources.md | 43 + .../api-v1/guides/user-tasks-in-the-dsf.md | 57 ++ docs/src/process-development/api-v1/index.md | 47 ++ 42 files changed, 2588 insertions(+) create mode 100644 docs/src/process-development/api-v1/bpmn/conditions.md create mode 100644 docs/src/process-development/api-v1/bpmn/gateways.md create mode 100644 docs/src/process-development/api-v1/bpmn/index.md create mode 100644 docs/src/process-development/api-v1/bpmn/messaging.md create mode 100644 docs/src/process-development/api-v1/bpmn/sequence-flow.md create mode 100644 docs/src/process-development/api-v1/bpmn/service-tasks.md create mode 100644 docs/src/process-development/api-v1/bpmn/timer-intermediate-catching-events.md create mode 100644 docs/src/process-development/api-v1/bpmn/user-tasks.md create mode 100644 docs/src/process-development/api-v1/dsf/bpmn-process-execution.md create mode 100644 docs/src/process-development/api-v1/dsf/bpmn-process-variables.md create mode 100644 docs/src/process-development/api-v1/dsf/draft-task-resources.md create mode 100644 docs/src/process-development/api-v1/dsf/environment-variables.md create mode 100644 docs/src/process-development/api-v1/dsf/index.md create mode 100644 docs/src/process-development/api-v1/dsf/message-correlation.md create mode 100644 docs/src/process-development/api-v1/dsf/message-delegates.md create mode 100644 docs/src/process-development/api-v1/dsf/organization-identifiers.md create mode 100644 docs/src/process-development/api-v1/dsf/process-plugin-api.md create mode 100644 docs/src/process-development/api-v1/dsf/process-plugin-definition.md create mode 100644 docs/src/process-development/api-v1/dsf/read-access-tag.md create mode 100644 docs/src/process-development/api-v1/dsf/requester-and-recipient.md create mode 100644 docs/src/process-development/api-v1/dsf/service-delegates.md create mode 100644 docs/src/process-development/api-v1/dsf/spring-framework-integration.md create mode 100644 docs/src/process-development/api-v1/dsf/versions-placeholders-urls.md create mode 100644 docs/src/process-development/api-v1/fhir/activitydefinition.md create mode 100644 docs/src/process-development/api-v1/fhir/codesystem.md create mode 100644 docs/src/process-development/api-v1/fhir/index.md create mode 100644 docs/src/process-development/api-v1/fhir/task.md create mode 100644 docs/src/process-development/api-v1/fhir/valueset.md create mode 100644 docs/src/process-development/api-v1/guides/accessing-bpmn-process-variables.md create mode 100644 docs/src/process-development/api-v1/guides/accessing-task-resources-during-execution.md create mode 100644 docs/src/process-development/api-v1/guides/adding-task-input-parameters-to-task-profiles.md create mode 100644 docs/src/process-development/api-v1/guides/configuring-read-access-tags.md create mode 100644 docs/src/process-development/api-v1/guides/creating-activity-definitions.md create mode 100644 docs/src/process-development/api-v1/guides/creating-codesystems-for-dsf-processes.md create mode 100644 docs/src/process-development/api-v1/guides/creating-task-resources-based-on-a-definition.md create mode 100644 docs/src/process-development/api-v1/guides/creating-valuesets-for-dsf-processes.md create mode 100644 docs/src/process-development/api-v1/guides/index.md create mode 100644 docs/src/process-development/api-v1/guides/managing-mutiple-incoming-messages-and-missing-messages.md create mode 100644 docs/src/process-development/api-v1/guides/setting-targets-for-message-events.md create mode 100644 docs/src/process-development/api-v1/guides/starting-a-process-via-task-resources.md create mode 100644 docs/src/process-development/api-v1/guides/user-tasks-in-the-dsf.md create mode 100644 docs/src/process-development/api-v1/index.md diff --git a/docs/src/process-development/api-v1/bpmn/conditions.md b/docs/src/process-development/api-v1/bpmn/conditions.md new file mode 100644 index 000000000..41447df07 --- /dev/null +++ b/docs/src/process-development/api-v1/bpmn/conditions.md @@ -0,0 +1,8 @@ +--- +title: Conditions +icon: creative +--- + +### Conditions + +[Conditions](https://docs.camunda.org/manual/7.21/user-guide/process-engine/expression-language/#conditions) allow you to change the behaviour of BPMN processes during execution. There are two ways you are able to add decision logic to Conditions. The [Camunda Modeler](https://camunda.com/download/modeler/) refers to them as `Type`. You can find them in the ``Condition`` tab of certain BPMN elements. The first one is `Script`. This allows you to add arbitrary complexity to your decisions logic and is rarely used for process plugins. The more common Type is `Expression`. Expressions have the following syntax: `${expression}`. An example of a simple expression would be a boolean condition like `var == true`. For this to work during BPMN process execution, the variable you want to use for the boolean condition must be available in the BPMN process variables before [Sequence Flow](sequence-flow.md) reaches the evaluation of the expression. You can learn more advanced features of Expressions [here](https://docs.camunda.org/manual/7.21/user-guide/process-engine/expression-language/). \ No newline at end of file diff --git a/docs/src/process-development/api-v1/bpmn/gateways.md b/docs/src/process-development/api-v1/bpmn/gateways.md new file mode 100644 index 000000000..630b26ae0 --- /dev/null +++ b/docs/src/process-development/api-v1/bpmn/gateways.md @@ -0,0 +1,16 @@ +--- +title: Gateways +icon: creative +--- + +### Gateways + +[Gateways](https://docs.camunda.org/manual/7.21/reference/bpmn20/gateways/) allow you to control the [Sequence Flow](sequence-flow.md). Different types of gateways are useful for different scenarios. + +#### Exclusive Gateways + +[Exclusive Gateways](https://docs.camunda.org/manual/7.21/reference/bpmn20/gateways/exclusive-gateway/) allow you to decide which [Sequence Flow](sequence-flow.md) should be followed based on [conditions](https://docs.camunda.org/manual/7.21/user-guide/process-engine/expression-language/#conditions). [Conditions](https://docs.camunda.org/manual/7.21/user-guide/process-engine/expression-language/#conditions) are not part of the [Exclusive Gateways](https://docs.camunda.org/manual/7.21/reference/bpmn20/gateways/exclusive-gateway/) themselves. You set them through the sequence flow exiting the [Exclusive Gateway](https://docs.camunda.org/manual/7.21/reference/bpmn20/gateways/exclusive-gateway/). In the [Camunda Modeler](https://camunda.com/download/modeler/), you can add conditions to [Sequence Flow](sequence-flow.md) by selecting a [Sequence Flow](sequence-flow.md) and opening the `Condition` tab. You can find more information on how to use Conditions [here](conditions.md). + +#### Event-based Gateway + +The [Event-based Gateway](https://docs.camunda.org/manual/7.21/reference/bpmn20/gateways/event-based-gateway/) allows you model scenarios where you are expecting one out of a number of events to occur. \ No newline at end of file diff --git a/docs/src/process-development/api-v1/bpmn/index.md b/docs/src/process-development/api-v1/bpmn/index.md new file mode 100644 index 000000000..d74ae074d --- /dev/null +++ b/docs/src/process-development/api-v1/bpmn/index.md @@ -0,0 +1,15 @@ +--- +title: BPMN +icon: creative +--- + +## Introduction +The DSF uses BPMN 2.0 to model processes. Specifically, the [Camunda 7](https://docs.camunda.org/manual/7.21/) dialect from the [Camunda Modeler](https://camunda.com/de/download/modeler/). Modeling processes for the DSF requires this modeler or any other modeler which is able to produce the correct Camunda dialect. + +## Details +- [Conditions](conditions.md) +- [Gateways](gateways.md) +- [Messaging](messaging.md) +- [Sequence Flow](sequence-flow.md) +- [Service Tasks](service-tasks.md) +- [Timer Intermediate Catching Events](timer-intermediate-catching-events.md) \ No newline at end of file diff --git a/docs/src/process-development/api-v1/bpmn/messaging.md b/docs/src/process-development/api-v1/bpmn/messaging.md new file mode 100644 index 000000000..97d05703b --- /dev/null +++ b/docs/src/process-development/api-v1/bpmn/messaging.md @@ -0,0 +1,24 @@ +--- +title: Messaging +icon: creative +--- + + +### Messaging + +In order to enable communication with other lanes, pools or even entirely separate processes you need to be able to exchange information. In BPMN, you can use [Message Events](https://docs.camunda.org/manual/7.21/reference/bpmn20/events/message-events/) to model this information exchange. Modeling communication with [Message Events](https://docs.camunda.org/manual/7.21/reference/bpmn20/events/message-events/) in the same diagram uses Message Flow. Message Flow is typically represented by a dashed line arrow between BPMN elements with a black (send) or white (receive) envelope icon. The following BPMN collaboration diagram shows message exchange between two processes. + +![BPMN collaboration diagram with two processes using message flow to exchange information between two organizations](/photos/developer-documentation/message_flow.svg) + +#### Message Start Event + +[Message Start Events](https://docs.camunda.org/manual/7.21/reference/bpmn20/events/message-events/#message-start-event) allow a BPMN process to be started by an incoming message. In the DSF, all BPMN processes are started via messages. Therefore, you will have to include a [Message Start Event](https://docs.camunda.org/manual/7.21/reference/bpmn20/events/message-events/#message-start-event) at the beginning of all of your BPMN models. + +#### Message Intermediate Throwing Event +[Message Intermediate Throwing Events](https://docs.camunda.org/manual/7.21/reference/bpmn20/events/message-events/#message-intermediate-throwing-event) are used to send messages during process execution. + +#### Message Intermediate Catching Event +[Message Intermediate Catching Events](https://docs.camunda.org/manual/7.21/reference/bpmn20/events/message-events/#message-intermediate-catching-event) serve as the counterpart to [Message Intermediate Throwing Events](messaging.md#message-intermediate-throwing-event). Use them whenever you expect to receive a message from another process or organization during execution. + +#### Message End Event +The [Message End Event](https://docs.camunda.org/manual/7.21/reference/bpmn20/events/message-events/#message-end-event) will stop the execution of a BPMN process and finish by sending a message. \ No newline at end of file diff --git a/docs/src/process-development/api-v1/bpmn/sequence-flow.md b/docs/src/process-development/api-v1/bpmn/sequence-flow.md new file mode 100644 index 000000000..3650cc635 --- /dev/null +++ b/docs/src/process-development/api-v1/bpmn/sequence-flow.md @@ -0,0 +1,7 @@ +--- +title: Sequence Flow +icon: creative +--- + +### Sequence Flow +BPMN 2.0 calls the continuous arrows connecting the BPMN elements in BPMN models, Sequence Flow. Sequence Flow exits one BPMN element and points at the next BPMN element to be processed. diff --git a/docs/src/process-development/api-v1/bpmn/service-tasks.md b/docs/src/process-development/api-v1/bpmn/service-tasks.md new file mode 100644 index 000000000..ebe8ad3c9 --- /dev/null +++ b/docs/src/process-development/api-v1/bpmn/service-tasks.md @@ -0,0 +1,8 @@ +--- +title: Service Tasks +icon: creative +--- + +### Service Tasks + +One of the most common types of BPMN Tasks used for modeling DSF processes is the [Service Task](https://docs.camunda.org/manual/7.21/reference/bpmn20/tasks/service-task/). They are different from regular BPMN Tasks in that they offer the ability to link an implementation to the [Service Task](https://docs.camunda.org/manual/7.21/reference/bpmn20/tasks/service-task/) which can be called and executed by a BPMN engine. The BPE (Business Process Engine) server of the DSF leverages this engine to execute your BPMN processes. \ No newline at end of file diff --git a/docs/src/process-development/api-v1/bpmn/timer-intermediate-catching-events.md b/docs/src/process-development/api-v1/bpmn/timer-intermediate-catching-events.md new file mode 100644 index 000000000..49ab4a8fc --- /dev/null +++ b/docs/src/process-development/api-v1/bpmn/timer-intermediate-catching-events.md @@ -0,0 +1,8 @@ +--- +title: Timer Intermediate Catching Events +icon: creative +--- + +### Timer Intermediate Catching Events + +A [Timer Intermediate Catching Event](https://docs.camunda.org/manual/7.21/reference/bpmn20/events/timer-events/#timer-intermediate-catching-event) allows you to model stopwatch behavior. A timer is started once the BPMN execution arrives at the event. The duration until the timer runs out is specified using the [ISO 8601 Durations](http://en.wikipedia.org/wiki/ISO_8601#Durations) format. Examples can be found [here](https://docs.camunda.org/manual/7.21/reference/bpmn20/events/timer-events/#time-duration). After running out, the BPMN process executes the [Sequence Flow](sequence-flow.md) following the [Timer Intermediate Catching Event](https://docs.camunda.org/manual/7.21/reference/bpmn20/events/timer-events/#timer-intermediate-catching-event). \ No newline at end of file diff --git a/docs/src/process-development/api-v1/bpmn/user-tasks.md b/docs/src/process-development/api-v1/bpmn/user-tasks.md new file mode 100644 index 000000000..8dda98d17 --- /dev/null +++ b/docs/src/process-development/api-v1/bpmn/user-tasks.md @@ -0,0 +1,8 @@ +--- +title: User Tasks +icon: creative +--- + +### User Tasks + +User Tasks define a process step that requires some kind of human interaction. Usually this is done by providing some kind of form the user can fill out. The Camunda Modeler allows to configure these forms as either a propriatary format called [Camunda Forms](https://docs.camunda.io/docs/guides/utilizing-forms/) or custom forms called `Embedded or External Task Forms`. The DSF uses such `External Task Forms` in the form of [Questionnaire](https://www.hl7.org/fhir/R4/questionnaire.html) and [Questionnaire Response](https://www.hl7.org/fhir/R4/questionnaireresponse.html) resources. This mechanism is further expanded upon in [User Tasks in the DSF](../guides/user-tasks-in-the-dsf.md). \ No newline at end of file diff --git a/docs/src/process-development/api-v1/dsf/bpmn-process-execution.md b/docs/src/process-development/api-v1/dsf/bpmn-process-execution.md new file mode 100644 index 000000000..f711532c9 --- /dev/null +++ b/docs/src/process-development/api-v1/dsf/bpmn-process-execution.md @@ -0,0 +1,8 @@ +--- +title: BPMN Process Execution +icon: creative +--- + +### BPMN Process Execution + +The BPMN process execution is the in-memory representation of a running BPMN process. BPMN processes have their executions structured as a tree hierarchy. Each BPMN process starts with the [process instance](https://docs.camunda.org/manual/7.21/user-guide/process-engine/process-engine-concepts/#process-instances) as its root level execution. If, for example, this root execution reaches a parallel gateway with two paths, it would spawn two child executions under itself for them to process all tasks along their paths on their own. Executions can access all the BPMN elements from the BPMN model as well as the [BPMN process variables](bpmn-process-variables.md). You have access to this representation in your Java code through the `execution` parameter when overriding certain methods in [Service](service-delegates.md) / [Message](message-delegates.md) Delegates like `execute` or `getAdditionalInputParameters` through the `variables` parameter. \ No newline at end of file diff --git a/docs/src/process-development/api-v1/dsf/bpmn-process-variables.md b/docs/src/process-development/api-v1/dsf/bpmn-process-variables.md new file mode 100644 index 000000000..6170e1b1e --- /dev/null +++ b/docs/src/process-development/api-v1/dsf/bpmn-process-variables.md @@ -0,0 +1,10 @@ +--- +title: BPMN Process Variables +icon: creative +--- + +### BPMN Process Variables + +BPMN process variables hold additional information which has to be available during BPMN process execution. Variables can be directly related to BPMN elements like the boolean value for [Conditions](../bpmn/conditions.md), but do not have to be. BPMN process variables are stored as key-value pairs with the key being the variable name. They are accessible during the entirety of the execution to all [Service](service-delegates.md) / [Message](message-delegates.md) Delegates. + +You can learn how to access to the BPMN process variables [here](../guides/accessing-bpmn-process-variables.md). \ No newline at end of file diff --git a/docs/src/process-development/api-v1/dsf/draft-task-resources.md b/docs/src/process-development/api-v1/dsf/draft-task-resources.md new file mode 100644 index 000000000..c1bcaa28c --- /dev/null +++ b/docs/src/process-development/api-v1/dsf/draft-task-resources.md @@ -0,0 +1,21 @@ +--- +title: Draft Task Resources +icon: creative +--- + +### Draft Task Resources + +[Task](../fhir/task.md) resources with status `draft` are used to create the DSF FHIR server's functionality of starting processes via its web interface. They are stored in `.../tutorial-process/src/main/resources/fhir/Task`. Compared to regular [Task](../fhir/task.md) resources used to start BPMN processes, this type of [Task](../fhir/task.md) resource requires the status `draft` instead the usual `requested`. It also replaces the value for `authoredOn` with the placeholder `#{date}`, the values of organization identifiers with the placeholder `#{organization}` and all instances of version numbers with `#{version}`. Additionally, it requires setting the `Task.identifier` element. It should look something like this: + +```xml +<identifier> + <system value="http://dsf.dev/sid/task-identifier" /> + <value value="http://dsf.dev/bpe/Process/processKey/#{version}/task-name" /> +</identifier> +``` +`processKey` should be the same one used in [URLs](versions-placeholders-urls.md#urls). +`task-name` can be any String you wish to identify this task with. E.g. you can use the file name of the Draft Task. + +For a complete example you can take a look at the Draft Task Resource in one of the solution branches and compare it to the one needed for cURL. The [Task](../fhir/task.md) resource created for cURL can be found at `.../tutorial-process/src/main/resources/example-task.xml`. + +You might also want to check out [this guide](../guides/creating-task-resources-based-on-a-definition.md) if you do not know how to create [Task](../fhir/task.md) resources in general. \ No newline at end of file diff --git a/docs/src/process-development/api-v1/dsf/environment-variables.md b/docs/src/process-development/api-v1/dsf/environment-variables.md new file mode 100644 index 000000000..fcea6697c --- /dev/null +++ b/docs/src/process-development/api-v1/dsf/environment-variables.md @@ -0,0 +1,10 @@ +--- +title: Environment Variables +icon: creative +--- + +### Environment Variables + +Environment variables offer a way to make configuration data available at the start of a [BPMN process execution](bpmn-process-execution.md). They are the same for all running process instances. They can be defined by adding a member variable with the [Spring-Framework @Value](https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#beans-value-annotations) annotation to the configuration class `TutorialConfig`. The value of the annotation uses the `${..}` notation and follows the form `${some.property:defaultValue}`, where each dot in the property name corresponds to an underscore in the equivalent environment variable. Environment variables are always written upper-case. The property `some.property` therefore corresponds to the environment variable `SOME_PROPERTY`. + +The DSF provides a feature to automatically generate documentation of environment variables during the Maven build process. You can use the `@ProcessDocumentation` annotation to automatically generate Markdown documentation for all fields with this annotation. You simply have to add [dsf-tools-documentation-generator](https://mvnrepository.com/artifact/dev.dsf/dsf-tools-documentation-generator) as a maven plugin. You can take a look at the `pom.xml` for the `tutorial-process` submodule [here](https://github.com/datasharingframework/dsf-process-tutorial/blob/main/tutorial-process/pom.xml) to see how you can add it to your own project. Keep in mind to point the `<workingPackage>` field to the package you want documentation for. \ No newline at end of file diff --git a/docs/src/process-development/api-v1/dsf/index.md b/docs/src/process-development/api-v1/dsf/index.md new file mode 100644 index 000000000..f70d7104e --- /dev/null +++ b/docs/src/process-development/api-v1/dsf/index.md @@ -0,0 +1,20 @@ +--- +title: DSF +icon: creative +--- + +## Details +- [BPMN Process Execution](bpmn-process-execution.md) +- [BPMN Process Variables](bpmn-process-variables.md) +- [Draft Task Resources](draft-task-resources.md) +- [Environment Variables](environment-variables.md) +- [Message Correlation](message-correlation.md) +- [Message Delegates](message-delegates.md) +- [Organization Identifiers](organization-identifiers.md) +- [Process Plugin API](process-plugin-api.md) +- [Process Plugin Definition](process-plugin-definition.md) +- [Read Access Tag](read-access-tag.md) +- [Requester and Recipient](requester-and-recipient.md) +- [Service Delegates](service-delegates.md) +- [Spring Framework Integration](spring-framework-integration.md) +- [Versions, Placeholders and URLs](versions-placeholders-urls.md) \ No newline at end of file diff --git a/docs/src/process-development/api-v1/dsf/message-correlation.md b/docs/src/process-development/api-v1/dsf/message-correlation.md new file mode 100644 index 000000000..23b18e3e3 --- /dev/null +++ b/docs/src/process-development/api-v1/dsf/message-correlation.md @@ -0,0 +1,10 @@ +--- +title: Message Correlation +icon: creative +--- + +### Message Correlation + +In order for messages to be able to be sent back and forth between organizations with potentially multiple of the same process plugin instances running at the same time and still arriving at the correct process instance, we need some mechanism to map messages to their rightful process instance. This mechanism is called Message Correlation and requires attaching a unique identifier to every process instance. This identifier is called the `business-key`. The `business-key` will get attached to every outgoing message automatically. + +It is possible that the `business-key` is insufficient to map messages to the correct process instance. This happens when you use subprocesses in your BPMN model which all expect messages to be sent to them, not the parent process. To solve this issue, [Task](../fhir/task.md) resources also come with an [Input Parameter](../fhir/task.md#task-input-parameters) called `correlation-key`. This is a secondary identifier you can attach to all messages if you need them to arrive at a specific subprocess. You can learn more about how `correlation-keys` are used by studying the [Ping-Pong Process](https://github.com/datasharingframework/dsf-process-ping-pong). \ No newline at end of file diff --git a/docs/src/process-development/api-v1/dsf/message-delegates.md b/docs/src/process-development/api-v1/dsf/message-delegates.md new file mode 100644 index 000000000..61a1a06f1 --- /dev/null +++ b/docs/src/process-development/api-v1/dsf/message-delegates.md @@ -0,0 +1,15 @@ +--- +title: Message Delegates +icon: creative +--- + +### Message Delegates + +Message Delegates are the Java representation of the [Message Events](../bpmn/messaging.md) in your BPMN model. You link a Message Delegate to a certain [Message Event](../bpmn/messaging.md) by selecting the Message Event in the [Camunda Modeler](https://camunda.com/download/modeler/) and adding a Java class to the `Implementation` field. Make sure you use the fully qualified class name. Like this: +``` +org.package.myClass +``` + +You will only need Message Delegates for [Message Send Events](../bpmn/messaging.md). Incoming messages will be resolved to the correct [BPMN process execution](bpmn-process-execution.md) automatically using [Message Correlation](message-correlation.md) and the message inputs will be added to that execution's [process variables](bpmn-process-variables.md). + +To make a Message Delegate for [Message Send Events](../bpmn/messaging.md), your Java class needs to extend `AbstractTaskMessageSend`. Most of the time, you will not be adding any processing logic to your Message Delegates, therefore you usually won't be overwriting the `doExecute` method like with [Service Delegates](service-delegates.md). Instead, you most likely want to aggregate the information you processed in earlier steps and attach it to a message. For this you need to overwrite the `getAdditionalInputParamters` method. The DSF translates BPMN messages into FHIR [Task](../fhir/task.md) resources to execute the communication modeled by your BPMN diagrams. The information you are sending to another BPMN process is specified in the Task.input elements a.k.a. [Input Parameters](../fhir/task.md#task-input-parameters), hence the name of the method. The constructor of your delegate class should also forward a `ProcessPluginApi` instance to its superclass constructor. You can learn more about the `ProcessPluginApi` [here](process-plugin-api.md). diff --git a/docs/src/process-development/api-v1/dsf/organization-identifiers.md b/docs/src/process-development/api-v1/dsf/organization-identifiers.md new file mode 100644 index 000000000..70d143150 --- /dev/null +++ b/docs/src/process-development/api-v1/dsf/organization-identifiers.md @@ -0,0 +1,10 @@ +--- +title: Organization Identifiers +icon: creative +--- + +### Organization Identifiers +DSF FHIR server instances always have something called an `organization identifer`. It uniquely identifies the organization the DSF FHIR server instance belongs to for its [Allow-List mechanism](https://dsf.dev/intro/info/allowList.html). It is configured as an [environment variable](https://dsf.dev/stable/maintain/fhir/configuration.html#dev-dsf-fhir-server-organization-identifier-value). You can make a GET request to `https://domain/fhir/Organization` to get a list of all organizations for the DSF FHIR server instance running under `domain`. The results will also include the `organization identifier` of each organization. + +#### Organization Identifiers in Task Resources +[Task](../fhir/task.md) resources require you to reference an organization via its identifier as the `Task.requester` and `Task.restriction.recipient` elements. The exact values for these elements depend on the [ActivityDefinition](../fhir/activitydefinition.md) the [Task](../fhir/task.md) resource should conform to. As a general rule, you will want to put the identifier of your own organization as the `Task.requester` and `Task.restriction.recipient` elements for [Task](../fhir/task.md) resources which initially start processes. All other cases depend on the context of the message being sent during process execution. \ No newline at end of file diff --git a/docs/src/process-development/api-v1/dsf/process-plugin-api.md b/docs/src/process-development/api-v1/dsf/process-plugin-api.md new file mode 100644 index 000000000..5d1381a5a --- /dev/null +++ b/docs/src/process-development/api-v1/dsf/process-plugin-api.md @@ -0,0 +1,32 @@ +--- +title: Process Plugin API +icon: creative +--- + +### Process Plugin API v1 Maven Module + +The [DSF Process Plugin API module](https://mvnrepository.com/artifact/dev.dsf/dsf-bpe-process-api-v1) consists of a set of utility classes designed to provide easy access to solutions for process plugin use cases. This includes for example the `Variables` class, which provides access to the [BPMN process variables](bpmn-process-variables.md). + +Maven Dependency: + +```xml +<dependencies> + <dependency> + <groupId>dev.dsf</groupId> + <artifactId>dsf-bpe-process-api-v1</artifactId> + <version>${dsf.version}</version> + <scope>provided</scope> + </dependency> +</dependencies> +``` + +#### Process Plugin Api +When creating [Service Delegates](service-delegates.md) or [Message Delegates](message-delegates.md) you wil notice that you need to provide a constructor which expects a `ProcessPluginApi` object and forward it to the superclasses' constructor. +This API instance provides a variety of utility classes: +- `ProxyConfig`**:** forward proxy configuration +- `EndpointProvider`**:** access to Endpoint resources +- `FhirContext`**:** HAPI FHIR Context for parsing/serializing +- `FhirWebserviceClientProvider`**:** Webservice client to access DSF FHIR server +- `MailService`**:** for sending automatic E-Mails (if configured) +- `OrganizationProvider`**:** access to Organization resources +- `Variables`**:** access to BPMN execution variables \ No newline at end of file diff --git a/docs/src/process-development/api-v1/dsf/process-plugin-definition.md b/docs/src/process-development/api-v1/dsf/process-plugin-definition.md new file mode 100644 index 000000000..a13bdbe26 --- /dev/null +++ b/docs/src/process-development/api-v1/dsf/process-plugin-definition.md @@ -0,0 +1,16 @@ +--- +title: Process Plugin Definition +icon: creative +--- + +### Process Plugin Definition + +In order for the DSF BPE server to load your plugin you need to provide it with the following information: +* A plugin [version](versions-placeholders-urls.md#version-pattern) +* A release date +* A plugin name +* The BPMN model files +* The FHIR resources grouped by BPMN process ID. Your plugin may have any number of BPMN models. Each has their own BPMN process ID and FHIR resources specific to that BPMN process (think [Task](../fhir/task.md) resources needed for messages specific to that BPMN model) +* The Class holding your [Spring Framework Configuration](spring-framework-integration.md) + +You will provide this information by implementing the `dev.dsf.bpe.ProcessPluginDefinition` interface. The DSF BPE server then searches for classes implementing this interface using the Java [ServiceLoader](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/ServiceLoader.html) mechanism. Therefore, you will have to register your interface implementation in the `src/main/resources/META-INF/services/dev.dsf.bpe.ProcessPluginDefinition` file. For this tutorial, the class implementing the `ProcessPluginDefinition` interface, `TutorialProcessPluginDefinition`, has already been added to the file. You can use it as a reference for later when you want to create your own plugin. \ No newline at end of file diff --git a/docs/src/process-development/api-v1/dsf/read-access-tag.md b/docs/src/process-development/api-v1/dsf/read-access-tag.md new file mode 100644 index 000000000..47a02b2c1 --- /dev/null +++ b/docs/src/process-development/api-v1/dsf/read-access-tag.md @@ -0,0 +1,22 @@ +--- +title: Read Access Tag +icon: creative +--- + +### Read Access Tag + +Axiomatically, nobody is allowed to write FHIR resources (except [Task](../fhir/task.md)) to the DSF FHIR server unless it is your own organization. By default, the same applies to reading FHIR resources (again except [Task](../fhir/task.md)). But since the DSF is often used to offer medical data in form of FHIR resources, you will find yourself wanting other organizations to be allowed to read the resources you are offering. The `Resource.meta.tag` element is used define access rules for all FHIR resources in the DSF, with the exception of [Task](../fhir/task.md) resources. We will explain the reason for this exception shortly. For example, allowing read access for all organizations, you would use the following `system` and `code` in your FHIR resource: + +```xml +<meta> + <tag> + <system value="http://dsf.dev/fhir/CodeSystem/read-access-tag" /> + <code value="ALL" /> + </tag> +</meta> +``` +You can find all codes for the Read Access Tag in its [CodeSystem](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/CodeSystem/dsf-read-access-tag-1.0.0.xml). + +The read access rules for [Task](../fhir/task.md) resources are defined through the `requester` and `recipient` elements of the [dsf-extension-process-authorization](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-extension-process-authorization-1.0.0.xml) in your plugin's [ActivityDefinitions](../fhir/activitydefinition.md). Therefore, no `read-access-tag` is needed. + +It is also possible to restrict read access of FHIR resources to organizations with a specific role in a parent organization or a specific identifier. If you want to find out more, you may look at the [guide on configuring the Read Access Tag](../guides/configuring-read-access-tags.md). diff --git a/docs/src/process-development/api-v1/dsf/requester-and-recipient.md b/docs/src/process-development/api-v1/dsf/requester-and-recipient.md new file mode 100644 index 000000000..8407bb318 --- /dev/null +++ b/docs/src/process-development/api-v1/dsf/requester-and-recipient.md @@ -0,0 +1,250 @@ +--- +title: Requester and Recipient +icon: creative +--- + +### Requester and Recipient Elements + +Below you will find a set of examples for each Coding used by `requester` and `recipient` elements from the [dsf-extension-process-authorization](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-extension-process-authorization-1.0.0.xml). CodeSystems referenced in the examples can be found [here](https://github.com/datasharingframework/dsf/tree/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/CodeSystem). Use this collection as a reference point when creating your own [ActivityDefinitions](../fhir/activitydefinition.md). + +#### Requester +The `requester` element uses one of the following Codings: +```xml +<profile value="http://dsf.dev/fhir/StructureDefinition/coding-process-authorization-local-all|1.0.0" /> +<profile value="http://dsf.dev/fhir/StructureDefinition/coding-process-authorization-local-all-practitioner|1.0.0" /> +<profile value="http://dsf.dev/fhir/StructureDefinition/coding-process-authorization-local-organization|1.0.0" /> +<profile value="http://dsf.dev/fhir/StructureDefinition/coding-process-authorization-local-organization-practitioner|1.0.0" /> +<profile value="http://dsf.dev/fhir/StructureDefinition/coding-process-authorization-local-parent-organization-role|1.0.0" /> +<profile value="http://dsf.dev/fhir/StructureDefinition/coding-process-authorization-local-parent-organization-role-practitioner|1.0.0" /> +<profile value="http://dsf.dev/fhir/StructureDefinition/coding-process-authorization-remote-all|1.0.0" /> +<profile value="http://dsf.dev/fhir/StructureDefinition/coding-process-authorization-remote-organization|1.0.0" /> +<profile value="http://dsf.dev/fhir/StructureDefinition/coding-process-authorization-remote-parent-organization-role|1.0.0" /> +``` + +##### Local All +```xml +<extension url="requester"> + <valueCoding> + <system value="http://dsf.dev/fhir/CodeSystem/process-authorization" /> + <code value="LOCAL_ALL" /> + </valueCoding> +</extension> +``` + +##### Local All Practitioner +```xml +<extension url="requester"> + <valueCoding> + <extension url="http://dsf.dev/fhir/StructureDefinition/extension-process-authorization-practitioner"> + <valueCoding> + <system value="http://dsf.dev/fhir/CodeSystem/practitioner-role"/> + <code value="DSF_ADMIN"/> <!-- example, replace appropriately --> + </valueCoding> + </extension> + <system value="http://dsf.dev/fhir/CodeSystem/process-authorization" /> + <code value="LOCAL_ALL_PRACTITIONER" /> + </valueCoding> +</extension> +``` + +##### Local Organization +```xml +<extension url="requester"> + <valueCoding> + <extension url="http://dsf.dev/fhir/StructureDefinition/extension-process-authorization-organization"> + <valueIdentifier> + <system value="http://dsf.dev/sid/organization-identifier"/> + <value value="My_Organization"/> <!-- example, replace appropriately --> + </valueIdentifier> + </extension> + <system value="http://dsf.dev/fhir/CodeSystem/process-authorization" /> + <code value="LOCAL_ORGANIZATION" /> + </valueCoding> +</extension> +``` + +##### Local Organization Practitioner +```xml +<extension url="requester"> + <valueCoding> + <extension url="http://dsf.dev/fhir/StructureDefinition/extension-process-authorization-organization-practitioner"> + <extension url="organization"> + <valueIdentifier> + <system value="http://dsf.dev/sid/organization-identifier"/> + <value value="My_Organization"/> <!-- example, replace appropriately --> + </valueIdentifier> + </extension> + <extension url="practitioner-role"> + <valueCoding> + <system value="http://dsf.dev/fhir/CodeSystem/practitioner-role"/> + <code value="DSF_ADMIN"/> <!-- example, replace appropriately --> + </valueCoding> + </extension> + </extension> + <system value="http://dsf.dev/fhir/CodeSystem/process-authorization" /> + <code value="LOCAL_ORGANIZATION_PRACTITIONER" /> + </valueCoding> +</extension> +``` + +##### Local Parent Organization Role +```xml +<extension url="requester"> + <valueCoding> + <extension url="http://dsf.dev/fhir/StructureDefinition/extension-process-authorization-parent-organization-role"> + <extension url="parent-organization"> + <valueIdentifier> + <system value="http://dsf.dev/sid/organization-identifier"/> + <value value="My_Parent_Organization"/> <!-- example, replace appropriately --> + </valueIdentifier> + </extension> + <extension url="organization-role"> + <valueCoding> + <system value="http://dsf.dev/fhir/CodeSystem/organization-role"/> + <code value="DIC"/> <!-- example, replace appropriately --> + </valueCoding> + </extension> + </extension> + <system value="http://dsf.dev/fhir/CodeSystem/process-authorization" /> + <code value="LOCAL_ROLE" /> + </valueCoding> +</extension> +``` + +##### Local Parent Organization Role Practitioner +```xml +<extension url="requester"> + <valueCoding> + <extension url="http://dsf.dev/fhir/StructureDefinition/extension-process-authorization-parent-organization-role-practitioner"> + <extension url="parent-organization"> + <valueIdentifier> + <system value="http://dsf.dev/sid/organization-identifier"/> + <value value="My_Parent_Organization"/> <!-- example, replace appropriately --> + </valueIdentifier> + </extension> + <extension url="organization-role"> + <valueCoding> + <system value="http://dsf.dev/fhir/CodeSystem/organization-role"/> + <code value="DIC"/> <!-- example, replace appropriately --> + </valueCoding> + </extension> + <extension url="practitioner-role"> + <valueCoding> + <system value="http://dsf.dev/fhir/CodeSystem/practitioner-role"/> + <code value="DSF_ADMIN"/> <!-- example, replace appropriately --> + </valueCoding> + </extension> + </extension> + <system value="http://dsf.dev/fhir/CodeSystem/process-authorization" /> + <code value="LOCAL_ROLE_PRACTITIONER" /> + </valueCoding> +</extension> +``` + +##### Remote All +```xml +<extension url="requester"> + <valueCoding> + <system value="http://dsf.dev/fhir/CodeSystem/process-authorization" /> + <code value="REMOTE_ALL" /> + </valueCoding> +</extension> +``` + +##### Remote Organization +```xml +<extension url="requester"> + <valueCoding> + <extension url="http://dsf.dev/fhir/StructureDefinition/extension-process-authorization-organization"> + <valueIdentifier> + <system value="http://dsf.dev/sid/organization-identifier"/> + <value value="My_Organization"/> <!-- example, replace appropriately --> + </valueIdentifier> + </extension> + <system value="http://dsf.dev/fhir/CodeSystem/process-authorization" /> + <code value="REMOTE_ORGANIZATION" /> + </valueCoding> +</extension> +``` + +##### Remote Parent Organization Role +```xml +<extension url="requester"> + <valueCoding> + <extension url="http://dsf.dev/fhir/StructureDefinition/extension-process-authorization-parent-organization-role"> + <extension url="parent-organization"> + <valueIdentifier> + <system value="http://dsf.dev/sid/organization-identifier"/> + <value value="My_Parent_Organization"/> <!-- example, replace appropriately --> + </valueIdentifier> + </extension> + <extension url="organization-role"> + <valueCoding> + <system value="http://dsf.dev/fhir/CodeSystem/organization-role"/> + <code value="DIC"/> <!-- example, replace appropriately --> + </valueCoding> + </extension> + </extension> + <system value="http://dsf.dev/fhir/CodeSystem/process-authorization" /> + <code value="REMOTE_ROLE" /> + </valueCoding> +</extension> +``` + +#### Recipient +The `recipeint` element uses one of the following Codings: +```xml +<profile value="http://dsf.dev/fhir/StructureDefinition/coding-process-authorization-local-all|1.0.0" /> +<profile value="http://dsf.dev/fhir/StructureDefinition/coding-process-authorization-local-organization|1.0.0" /> +<profile value="http://dsf.dev/fhir/StructureDefinition/coding-process-authorization-local-parent-organization-role|1.0.0" /> +``` + +##### Local All +```xml +<extension url="recipient"> + <valueCoding> + <system value="http://dsf.dev/fhir/CodeSystem/process-authorization" /> + <code value="LOCAL_ALL" /> + </valueCoding> +</extension> +``` + +##### Local Organization +```xml +<extension url="recipient"> + <valueCoding> + <extension url="http://dsf.dev/fhir/StructureDefinition/extension-process-authorization-organization"> + <valueIdentifier> + <system value="http://dsf.dev/sid/organization-identifier"/> + <value value="My_Organization"/> <!-- example, replace appropriately --> + </valueIdentifier> + </extension> + <system value="http://dsf.dev/fhir/CodeSystem/process-authorization" /> + <code value="LOCAL_ORGANIZATION" /> + </valueCoding> +</extension> +``` + +##### Local Parent Organization Role +```xml +<extension url="recipient"> + <valueCoding> + <extension url="http://dsf.dev/fhir/StructureDefinition/extension-process-authorization-parent-organization-role"> + <extension url="parent-organization"> + <valueIdentifier> + <system value="http://dsf.dev/sid/organization-identifier"/> + <value value="My_Parent_Organization"/> <!-- example, replace appropriately --> + </valueIdentifier> + </extension> + <extension url="organization-role"> + <valueCoding> + <system value="http://dsf.dev/fhir/CodeSystem/organization-role"/> + <code value="DIC"/> <!-- example, replace appropriately --> + </valueCoding> + </extension> + </extension> + <system value="http://dsf.dev/fhir/CodeSystem/process-authorization" /> + <code value="LOCAL_ROLE" /> + </valueCoding> +</extension> +``` diff --git a/docs/src/process-development/api-v1/dsf/service-delegates.md b/docs/src/process-development/api-v1/dsf/service-delegates.md new file mode 100644 index 000000000..278b51e34 --- /dev/null +++ b/docs/src/process-development/api-v1/dsf/service-delegates.md @@ -0,0 +1,12 @@ +--- +title: Service Delegates +icon: creative +--- + +### Service Delegates + +Service Delegates are the Java representation of the [Service Tasks](../bpmn/service-tasks.md) in your BPMN model. You link a Service Delegate to a certain [Service Task](../bpmn/service-tasks.md) by selecting the [Service Task](../bpmn/service-tasks.md) in the [Camunda Modeler](https://camunda.com/download/modeler/) and adding a Java class to the `Implementation` field. Make sure you use the fully qualified class name. Like this: +``` +org.package.myClass +``` +All that is left is for your Java class to extend `AbstractServiceDelegate` and override the `doExecute` method. This is the place where you can put your actual business logic. The method will be called when the [BPMN process execution](bpmn-process-execution.md) arrives at the [Service Task](../bpmn/service-tasks.md) your Service Delegate is linked to. The constructor of your delegate class should also forward a `ProcessPluginApi` instance to its superclass constructor. You can learn more about the `ProcessPluginApi` [here](process-plugin-api.md). \ No newline at end of file diff --git a/docs/src/process-development/api-v1/dsf/spring-framework-integration.md b/docs/src/process-development/api-v1/dsf/spring-framework-integration.md new file mode 100644 index 000000000..55f96f342 --- /dev/null +++ b/docs/src/process-development/api-v1/dsf/spring-framework-integration.md @@ -0,0 +1,14 @@ +--- +title: Spring Framework Integration +icon: creative +--- + +### Spring Framework Integration + +Since the DSF also employs the use of the [Spring Framework](https://spring.io/projects/spring-framework) you will also have to provide some Spring functionality. When deployed, every process plugin exists in its own [Spring context](https://docs.spring.io/spring-framework/reference/core/beans/introduction.html). To make the process plugin work, you have to provide [Spring Beans](https://docs.spring.io/spring-framework/reference/core/beans/definition.html) with `prototype` [scope](https://docs.spring.io/spring-framework/reference/core/beans/factory-scopes.html) for all classes which either extend or implement the following classes/interfaces (as of version 1.4.0): +- `AbstractTaskMessageSend` +- `AbstractServiceDelegate` +- `DefaultUserTaskListener` +- `ProcessPluginDeploymentStateListener` + +A [Spring-Framework configuration class](https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#beans-java-basic-concepts) located in `spring/config` is expected to provide the Spring Beans. For this tutorial, the `TutorialConfig` class will take this role. If you are unfamiliar with the Spring Framework, you might want to check out the chapter [Java-based Container Configuration](https://docs.spring.io/spring-framework/reference/core/beans/java.html) of the Spring Framework documentation, specifically the topics [Using the @Bean Annotation](https://docs.spring.io/spring-framework/reference/core/beans/java/bean-annotation.html) and [Using the @Configuration Annotation](https://docs.spring.io/spring-framework/reference/core/beans/java/configuration-annotation.html). \ No newline at end of file diff --git a/docs/src/process-development/api-v1/dsf/versions-placeholders-urls.md b/docs/src/process-development/api-v1/dsf/versions-placeholders-urls.md new file mode 100644 index 000000000..0381ec629 --- /dev/null +++ b/docs/src/process-development/api-v1/dsf/versions-placeholders-urls.md @@ -0,0 +1,38 @@ +--- +title: Versions, Placeholders and URLs +icon: creative +--- + +### Versions, Placeholders and URLs + +#### Version Pattern + +Process plugin versions have to obey the pattern: +``` +\d+\.\d+\.\d+\.\d+ Example: 1.2.3.4 +``` + +The first two numbers (`1.2`) are used in FHIR resources and signal changes which break compatibility with previous process versions. For example, altering FHIR resources usually results in a breaking change. The latter two (`3.4`) signal changes which do not break compatibility with previous process versions. Specifically, the 4th number is reserved for bug-fixes and the 3rd number includes all other non-breaking changes. + +#### Placeholders + +To avoid specifying the version and release date in multiple files, the placeholders `#{version}` and `#{date}` can be used within FHIR resources and BPMN models. They are replaced with the values returned by the methods `ProcessPluginDefinition#getResourceVersion` and `ProcessPluginDefinition#getReleaseDate` respectively during deployment of a process plugin by the DSF BPE server. There is also a placeholder for the organization the DSF instance is running in: `#{organization}`, typically use in [Draft Task Resources](draft-task-resources.md). + +#### URLs + +BPMN models have an ID call process definition key. The BPMN process definition key needs to be specified following the pattern: +``` +^[-a-zA-Z0-9]+_[-a-zA-Z0-9]+$ Example: domainorg_processKey +``` +In addition, the BPMN model needs to specify a version. You should be using the ``#{version}`` [placeholder](#placeholders) for this as well. The DSF will also reference this process in URL form in FHIR resources: +``` +http://domain.org/bpe/Process/processKey|1.2 +``` + +As you can see, the version in the URL ``|1.2`` only uses the resource version and omits the code base version. As mentioned in [Version Pattern](#version-pattern), this means that only changes to the first two version numbers are significant to signal compatibility when communicating with other process plugin instances. The process definition key and URL are also related to each other. The DSF will try to match BPMN models to FHIR resources by transforming the URL into a process definition key. That is why it is important you obey the pattern above. + +You will use the above URL as your instantiatesCanonical value for [Task](../fhir/task.md) profile definitions as well as references to [Task](../fhir/task.md) profiles in other resources. You will also use it as the URL value for your [ActivityDefinitions](../fhir/activitydefinition.md). In this case though, you have to split up the URL into two parts. You will separate the version (``|1.2``) from the URL and use it as a value for the `ActivityDefinition.version` element. Since it refers to the plugin's resource version, you should also use the `#{version}` [placeholder](#placeholders) here instead. Going by the example from above, you will be left with a URL that looks like this: +``` +http://domain.org/bpe/Process/processKey +``` +This will be the value for your `ActivityDefinition.url` element with `#{version}` as the value for your `ActivityDefinition.version` element. \ No newline at end of file diff --git a/docs/src/process-development/api-v1/fhir/activitydefinition.md b/docs/src/process-development/api-v1/fhir/activitydefinition.md new file mode 100644 index 000000000..5cd27ca91 --- /dev/null +++ b/docs/src/process-development/api-v1/fhir/activitydefinition.md @@ -0,0 +1,23 @@ +--- +title: ActivityDefinition +icon: creative +--- + +### ActivityDefinition + +[ActivityDefinitions](http://hl7.org/fhir/R4/activitydefinition.html) are used by the DSF to advertise which processes are available at any given instance and who is allowed to request and who is allowed to execute a process. The DSF defined elements for this purpose in the [dsf-activity-definition](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-activity-definition-1.0.0.xml) profile. + + +The most important elements in ActivityDefinitions are: +- `message-name` +- `task-profile` +- `requester` +- `recipient` + +The `message-name` element contains the name of the [BPMN message start event](../bpmn/messaging.md#message-start-event) or [BPMN message intermediate catching event](../bpmn/messaging.md#message-intermediate-catching-event) which expects a [Task](task.md) resource complying to the profile defined by `task-profile`. + +The `requester` and `recipient` elements define the organisation(s) or person(s) who are allowed to request or receive the message specified by `message-name`. The receiving DSF instance is the one who will execute the process connected to the message. + +You will have to create your own [ActivityDefinitions](activitydefinition.md) when developing a process plugin. If you are fluent in reading XML FHIR definitions and translating them into XML resources, you can take a look at the DSF's profile for ActivityDefinitions [here](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-activity-definition-1.0.0.xml). ActivityDefinitions also reference other resource definitions. Depending on the resource, you will find them in one of [these folders](https://github.com/datasharingframework/dsf/tree/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir). If you are not as comfortable with these requirements you might want to check out the guide on [creating ActivityDefinitions](../guides/creating-activity-definitions.md). + +You can also find examples for all possible `requester` and `recipient` elements [here](../dsf/requester-and-recipient.md). \ No newline at end of file diff --git a/docs/src/process-development/api-v1/fhir/codesystem.md b/docs/src/process-development/api-v1/fhir/codesystem.md new file mode 100644 index 000000000..e40a365f2 --- /dev/null +++ b/docs/src/process-development/api-v1/fhir/codesystem.md @@ -0,0 +1,12 @@ +--- +title: CodeSystem +icon: creative +--- + +### CodeSystem + +[CodeSystems](https://www.hl7.org/fhir/R4/codesystem.html) usually represent a set of concepts which can be assigned to a code (think LOINC). If you want to use a Code in a resource, you will usually include them in a [ValueSet](valueset.md). + +Plugin development for the DSF requires the use of [CodeSystems](https://www.hl7.org/fhir/R4/codesystem.html) in two major ways: +1. Using existing [DSF CodeSystems](https://github.com/datasharingframework/dsf/tree/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/CodeSystem) in other FHIR resources like the [dsf-extension-process-authorization](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-extension-process-authorization-1.0.0.xml). +2. Creating your own CodeSystem to add additional [Input Parameters](task.md#task-input-parameters) to your [Task](task.md) profiles. \ No newline at end of file diff --git a/docs/src/process-development/api-v1/fhir/index.md b/docs/src/process-development/api-v1/fhir/index.md new file mode 100644 index 000000000..47e4a6cda --- /dev/null +++ b/docs/src/process-development/api-v1/fhir/index.md @@ -0,0 +1,13 @@ +--- +title: FHIR +icon: creative +--- + +## Introduction +The DSF uses a variety of [FHIR resources](https://dsf.dev/intro/info/basics.html#why-are-we-using-fhir-and-bpmn). The DSF uses XML as the format for FHIR resources. The most important resources for plugin development are [ActivityDefinitions](activitydefinition.md), [CodeSystems](codesystem.md), [Tasks](task.md) and [ValueSets](valueset.md). There is also a catalog of DSF-specific FHIR resources including CodeSystems, ValueSets and Extensions. For now, you can find them in the official DSF GitHub repository [here](https://github.com/datasharingframework/dsf/tree/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir). + +## Details +- [ActivityDefinition](activitydefinition.md) +- [CodeSystem](codesystem.md) +- [Task](task.md) +- [ValueSet](valueset.md) \ No newline at end of file diff --git a/docs/src/process-development/api-v1/fhir/task.md b/docs/src/process-development/api-v1/fhir/task.md new file mode 100644 index 000000000..a647fc46c --- /dev/null +++ b/docs/src/process-development/api-v1/fhir/task.md @@ -0,0 +1,19 @@ +--- +title: Task +icon: creative +--- + +### Task + +The [FHIR Task](https://www.hl7.org/fhir/R4/task.html) resource enables the DSF's distributed communication. Whenever a BPMN process instance communicates with a different process instance, the DSF will create a Task resource based on parameters you set in the BPMN model and during execution. It will then automatically send the Task resource to the recipient to start or continue whatever process the Task resource referred to. All Task resources used in the DSF derive from the [dsf-task-base](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-task-base-1.0.0.xml). This profile includes a splicing for `Task.input` with three additional [Input Parameters](task.md#task-input-parameters): +- `message-name` +- `business-key` +- `correlation-key` + +When creating your own plugin, you will want to create your own profiles based on the [dsf-task-base](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-task-base-1.0.0.xml). + +#### Task Input Parameters + +Task Input Parameters allow you to add additional information to [Task](task.md#task) resources. For example, if your particular data exchange requires additional medical data, you would add a slice to your Task profile in the same way the [dsf-task-base](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-task-base-1.0.0.xml) adds slices to the original [FHIR Task](https://www.hl7.org/fhir/R4/task.html) resource. Notice that this also requires creating a [CodeSystem](codesystem.md) and including it in a [ValueSet](valueset.md) to be able to use it in the Task resource. + +If these instructions are insufficient you can check out the guide on [how to add Task Input Parameters](../guides/adding-task-input-parameters-to-task-profiles.md). \ No newline at end of file diff --git a/docs/src/process-development/api-v1/fhir/valueset.md b/docs/src/process-development/api-v1/fhir/valueset.md new file mode 100644 index 000000000..6be03a3fb --- /dev/null +++ b/docs/src/process-development/api-v1/fhir/valueset.md @@ -0,0 +1,10 @@ +--- +title: ValueSet +icon: creative +--- + +### ValueSet + +[ValueSets](https://www.hl7.org/fhir/R4/valueset.html) bind codes from [CodeSystems](codesystem.md) to coded elements like `code`, `Coding` or `CodeableConcept`. + +[ValueSets](https://www.hl7.org/fhir/R4/valueset.html) are mostly needed to use the [Concepts](https://www.hl7.org/fhir/R4/codesystem-definitions.html#CodeSystem.concept) from [CodeSystems](codesystem.md) in your [Task](task.md) profiles. \ No newline at end of file diff --git a/docs/src/process-development/api-v1/guides/accessing-bpmn-process-variables.md b/docs/src/process-development/api-v1/guides/accessing-bpmn-process-variables.md new file mode 100644 index 000000000..f03bee5d0 --- /dev/null +++ b/docs/src/process-development/api-v1/guides/accessing-bpmn-process-variables.md @@ -0,0 +1,10 @@ +--- +title: Accessing BPMN Process Variables +icon: creative +--- + +### Accessing BPMN Process Variables + +After creating a [Service Delegate](../dsf/service-delegates.md) or [Message Delegate](../dsf/message-delegates.md), you might want to retrieve data from or store data in the [BPMN process variables](../dsf/bpmn-process-variables.md). You can achieve this either through the [BPMN process execution](../dsf/bpmn-process-execution.md) or via the `Variables` class. *It is very much recommended to use the latter method*. + +The `Variables` class provides lots of utility methods to read or write certain types of [BPMN process variables](../dsf/bpmn-process-variables.md). If for some reason you need to fall back on the [BPMN process execution](../dsf/bpmn-process-execution.md) to solve your problem, we would like to learn how the current API of the `Variables` class is limiting you. Contact us, and we might turn it into a feature request ([Contribute](https://dsf.dev/stable/contribute)). diff --git a/docs/src/process-development/api-v1/guides/accessing-task-resources-during-execution.md b/docs/src/process-development/api-v1/guides/accessing-task-resources-during-execution.md new file mode 100644 index 000000000..196e16381 --- /dev/null +++ b/docs/src/process-development/api-v1/guides/accessing-task-resources-during-execution.md @@ -0,0 +1,12 @@ +--- +title: Accessing Task Resources During Execution +icon: creative +--- + +### Accessing Task Resources During Execution + +If you want access to the [Task](../fhir/task.md) resources in your [Service](../dsf/service-delegates.md) / [Message](../dsf/message-delegates.md) Delegates, the `Variables` class will provide methods which return certain kinds of [Task](../fhir/task.md) resources. The most commonly used ones are the start [Task](../fhir/task.md), referring to the [Task](../fhir/task.md) / [Message Start Event](../bpmn/messaging.md#message-start-event) responsible for starting the process, and the latest [Task](../fhir/task.md), referring to most recently received [Task](../fhir/task.md) / Message. +In principle, this is sufficient to access all information in a [Task](../fhir/task.md) resource, since you have the [Task](../fhir/task.md) resource's Java object, but very cumbersome. +Instead of navigating the [Task](../fhir/task.md) resource's element tree, you should first try to use the [ProcessPluginApi's](../dsf/process-plugin-api.md) `TaskHelper` in conjunction with the method above. The `TaskHelper` class offers specific methods related to [Task](../fhir/task.md) resources. +The most common use case for this is retrieving data from a [Task's](../fhir/task.md) [Input Parameter](../fhir/task.md#task-input-parameters) or creating a new [Input Parameter](../fhir/task.md#task-input-parameters) for a [Message Delegate's](../dsf/message-delegates.md) `getAdditionalInputParameters` method. When retrieving data from a [Task's](../fhir/task.md) Input Parameter you first have to get to the [Input Parameter](../fhir/task.md#task-input-parameters) you are looking to extract data from. You can use one of the `TaskHelper's` getters for [Input Parameters](../fhir/task.md#task-input-parameters) to find the right one. The methods will try to match the provided [CodeSystem](../fhir/codesystem.md) and Code to any [Input Parameter](../fhir/task.md#task-input-parameters) of the provided [Task](../fhir/task.md) resource. Depending on the method you chose you will for example receive all matches or just the first one. +To create new [Input Parameters](../fhir/task.md#task-input-parameters) to attach to a [Task](../fhir/task.md) resource, you may invoke the `TaskHelper#createInput` method. This is most often used when overriding the `getAdditionalInputParamters` method of you [Message Delegate](../dsf/message-delegates.md). \ No newline at end of file diff --git a/docs/src/process-development/api-v1/guides/adding-task-input-parameters-to-task-profiles.md b/docs/src/process-development/api-v1/guides/adding-task-input-parameters-to-task-profiles.md new file mode 100644 index 000000000..7a625d5f4 --- /dev/null +++ b/docs/src/process-development/api-v1/guides/adding-task-input-parameters-to-task-profiles.md @@ -0,0 +1,210 @@ +--- +title: Adding Task Input Parameters to Task Profiles +icon: creative +--- + +### Adding Task Input Parameters to Task Profiles + +When adding a new [Input Parameter](../fhir/task.md#task-input-parameters) to a [Task](../fhir/task.md) profile, you are essentially adding a new slice to `Task.input`. [Slicing](https://www.hl7.org/fhir/R4/profiling.html#slicing) is part of [profiling](https://www.hl7.org/fhir/R4/profiling.html) in FHIR. Profiling lets you create your own FHIR definitions based on pre-existing FHIR definitions. A slicing defines constraints on element lists like `Task.input` e.g. by only allowing the elements to be of certain types. +For example, you might have a list of fruits in a `FruitBasket` resource. Constraining that list to only include fruits of type `Apple`, `Banana` and `Orange` would be considered [slicing](https://www.hl7.org/fhir/R4/profiling.html#slicing). +This guide will not cover how slicing works in general, only for the case presented by the DSF FHIR resource context. Our goal will be to add a new [Input Parameter](../fhir/task.md#task-input-parameters) of type `example-input` to the `task-start-dic-process.xml` profile which will be used to submit `integer` values to our `dicProcess`. + +Let us start out by adding a slice to `task-start-dic-process.xml`. Since there is already a slicing defined on `Task.input` by `task-start-dic-process.xml`'s `baseDefinition`, we have to check out this resource first. As a part of the [differential](https://www.hl7.org/fhir/R4/profiling.html#snapshot) statement, slicing also uses [Element Definitions](https://www.hl7.org/fhir/R4/elementdefinition.html). +The slicing for `Task.input` is defined in this part of the `baseDefinition`: +```xml +<element id="Task.input"> + <extension url="http://hl7.org/fhir/StructureDefinition/structuredefinition-explicit-type-name"> + <valueString value="Parameter" /> + </extension> + <path value="Task.input" /> + <slicing> + <discriminator> + <type value="value" /> + <path value="type.coding.system" /> + </discriminator> + <discriminator> + <type value="value" /> + <path value="type.coding.code" /> + </discriminator> + <rules value="openAtEnd" /> + </slicing> + <min value="1" /> +</element> +``` +*The resource can be found [here](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-task-base-1.0.0.xml)* + +We will only need to take a look at the `discrimitator` tag for now. Discriminators define the elements a FHIR processor needs to distinguish slices by. In our case, a processor would look at the values for `type.coding.system` and `type.coding.code` to determine which slice this element belongs to. The discriminator type `value` implies that `type.coding.system` and `type.coding.code` have to be present in all slices and need to have a fixed value. You can learn more about discriminators [here](https://www.hl7.org/fhir/R4/profiling.html#discriminator). + +Let us revisit `task-start-dic-process.xml` and start adding a slice called `example-input` to it: +```xml +<StructureDefinition xmlns="http://hl7.org/fhir"> + ... + <differential> + ... + <element id="Task.input:example-input"> + <path value="Task.input" /> + <sliceName value="example-input" /> + <min value="1" /> + <max value="1" /> + </element> + </differential> +</StructureDefinition> +``` +*Irrelevant elements for this guide are hidden by ... placeholders.* + +We have now defined a slice on `Task.input` with the name and id of `example-input` and cardinality of `1..1`. You might want a different cardinality for your use case. We recommend you also take a look at the documentation for [ElementDefinition.id](https://www.hl7.org/fhir/R4/elementdefinition.html#id) and [ElementDefinition.path](https://www.hl7.org/fhir/R4/elementdefinition.html#path). They explain how to create the proper values for these elements. Cardinality is also part of the [element definition](https://www.hl7.org/fhir/R4/elementdefinition.html) hierarchy (see [ElementDefinition.min](https://www.hl7.org/fhir/R4/elementdefinition-definitions.html#ElementDefinition.min) and [ElementDefinition.max](https://www.hl7.org/fhir/R4/elementdefinition-definitions.html#ElementDefinition.max)). + +Next up, we need to define the binding for `Task.input:example-input.type`. Because `Task.input.type` is a `CodeableConcept` which uses codings from a [ValueSet](../fhir/valueset.md), the [discriminator](https://www.hl7.org/fhir/R4/profiling.html#discriminator) requires us to use `required` as the binding strength: +```xml +<StructureDefinition xmlns="http://hl7.org/fhir"> + ... + <differential> + ... + <element id="Task.input:example-input"> + <path value="Task.input" /> + <sliceName value="example-input" /> + <min value="1" /> + <max value="1" /> + </element> + <element id="Task.input:example-input.type"> + <path value="Task.input.type" /> + <binding> + <strength value="required"/> + <valueSet value="http://dsf.dev/fhir/ValueSet/example" /> + </binding> + </element> + </differential> +</StructureDefinition> +``` +As you can see, we referenced a [ValueSet](../fhir/valueset.md) in this binding. When adding an actual slice for your use case, you will have to reference an existing [ValueSet](../fhir/valueset.md) resource or create a new one. A guide on how to create them can be found [here](../guides/creating-valuesets-for-dsf-processes.md). + +Since the [discriminator](https://www.hl7.org/fhir/R4/profiling.html#discriminator) requires `Task.input.coding.code` and `Task.input.coding.system` to be present, we will make `Task.input.coding` mandatory as well: +```xml +<StructureDefinition xmlns="http://hl7.org/fhir"> + ... + <differential> + ... + <element id="Task.input:example-input"> + <path value="Task.input" /> + <sliceName value="example-input" /> + <min value="1" /> + <max value="1" /> + </element> + <element id="Task.input:example-input.type"> + <path value="Task.input.type" /> + <binding> + <strength value="required"/> + <valueSet value="http://dsf.dev/fhir/ValueSet/example" /> + </binding> + </element> + <element id="Task.input:example-input.type.coding"> + <path value="Task.input.type.coding"/> + <min value="1" /> + </element> + </differential> +</StructureDefinition> +``` + +In the beginning we mentioned how `Task.input.type.coding.system` and `Task.input.type.coding.code` have to use fixed values. Here is how we accomplish this: + +```xml +<StructureDefinition xmlns="http://hl7.org/fhir"> + ... + <differential> + ... + <element id="Task.input:example-input"> + <path value="Task.input" /> + <sliceName value="example-input" /> + <min value="1" /> + <max value="1" /> + </element> + <element id="Task.input:example-input.type"> + <path value="Task.input.type" /> + <binding> + <strength value="required"/> + <valueSet value="http://dsf.dev/fhir/ValueSet/example" /> + </binding> + </element> + <element id="Task.input:example-input.type.coding"> + <path value="Task.input.type.coding"/> + <min value="1" /> + </element> + <element id="Task.input:example-input.type.coding.system"> + <path value="Task.input.type.coding.system"/> + <min value="1"/> + <fixedUri value="http://dsf.dev/fhir/CodeSystem/example"/> + </element> + <element id="Task.input:example-input.type.coding.code"> + <path value="Task.input.type.coding.code"/> + <min value="1"/> + <fixedCode value="example-input" /> + </element> + </differential> +</StructureDefinition> +``` +*Notice that we also made the two elements mandatory because they are required by the discriminator.* + +For the `type.coding.system` element we referenced a [CodeSystem](../fhir/codesystem.md). The `type.coding.code` element uses a code from this [CodeSystem](../fhir/codesystem.md) called `example-input`. This is the mechanism by which you actually "name" your [Input Parameter](../fhir/task.md#task-input-parameters). The `type.coding.code` value will identify your [Input Parameter](../fhir/task.md#task-input-parameters) when you use it in an actual [Task](../fhir/task.md#task-input-parameters) resource. Here is how this would look like: + +```xml +<Task xmlns="http://hl7.org/fhir"> + ... + <input> + <type> + <coding> + <system value="http://dsf.dev/fhir/CodeSystem/example"/> + <code value="example-input" /> + </coding> + </type> + ... + </input> +</Task> +``` + +When adding an actual slice for your use case, you will also need to reference an existing [CodeSystem](../fhir/codesystem.md) resource or create a new one to reference. A guide on how to create them can be found [here](../guides/creating-codesystems-for-dsf-processes.md). + +`Task.input.value[x]` is the actual value you will submit using your Input Parameter. You can make it any of [these](https://www.hl7.org/fhir/R4/datatypes.html#open) data types. This is because `Type.input.value[x]` refers to `*` instead of any particular type in its [definition](https://www.hl7.org/fhir/R4/task-definitions.html#Task.input.value_x_). Let us define it as an `integer` type`: + +```xml +<StructureDefinition xmlns="http://hl7.org/fhir"> + ... + <differential> + ... + <element id="Task.input:example-input"> + <path value="Task.input" /> + <sliceName value="example-input" /> + <min value="1" /> + <max value="1" /> + </element> + <element id="Task.input:example-input.type"> + <path value="Task.input.type" /> + <binding> + <strength value="required"/> + <valueSet value="http://dsf.dev/fhir/ValueSet/example" /> + </binding> + </element> + <element id="Task.input:example-input.type.coding"> + <path value="Task.input.type.coding"/> + <min value="1" /> + </element> + <element id="Task.input:example-input.type.coding.system"> + <path value="Task.input.type.coding.system"/> + <min value="1"/> + <fixedUri value="http://dsf.dev/fhir/CodeSystem/example"/> + </element> + <element id="Task.input:example-input.type.coding.code"> + <path value="Task.input.type.coding.code"/> + <min value="1"/> + <fixedCode value="example-input" /> + </element> + <element id="Task.input:example-input.value[x]"> + <path value="Task.input.value[x]"/> + <type> + <code value="integer"/> + </type> + </element> + </differential> +</StructureDefinition> +``` + +Now we have a new Input Parameter of type `example-input` which accepts any `integer` as its value. diff --git a/docs/src/process-development/api-v1/guides/configuring-read-access-tags.md b/docs/src/process-development/api-v1/guides/configuring-read-access-tags.md new file mode 100644 index 000000000..404f2286e --- /dev/null +++ b/docs/src/process-development/api-v1/guides/configuring-read-access-tags.md @@ -0,0 +1,415 @@ +--- +title: Configuring Read Access Tags +icon: creative +--- + +### Configuring Read Access Tags + +To start off, you want to take a look at the [CodeSystem](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/CodeSystem/dsf-read-access-tag-1.0.0.xml) defined for the [Read Access Tag](../dsf/read-access-tag.md) and choose one of the codes from it: +```xml +<CodeSystem xmlns="http://hl7.org/fhir"> + ... + <url value="http://dsf.dev/fhir/CodeSystem/read-access-tag"/> + ... + <concept> + <code value="LOCAL"/> + <display value="Local"/> + <definition value="Read access for local users"/> + </concept> + <concept> + <code value="ORGANIZATION"/> + <display value="Organization"/> + <definition value="Read access for organization specified via extension http://dsf.dev/fhir/StructureDefinition/extension-read-access-organization"/> + </concept> + <concept> + <code value="ROLE"/> + <display value="Role"/> + <definition value="Read access for member organizations with role in consortium (parent organization) specified via extension http://dsf.dev/fhir/StructureDefinition/extension-read-access-consortium-role"/> + </concept> + <concept> + <code value="ALL"/> + <display value="All"/> + <definition value="Read access for remote and local users"/> + </concept> +</CodeSystem> +``` + +The codes `LOCAL` and `ALL` are trivial. Their [Read Access Tag](../dsf/read-access-tag.md) would look like this: +```xml +<meta> + <tag> + <system value="http://dsf.dev/fhir/CodeSystem/read-access-tag"/> + <code value="ALL"/> <!-- or value="LOCAL" respectively--> + </tag> +</meta> +``` + +Let us try to configure a Read Access Tag whose code uses an extension. We will choose `ROLE` for this example. We start out the same way as before: +```xml +<meta> + <tag> + <system value="http://dsf.dev/fhir/CodeSystem/read-access-tag"/> + <code value="ROLE"/> + </tag> +</meta> +``` + +The `definition` element of the `ROLE` code references an extension called [dsf-extension-read-access-parent-organization-role](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-extension-read-access-parent-organization-role-1.0.0.xml). + +The most important part of it is the `differential` statement. It uses [element definitions](https://www.hl7.org/fhir/R4/elementdefinition.html) to describe how we need to implement the extension: +```xml +<StructureDefinition xmlns="http://hl7.org/fhir"> + ... + <differential> + <element id="Extension.extension"> + <path value="Extension.extension" /> + <slicing> + <discriminator> + <type value="value" /> + <path value="url" /> + </discriminator> + <rules value="open" /> + </slicing> + </element> + <element id="Extension.extension:parentOrganization"> + <path value="Extension.extension" /> + <sliceName value="parentOrganization" /> + <min value="1" /> + <max value="1" /> + </element> + <element id="Extension.extension:parentOrganization.url"> + <path value="Extension.extension.url" /> + <fixedUri value="parent-organization" /> + </element> + <element id="Extension.extension:parentOrganization.value[x]"> + <path value="Extension.extension.value[x]" /> + <min value="1" /> + <type> + <code value="Identifier" /> + </type> + </element> + <element id="Extension.extension:parentOrganization.value[x].system"> + <path value="Extension.extension.value[x].system" /> + <min value="1" /> + <fixedUri value="http://dsf.dev/sid/organization-identifier" /> + </element> + <element id="Extension.extension:parentOrganization.value[x].value"> + <path value="Extension.extension.value[x].value" /> + <min value="1" /> + </element> + <element id="Extension.extension:organizationRole"> + <path value="Extension.extension" /> + <sliceName value="organizationRole" /> + <min value="1" /> + <max value="1" /> + </element> + <element id="Extension.extension:organizationRole.url"> + <path value="Extension.extension.url" /> + <fixedUri value="organization-role" /> + </element> + <element id="Extension.extension:organizationRole.value[x]"> + <path value="Extension.extension.value[x]" /> + <min value="1" /> + <type> + <code value="Coding" /> + </type> + </element> + <element id="Extension.extension:organizationRole.value[x].system"> + <path value="Extension.extension.value[x].system" /> + <min value="1" /> + </element> + <element id="Extension.extension:organizationRole.value[x].code"> + <path value="Extension.extension.value[x].code" /> + <min value="1" /> + </element> + <element id="Extension.url"> + <path value="Extension.url" /> + <fixedUri value="http://dsf.dev/fhir/StructureDefinition/extension-read-access-parent-organization-role" /> + </element> + <element id="Extension.value[x]"> + <path value="Extension.value[x]" /> + <max value="0" /> + </element> + </differential> +</StructureDefinition> +``` + +All extensions for the [Read Access Tag](../dsf/read-access-tag.md) CodeSystem are defined on the `meta.tag.extension` element through the extension's `context` element: +```xml +<context> + <type value="element" /> + <expression value="Coding" /> <!-- meta.tag is of type Coding--> +</context> +``` + +That is why the first element we are adding to `meta.tag` is an `extension` element: +```xml +<meta> + <tag> + <extenion> + + </extenion> + <system value="http://dsf.dev/fhir/CodeSystem/read-access-tag"/> + <code value="ROLE"/> + </tag> +</meta> +``` + +We will now go through the `differential` statement one element at a time, starting at the top: +```xml +<StructureDefinition xmlns="http://hl7.org/fhir"> + ... + <differential> + <element id="Extension.extension"> + <path value="Extension.extension" /> + <slicing> + <discriminator> + <type value="value" /> + <path value="url" /> + </discriminator> + <rules value="open" /> + </slicing> + </element> + ... + </differential> +</StructureDefinition> +``` + +It defines a [slicing](https://www.hl7.org/fhir/R4/profiling.html#slicing) for the `Extension.extension` element, meaning we are dealing with a nested extension. The `discriminator` element tells us that slices will be identified by the value of their `url` attribute. A `rules` element with value `open` means other types of slices may be added later on e.g. when creating a profile. We do not have to add any elements from here to the `meta.tag.extension` element. Next up is the first slice called `parentOrganization`: + +```xml +<StructureDefinition xmlns="http://hl7.org/fhir"> + ... + <differential> + ... + <element id="Extension.extension:parentOrganization"> + <path value="Extension.extension" /> + <sliceName value="parentOrganization" /> + <min value="1" /> + <max value="1" /> + </element> + <element id="Extension.extension:parentOrganization.url"> + <path value="Extension.extension.url" /> + <fixedUri value="parent-organization" /> + </element> + <element id="Extension.extension:parentOrganization.value[x]"> + <path value="Extension.extension.value[x]" /> + <min value="1" /> + <type> + <code value="Identifier" /> + </type> + </element> + <element id="Extension.extension:parentOrganization.value[x].system"> + <path value="Extension.extension.value[x].system" /> + <min value="1" /> + <fixedUri value="http://dsf.dev/sid/organization-identifier" /> + </element> + <element id="Extension.extension:parentOrganization.value[x].value"> + <path value="Extension.extension.value[x].value" /> + <min value="1" /> + </element> + ... + </differential> +</StructureDefinition> +``` + +The first element defines a slice called `parentOrganization` on the `Extension.extension` element with cardinality `1..1`. The second element defines the url attribute of the `parentOrganization` slice to be fixed to the value `parent-organization`. With this information we can add the next element to `meta.tag`. Since it is defined on `Extension.extension` we will add it to `meta.tag.extension.extension` like this: +```xml +<meta> + <tag> + <extension> + <extension url="parent-organization"> + + </extension> + </extension> + <system value="http://dsf.dev/fhir/CodeSystem/read-access-tag"/> + <code value="ROLE"/> + </tag> +</meta> +``` + +After that, it defines `parentOrganization.value[x]` to occur at least once and have a type of `Identifier`. To turn this into an element to add to `meta.tag.extension.extension` we have to replace `[x]` with our code in `value[x].type`, which in this case is `Identifier`. It is important to note, that should the value in the code element be lowercase, you will have make it uppercase before replacement. In our case this means we will have a `meta.tag.extension.extension.valueIdentifier` element: +```xml +<meta> + <tag> + <extension> + <extension url="parent-organization"> + <valueIdentifier> + + </valueIdentifier> + </extension> + </extension> + <system value="http://dsf.dev/fhir/CodeSystem/read-access-tag"/> + <code value="ROLE"/> + </tag> +</meta> +``` + +The last two elements define a `system` element with a fixed value and `value` element we can fill in on our own, since it does not have any constraints applied. Notice that the element definition still uses `value[x].system` and `value[x].value`. The replacement mentioned earlier does not happen in the element definition, but since `value[x]` is defined to have the type `Identifier` it is inferred that we mean to reference `Identifier.system` and `Identifier.value`. We will choose an arbitrary `Idenfier` value, but you should be using an actual organization identifier depending on who you want to allow read access to the resource. + +```xml +<meta> + <tag> + <extension> + <extension url="parent-organization"> + <valueIdentifier> + <system value="http://dsf.dev/sid/organization-identifier"/> + <value value="My_Organization"/> + </valueIdentifier> + </extension> + </extension> + <system value="http://dsf.dev/fhir/CodeSystem/read-access-tag"/> + <code value="ROLE"/> + </tag> +</meta> +``` + +Next is the slice is called `organizationRole`: +```xml +<StructureDefinition xmlns="http://hl7.org/fhir"> + ... + <differential> + ... + <element id="Extension.extension:organizationRole"> + <path value="Extension.extension" /> + <sliceName value="organizationRole" /> + <min value="1" /> + <max value="1" /> + </element> + <element id="Extension.extension:organizationRole.url"> + <path value="Extension.extension.url" /> + <fixedUri value="organization-role" /> + </element> + <element id="Extension.extension:organizationRole.value[x]"> + <path value="Extension.extension.value[x]" /> + <min value="1" /> + <type> + <code value="Coding" /> + </type> + </element> + <element id="Extension.extension:organizationRole.value[x].system"> + <path value="Extension.extension.value[x].system" /> + <min value="1" /> + </element> + <element id="Extension.extension:organizationRole.value[x].code"> + <path value="Extension.extension.value[x].code" /> + <min value="1" /> + </element> + ... + </differential> +</StructureDefinition> +``` + +Like with `parentOrganization`, we will add an extension element to `meta.tag.extension` with the fixed url value defined above: +```xml +<meta> + <tag> + <extension> + <extension url="parent-organization"> + <valueIdentifier> + <system value="http://dsf.dev/sid/organization-identifier"/> + <value value="My_Organization"/> + </valueIdentifier> + </extension> + <extension url="organization-role"> + + </extension> + </extension> + <system value="http://dsf.dev/fhir/CodeSystem/read-access-tag"/> + <code value="ROLE"/> + </tag> +</meta> +``` + +Instead of `Identifier`, the `value[x]` element is now defined as a `Coding` type. This means we will add a `valueCoding` element to the extension: +```xml +<meta> + <tag> + <extension> + <extension url="parent-organization"> + <valueIdentifier> + <system value="http://dsf.dev/sid/organization-identifier"/> + <value value="My_Organization"/> + </valueIdentifier> + </extension> + <extension url="organization-role"> + <valueCoding> + + </valueCoding> + </extension> + </extension> + <system value="http://dsf.dev/fhir/CodeSystem/read-access-tag"/> + <code value="ROLE"/> + </tag> +</meta> +``` + +A `Coding` has to belong to some [CodeSystem](../fhir/codesystem.md). The DSF has a CodeSystem called [dsf-organization-role](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/CodeSystem/dsf-organization-role-1.0.0.xml). Before creating your own CodeSystem, it is worth taking a look at it to see if an appropriate role already exists for your organization. For demonstration purposes, we will be using the `DIC` role: +```xml +<meta> + <tag> + <extension> + <extension url="parent-organization"> + <valueIdentifier> + <system value="http://dsf.dev/sid/organization-identifier"/> + <value value="My_Organization"/> + </valueIdentifier> + </extension> + <extension url="organization-role"> + <valueCoding> + <system value="http://dsf.dev/fhir/CodeSystem/organization-role"/> + <code value="DIC"/> + </valueCoding> + </extension> + </extension> + <system value="http://dsf.dev/fhir/CodeSystem/read-access-tag"/> + <code value="ROLE"/> + </tag> +</meta> +``` + +Now we only have two elements left in the `differential` statement: + +```xml +<StructureDefinition xmlns="http://hl7.org/fhir"> + ... + <differential> + ... + <element id="Extension.url"> + <path value="Extension.url" /> + <fixedUri value="http://dsf.dev/fhir/StructureDefinition/extension-read-access-parent-organization-role" /> + </element> + <element id="Extension.value[x]"> + <path value="Extension.value[x]" /> + <max value="0" /> + </element> + </differential> +</StructureDefinition> +``` + +The `Extension.url` element tells us to add a url attribute to `meta.tag.extension`. The last element makes it so we must not add a `meta.tag.extension.value[x]` element. This leaves us with this final Read Access Tag: + +```xml +<meta> + <tag> + <extension url="http://dsf.dev/fhir/StructureDefinition/extension-read-access-parent-organization-role"> + <extension url="parent-organization"> + <valueIdentifier> + <system value="http://dsf.dev/sid/organization-identifier"/> + <value value="My_Organization"/> + </valueIdentifier> + </extension> + <extension url="organization-role"> + <valueCoding> + <system value="http://dsf.dev/fhir/CodeSystem/organization-role"/> + <code value="DIC"/> + </valueCoding> + </extension> + </extension> + <system value="http://dsf.dev/fhir/CodeSystem/read-access-tag"/> + <code value="ROLE"/> + </tag> +</meta> +``` + +You can follow the same method to configure the other types of Read Access Tags as well. \ No newline at end of file diff --git a/docs/src/process-development/api-v1/guides/creating-activity-definitions.md b/docs/src/process-development/api-v1/guides/creating-activity-definitions.md new file mode 100644 index 000000000..40a7cfb2e --- /dev/null +++ b/docs/src/process-development/api-v1/guides/creating-activity-definitions.md @@ -0,0 +1,750 @@ +--- +title: Creating ActivityDefinitions +icon: creative +--- + +### Creating ActivityDefinitions + +This guide will teach you how to create an ActivityDefinition based on the [dsf-activity-definition](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-activity-definition-1.0.0.xml) profile for your process plugin. +It is divided into steps for each of the main components of ActivityDefinitions: +1. Read Access Tag +2. Extension: process authorization +3. BPE Managed Elements +4. Regular Elements + +*Regular elements* are all elements not part of the first 3 main components. + +*We will assume you know how to translate [ElementDefinitions](https://www.hl7.org/fhir/R4/elementdefinition.html) to actual elements in a FHIR resource. If you do not, you might want to check out the guide on [creating Task resources](../guides/creating-task-resources-based-on-a-definition.md) first.* + +#### 1. Read Access Tag +Let us start out with an empty [ActivityDefinition](../fhir/activitydefinition.md): +```xml +<ActivityDefinition xmlns="http://hl7.org/fhir"> + +</ActivityDefinition> +``` + +The first element in DSF FHIR resources is always the [Read Access Tag](../dsf/read-access-tag.md). It describes who is allowed to read this resource through the DSF FHIR server's REST API. You can learn more complex configurations of the [Read Access Tag](../dsf/read-access-tag.md) in [this guide](../dsf/read-access-tag.md). In this case, we will allow read access to everyone: + +```xml +<ActivityDefinition xmlns="http://hl7.org/fhir"> + <meta> + <tag> + <system value="http://dsf.dev/fhir/CodeSystem/read-access-tag" /> + <code value="ALL" /> + </tag> + </meta> +</ActivityDefinition> +``` + +#### 2. Extension: Process Authorization +This part of your ActivityDefinition will tell the DSF who is allowed to request and receive messages ([Task](../fhir/task.md) resources) for your BPMN process. If your plugin contains more than one BPMN process, you will have to create one [ActivityDefinition](../fhir/activitydefinition.md) for each BPMN process. It is important to note that you need to include authorization rules for **ALL** messages received in your BPMN process. This includes the message starting your BPMN process initially. You can find the extension [here](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-extension-process-authorization-1.0.0.xml). Let us continue by adding the [extension element](http://hl7.org/fhir/R4/extensibility.html#extension) with the correct URL. You can get the value for the URL from the `Extension.url` element: +```xml +<ActivityDefinition xmlns="http://hl7.org/fhir"> + ... + <extension url="http://dsf.dev/fhir/StructureDefinition/extension-process-authorization"> + + </extension> +</ActivityDefinition> +``` +*Elements not relevant to the current component are hidden with ... to increase readability.* + +The [differential](https://www.hl7.org/fhir/R4/profiling.html#snapshot) statement starts by defining the [slicing](https://www.hl7.org/fhir/R4/profiling.html#snapshot) for the `Extension.extension` element: + +```xml +<StructureDefinition xmlns="http://hl7.org/fhir"> + ... + <differential> + <element id="Extension"> + <path value="Extension" /> + <min value="1" /> + </element> + <element id="Extension.extension"> + <path value="Extension.extension" /> + <slicing> + <discriminator> + <type value="value" /> + <path value="url" /> + </discriminator> + <rules value="open" /> + </slicing> + </element> + ... + </differential> +</StructureDefinition> +``` + +The above states that whenever this extension is used in a profile, the profile needs to include this extension at least once (`<min value="1" />`). The [slicing](https://www.hl7.org/fhir/R4/profiling.html#snapshot) on `Extension.extension` tells us that elements of this [slicing](https://www.hl7.org/fhir/R4/profiling.html#snapshot) are identified by the value of their URL (`<discriminator>`), which is always the case for extensions, and that other extensions can be added to the [slicing](https://www.hl7.org/fhir/R4/profiling.html#snapshot) (`<rules value="open" />`). Since there is a [slicing](https://www.hl7.org/fhir/R4/profiling.html#snapshot) on `Extension.extension`, we are dealing with a nested extension. + +After these initial element definitions come the elements relevant for your process plugin. The first one is the `message-name` slice: +```xml +<StructureDefinition xmlns="http://hl7.org/fhir"> + ... + <differential> + ... + <element id="Extension.extension:message-name"> + <path value="Extension.extension" /> + <sliceName value="message-name" /> + <min value="1" /> + <max value="1" /> + </element> + <element id="Extension.extension:message-name.url"> + <path value="Extension.extension.url" /> + <fixedUri value="message-name" /> + </element> + <element id="Extension.extension:message-name.value[x]"> + <path value="Extension.extension.value[x]" /> + <min value="1" /> + <type> + <code value="string" /> + </type> + </element> + ... + </differential> +</StructureDefinition> +``` + +This section tells us that we need to include exactly one extension element from the `message-name` slice in our [ActivityDefinition](../fhir/activitydefinition.md). The extension element will have a URL value of `message-name`. If you remember the `discriminator` configuration, this URL value identifies the element to belong to the `message-name` slice on `Extension.extension`. Lastly, the extension element includes a `valueString` element. In case you are wondering how `value[x]` turned into `valueString`, FHIR does not allow using `value[x]` as actual element. The value in `value[x]` is always strictly bound to some kind of type. FHIR uses the `value[x].type.code` value to determine this type and replaces `[x]` with an uppercase version of `element.type.code`. This results in the following extension element we will add to our [ActivityDefinition](../fhir/activitydefinition.md): +```xml +<extension url="message-name"> + <valueString value="myMessage"/> +</extension> +``` + +For your use case, you have to replace `myMessage` with the name of the [BPMN message event](../bpmn/messaging.md) that is expecting this message. + +<details> +<summary>This is how your ActivityDefinition should look like so far</summary> + +```xml +<ActivityDefinition xmlns="http://hl7.org/fhir"> + <meta> + <tag> + <system value="http://dsf.dev/fhir/CodeSystem/read-access-tag" /> + <code value="ALL" /> + </tag> + </meta> + <extension url="http://dsf.dev/fhir/StructureDefinition/extension-process-authorization"> + <extension url="message-name"> + <valueString value="myMessage"/> + </extension> + </extension> +</ActivityDefinition> +``` +</details> + +The next slice is called `task-profile`: +```xml +<StructureDefinition xmlns="http://hl7.org/fhir"> + ... + <differential> + ... + <element id="Extension.extension:task-profile"> + <path value="Extension.extension" /> + <sliceName value="task-profile" /> + <min value="1" /> + <max value="1" /> + </element> + <element id="Extension.extension:task-profile.url"> + <path value="Extension.extension.url" /> + <fixedUri value="task-profile" /> + </element> + <element id="Extension.extension:task-profile.value[x]"> + <path value="Extension.extension.value[x]" /> + <min value="1" /> + <type> + <code value="canonical" /> + </type> + </element> + ... + </differential> +</StructureDefinition> +``` + +This section has almost the same structure as `message-name`. The only difference is the value for `value[x].type.code`. This means that instead of `valueString`, we will have to use a `valueCanonical` element for `task-profile.value[x]`. Canonical values referring to [Task](../fhir/task.md) profiles in ActivityDefinitions have to conform to the rules outlined by the documentation on [URLs](../dsf/versions-placeholders-urls.md#urls). From the definition above, we will create the following extension element and add it to our [ActivityDefinition](../fhir/activitydefinition.md): +```xml +<extension url="task-profile"> + <valueCanonical value="http://dsf.dev/fhir/StructureDefinition/my-task|#{version}"/> +</extension> +``` + +<details> +<summary>This is how your ActivityDefinition should look like so far</summary> + +```xml +<ActivityDefinition xmlns="http://hl7.org/fhir"> + <meta> + <tag> + <system value="http://dsf.dev/fhir/CodeSystem/read-access-tag" /> + <code value="ALL" /> + </tag> + </meta> + <extension url="http://dsf.dev/fhir/StructureDefinition/extension-process-authorization"> + <extension url="message-name"> + <valueString value="myMessage"/> + </extension> + <extension url="task-profile"> + <valueCanonical value="http://dsf.dev/fhir/StructureDefinition/my-task|#{version}"/> + </extension> + </extension> +</ActivityDefinition> +``` +</details> + +The next slice is `requester`: +```xml +<StructureDefinition xmlns="http://hl7.org/fhir"> + ... + <differential> + ... + <element id="Extension.extension:requester"> + <path value="Extension.extension" /> + <sliceName value="requester" /> + <min value="1" /> + </element> + <element id="Extension.extension:requester.url"> + <path value="Extension.extension.url" /> + <fixedUri value="requester" /> + </element> + <element id="Extension.extension:requester.value[x]"> + <path value="Extension.extension.value[x]" /> + <min value="1" /> + <type> + <code value="Coding" /> + <profile value="http://dsf.dev/fhir/StructureDefinition/coding-process-authorization-local-all|1.0.0" /> + <profile value="http://dsf.dev/fhir/StructureDefinition/coding-process-authorization-local-all-practitioner|1.0.0" /> + <profile value="http://dsf.dev/fhir/StructureDefinition/coding-process-authorization-local-organization|1.0.0" /> + <profile value="http://dsf.dev/fhir/StructureDefinition/coding-process-authorization-local-organization-practitioner|1.0.0" /> + <profile value="http://dsf.dev/fhir/StructureDefinition/coding-process-authorization-local-parent-organization-role|1.0.0" /> + <profile value="http://dsf.dev/fhir/StructureDefinition/coding-process-authorization-local-parent-organization-role-practitioner|1.0.0" /> + <profile value="http://dsf.dev/fhir/StructureDefinition/coding-process-authorization-remote-all|1.0.0" /> + <profile value="http://dsf.dev/fhir/StructureDefinition/coding-process-authorization-remote-organization|1.0.0" /> + <profile value="http://dsf.dev/fhir/StructureDefinition/coding-process-authorization-remote-parent-organization-role|1.0.0" /> + </type> + <binding> + <strength value="required" /> + <valueSet value="http://dsf.dev/fhir/ValueSet/process-authorization-requester|1.0.0" /> + </binding> + </element> + ... + </differential> +</StructureDefinition> +``` +Instead of a `string` or `canonical` type for `value[x]` we now have a `Coding` type. See the [FHIR documentation on Codings](https://www.hl7.org/fhir/R4/datatypes.html#Coding) for more in-depth information. `Codings` are elements which contain, among other things, a `code` and the `system` the code belongs to. In the same way we transformed `value[x]` into `valueString` or `valueCanonical` before, we will also have to turn `value[x]` into `valueCoding`. To use `Codings` in `valueCoding` elements, they are usually bound to the element through a [ValueSet](../fhir/valueset.md). This is the responsibility of the `binding` element. You can also see that `value[x].type.profile` lists a number of profiles. Instead of defining the elements in the same file, they were defined in different files for better readability. Depending on your use case, you have to pick one of the profiles. +Here is what they mean: +- `local-all`: All local requests will be allowed. Local requests are identified by matching the requester's certificate to a thumbprint which was internally marked by the DSF FHIR server as belonging to a local organization. +- `local-organization`: All local requests made from an organization with a specific `organization-identifier` will be allowed. +- `local-parent-organization-role`: All local requests made from an organization having a specific role inside a specific parent organization will be allowed. +- `remote` versions of the above rules work the same but the requester's certificate is instead required to match a thumbprint marked as a remote organization. +- `practitioner` suffixes all work the same. They include the same rules as their prefixes but now additionally require the requester to match a certain `practitioner-role`. A list of them + can be found [here](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/CodeSystem/dsf-practitioner-role-1.0.0.xml). This allows + for more granularity when defining authorization rules within an organization and can be integrated into local user management via [OpenID Connect](https://dsf.dev/stable/maintain/fhir/access-control.html). + +As you can see, there are no `practitioner` versions of `remote` authorization rules. From the perspective of the receiving DSF instance, remote requests are always issued by an organization. They do not hold any information about the local user management of the requesting organization. You can also find examples of all Codings from above [here](../dsf/requester-and-recipient.md). + +It is also good to keep in mind that you are allowed to add any number of `requester` elements into your [ActivityDefinition](../fhir/activitydefinition.md). Let us start out by adding a `requester` element like we did for previous elements: + +```xml +<extension url="requester"> + <valueCoding> + + </valueCoding> +</extension> +``` + +We now have to look at the elements that are defined in one of the profiles to fill in the remaining elements since they are not defined by the `requester` extension. For demonstration purposes, we will choose the [dsf-coding-process-authorization-local-organization-practitioner](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-coding-process-authorization-local-organization-practitioner-1.0.0.xml) profile. Since all elements listed in the [Coding definition](https://www.hl7.org/fhir/R4/datatypes.html#codesystem) are optional, we only have to look at the `differential` element from the profile we just selected: +<a id="coding-differential"></a> +```xml +<differential> + <element id="Coding.extension"> + <path value="Coding.extension" /> + <slicing> + <discriminator> + <type value="value" /> + <path value="url" /> + </discriminator> + <rules value="open" /> + </slicing> + </element> + <element id="Coding.extension:organization-practitioner"> + <path value="Coding.extension" /> + <sliceName value="organization-practitioner" /> + <min value="1" /> + <max value="1" /> + <type> + <code value="Extension" /> + <profile value="http://dsf.dev/fhir/StructureDefinition/extension-process-authorization-organization-practitioner|1.0.0" /> + </type> + </element> + <element id="Coding.system"> + <path value="Coding.system" /> + <min value="1" /> + <fixedUri value="http://dsf.dev/fhir/CodeSystem/process-authorization" /> + </element> + <element id="Coding.code"> + <path value="Coding.code" /> + <min value="1" /> + <fixedCode value="LOCAL_ORGANIZATION_PRACTITIONER" /> + </element> +</differential> +``` +It defines an extension called `organization-practitioner` which is identified through its url attribute. Again, the extension is only referenced, its location is in a different file. You can find it [here](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-extension-process-authorization-organization-practitioner-1.0.0.xml). Let us look at its `differential` element in the extension file to see how we need to populate the extension: +```xml +<differential> + <element id="Extension"> + <path value="Extension" /> + <min value="1" /> + <max value="1" /> + </element> + <element id="Extension.extension"> + <path value="Extension.extension" /> + <slicing> + <discriminator> + <type value="value" /> + <path value="url" /> + </discriminator> + <rules value="open" /> + </slicing> + </element> + <element id="Extension.extension:organization"> + <path value="Extension.extension" /> + <sliceName value="organization" /> + <min value="1" /> + <max value="1" /> + </element> + <element id="Extension.extension:organization.url"> + <path value="Extension.extension.url" /> + <fixedUri value="organization" /> + </element> + <element id="Extension.extension:organization.value[x]"> + <path value="Extension.extension.value[x]" /> + <min value="1" /> + <type> + <code value="Identifier" /> + </type> + </element> + <element id="Extension.extension:organization.value[x].system"> + <path value="Extension.extension.value[x].system" /> + <min value="1" /> + <fixedUri value="http://dsf.dev/sid/organization-identifier" /> + </element> + <element id="Extension.extension:organization.value[x].value"> + <path value="Extension.extension.value[x].value" /> + <min value="1" /> + </element> + <element id="Extension.extension:practitionerRole"> + <path value="Extension.extension" /> + <sliceName value="practitionerRole" /> + <min value="1" /> + <max value="1" /> + </element> + <element id="Extension.extension:practitionerRole.url"> + <path value="Extension.extension.url" /> + <fixedUri value="practitioner-role" /> + </element> + <element id="Extension.extension:practitionerRole.value[x]"> + <path value="Extension.extension.value[x]" /> + <min value="1" /> + <type> + <code value="Coding" /> + </type> + </element> + <element id="Extension.extension:practitionerRole.value[x].system"> + <path value="Extension.extension.value[x].system" /> + <min value="1" /> + </element> + <element id="Extension.extension:practitionerRole.value[x].code"> + <path value="Extension.extension.value[x].code" /> + <min value="1" /> + </element> + <element id="Extension.url"> + <path value="Extension.url" /> + <fixedUri value="http://dsf.dev/fhir/StructureDefinition/extension-process-authorization-organization-practitioner" /> + </element> + <element id="Extension.value[x]"> + <path value="Extension.value[x]" /> + <max value="0" /> + </element> +</differential> +``` + +This extension does not reference any other files. This means we reached the "deepest" level. So now we can start working our way back up again from here, by translating this definition into actual extension elements, then inserting it into the Coding we selected, translating the rest of the element definitions from the Coding resource and adding everything to our [ActivityDefinition](../fhir/activitydefinition.md). + +We will start with the `Extension.url` element, since the `Extension` element is the parent element for all slices on the `Extension.extension` elements: +```xml +<extension url="http://dsf.dev/fhir/StructureDefinition/extension-process-authorization-organization-practitioner"> + +</extension> +``` + +Next, we will add the `organization` slice: +```xml +<extension url="http://dsf.dev/fhir/StructureDefinition/extension-process-authorization-organization-practitioner"> + <extension url="organization"> + <valueIdentifier> + <system value="http://dsf.dev/sid/organization-identifier"/> + <value value="My_Organization"/> + </valueIdentifier> + </extension> +</extension> +``` +Finally, we will add the `practitionerRole` slice: + +```xml +<extension url="http://dsf.dev/fhir/StructureDefinition/extension-process-authorization-organization-practitioner"> + <extension url="organization"> + <valueIdentifier> + <system value="http://dsf.dev/sid/organization-identifier"/> + <value value="My_Organization"/> + </valueIdentifier> + </extension> + <extension url="practitioner-role"> + <valueCoding> + <system value="http://dsf.dev/fhir/CodeSystem/practitioner-role"/> + <code value="DSF_ADMIN"/> + </valueCoding> + </extension> +</extension> +``` + +Notice that there is no `binding` element specified for `practitionerRole.value[x]`. This is intentional. In the example we used a code from the [dsf-practitioner-role](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/CodeSystem/dsf-practitioner-role-1.0.0.xml) CodeSystem. This CodeSystem includes a standard set of codes which are often sufficient for DSF use cases. You can freely add other CodeSystems if you find these codes do not apply for your use case. The code you set here can be used in the [DSF role config](https://dsf.dev/stable/maintain/fhir/access-control.html) to allow certain users with this `practitioner-role` to send requests. + +Working our way back up to the Coding we selected, we will now add the extension we just created as the `Coding.extension:organization-practitioner` element: +```xml +<extension url="requester"> + <valueCoding> + <extension url="http://dsf.dev/fhir/StructureDefinition/extension-process-authorization-organization-practitioner"> + <extension url="organization"> + <valueIdentifier> + <system value="http://dsf.dev/sid/organization-identifier"/> + <value value="My_Organization"/> + </valueIdentifier> + </extension> + <extension url="practitioner-role"> + <valueCoding> + <system value="http://dsf.dev/fhir/CodeSystem/practitioner-role"/> + <code value="DSF_ADMIN"/> + </valueCoding> + </extension> + </extension> + </valueCoding> +</extension> +``` +Now might be a good time to look at the [differential](#coding-differential) from the Coding again. Our next elements to be added are `Coding.system` and `Coding.code`: +```xml +<extension url="requester"> + <valueCoding> + <extension url="http://dsf.dev/fhir/StructureDefinition/extension-process-authorization-organization-practitioner"> + <extension url="organization"> + <valueIdentifier> + <system value="http://dsf.dev/sid/organization-identifier"/> + <value value="My_Organization"/> + </valueIdentifier> + </extension> + <extension url="practitioner-role"> + <valueCoding> + <system value="http://dsf.dev/fhir/CodeSystem/practitioner-role"/> + <code value="DSF_ADMIN"/> + </valueCoding> + </extension> + </extension> + <system value="http://dsf.dev/fhir/CodeSystem/process-authorization"/> + <code value="LOCAL_ORGANIZATION_PRACTITIONER"/> + </valueCoding> +</extension> +``` +Now we are finished with the `requester` extension and can add it to our [ActivityDefinition](../fhir/activitydefinition.md) under the [dsf-extension-process-authorization](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-extension-process-authorization-1.0.0.xml). + +<details> +<summary>This is how your ActivityDefinition should look like so far</summary> + +```xml +<ActivityDefinition xmlns="http://hl7.org/fhir"> + <meta> + <tag> + <system value="http://dsf.dev/fhir/CodeSystem/read-access-tag" /> + <code value="ALL" /> + </tag> + </meta> + <extension url="http://dsf.dev/fhir/StructureDefinition/extension-process-authorization"> + <extension url="message-name"> + <valueString value="myMessage"/> + </extension> + <extension url="task-profile"> + <valueCanonical value="http://dsf.dev/fhir/StructureDefinition/my-task|#{version}"/> + </extension> + <extension url="requester"> + <valueCoding> + <extension url="http://dsf.dev/fhir/StructureDefinition/extension-process-authorization-organization-practitioner"> + <extension url="organization"> + <valueIdentifier> + <system value="http://dsf.dev/sid/organization-identifier"/> + <value value="My_Organization"/> + </valueIdentifier> + </extension> + <extension url="practitioner-role"> + <valueCoding> + <system value="http://dsf.dev/fhir/CodeSystem/practitioner-role"/> + <code value="DSF_ADMIN"/> + </valueCoding> + </extension> + </extension> + <system value="http://dsf.dev/fhir/CodeSystem/process-authorization"/> + <code value="LOCAL_ORGANIZATION_PRACTITIONER"/> + </valueCoding> + </extension> + </extension> +</ActivityDefinition> +``` +</details> + +Now we are back to looking at the [dsf-extension-process-authorization](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-extension-process-authorization-1.0.0.xml) again. The last slice for this extension is `recipient`: +```xml +<StructureDefinition xmlns="http://hl7.org/fhir"> + ... + <differential> + ... + <element id="Extension.extension:recipient"> + <path value="Extension.extension" /> + <sliceName value="recipient" /> + <min value="1" /> + </element> + <element id="Extension.extension:recipient.url"> + <path value="Extension.extension.url" /> + <fixedUri value="recipient" /> + </element> + <element id="Extension.extension:recipient.value[x]"> + <path value="Extension.extension.value[x]" /> + <min value="1" /> + <type> + <code value="Coding" /> + <profile value="http://dsf.dev/fhir/StructureDefinition/coding-process-authorization-local-all|1.0.0" /> + <profile value="http://dsf.dev/fhir/StructureDefinition/coding-process-authorization-local-organization|1.0.0" /> + <profile value="http://dsf.dev/fhir/StructureDefinition/coding-process-authorization-local-parent-organization-role|1.0.0" /> + </type> + <binding> + <strength value="required" /> + <valueSet value="http://dsf.dev/fhir/ValueSet/process-authorization-recipient|1.0.0" /> + </binding> + </element> + ... + </differential> +</StructureDefinition> +``` + +The `recipient` will decide which DSF instance is allowed to process that message. That is the reason why you will not find any Codings for `remote` or `practitioner` here. For `requester`, we already decided that we will only allow users with a certain role from our own (local) organization to send this message. So now we will only allow the DSF instance run by that same local organization to process the message. The right Coding for this job is the [coding-process-authorization-local-organization](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-coding-process-authorization-local-organization-1.0.0.xml). The configuration of a local requester and local receiver is often used for the message that starts up the first BPMN process of the plugin. The process of adding the `recipient` slice is the exact same as it is for `requester`. You can follow the steps for the `requester` slice again but just use a different Coding. + +<details> +<summary>Using the Coding we just decided on, this is how your ActivityDefinition should look like</summary> + +```xml +<ActivityDefinition xmlns="http://hl7.org/fhir"> + <meta> + <tag> + <system value="http://dsf.dev/fhir/CodeSystem/read-access-tag" /> + <code value="ALL" /> + </tag> + </meta> + <extension url="http://dsf.dev/fhir/StructureDefinition/extension-process-authorization"> + <extension url="message-name"> + <valueString value="myMessage"/> + </extension> + <extension url="task-profile"> + <valueCanonical value="http://dsf.dev/fhir/StructureDefinition/my-task|#{version}"/> + </extension> + <extension url="requester"> + <valueCoding> + <extension url="http://dsf.dev/fhir/StructureDefinition/extension-process-authorization-organization-practitioner"> + <extension url="organization"> + <valueIdentifier> + <system value="http://dsf.dev/sid/organization-identifier"/> + <value value="My_Organization"/> + </valueIdentifier> + </extension> + <extension url="practitioner-role"> + <valueCoding> + <system value="http://dsf.dev/fhir/CodeSystem/practitioner-role"/> + <code value="DSF_ADMIN"/> + </valueCoding> + </extension> + </extension> + <system value="http://dsf.dev/fhir/CodeSystem/process-authorization"/> + <code value="LOCAL_ORGANIZATION_PRACTITIONER"/> + </valueCoding> + </extension> + <extension url="recipient"> + <valueCoding> + <extension url="http://dsf.dev/fhir/StructureDefinition/extension-process-authorization-organization"> + <valueIdentifier> + <system value="http://dsf.dev/sid/organization-identifier"/> + <value value="My_Organization"/> + </valueIdentifier> + </extension> + <system value="http://dsf.dev/fhir/CodeSystem/process-authorization"/> + <code value="LOCAL_ORGANIZATION"/> + </valueCoding> + </extension> + </extension> +</ActivityDefinition> +``` +</details> + +The last element defined in the [process authorization extension](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-extension-process-authorization-1.0.0.xml) is `Extension.url`. But since we added this element at the very beginning of the working through the extension, we are finished with it here. + +#### 3. BPE Managed Elements + +Some elements of [ActivityDefinitions](../fhir/activitydefinition.md) are managed by the DSF BPE and replaced with certain values at appropriate times. + +The following elements are managed by the DSF BPE: +- `ActivityDefinition.version` should use the [placeholder](../dsf/versions-placeholders-urls.md#placeholders) `#{version}` +- `ActivityDefinition.date` is not required, but should you decide to include it, use the [placeholder](../dsf/versions-placeholders-urls.md#placeholders) `#{date}` +- `ActivityDefinition.status` must have a value of `unknown` + +<details> +<summary>Your ActivityDefinition should now look like this</summary> + +```xml +<ActivityDefinition xmlns="http://hl7.org/fhir"> + <meta> + <tag> + <system value="http://dsf.dev/fhir/CodeSystem/read-access-tag" /> + <code value="ALL" /> + </tag> + </meta> + <extension url="http://dsf.dev/fhir/StructureDefinition/extension-process-authorization"> + <extension url="message-name"> + <valueString value="myMessage"/> + </extension> + <extension url="task-profile"> + <valueCanonical value="http://dsf.dev/fhir/StructureDefinition/my-task|#{version}"/> + </extension> + <extension url="requester"> + <valueCoding> + <extension url="http://dsf.dev/fhir/StructureDefinition/extension-process-authorization-organization-practitioner"> + <extension url="organization"> + <valueIdentifier> + <system value="http://dsf.dev/sid/organization-identifier"/> + <value value="My_Organization"/> + </valueIdentifier> + </extension> + <extension url="practitioner-role"> + <valueCoding> + <system value="http://dsf.dev/fhir/CodeSystem/practitioner-role"/> + <code value="DSF_ADMIN"/> + </valueCoding> + </extension> + </extension> + <system value="http://dsf.dev/fhir/CodeSystem/process-authorization"/> + <code value="LOCAL_ORGANIZATION_PRACTITIONER"/> + </valueCoding> + </extension> + <extension url="recipient"> + <valueCoding> + <extension url="http://dsf.dev/fhir/StructureDefinition/extension-process-authorization-organization"> + <valueIdentifier> + <system value="http://dsf.dev/sid/organization-identifier"/> + <value value="My_Organization"/> + </valueIdentifier> + </extension> + <system value="http://dsf.dev/fhir/CodeSystem/process-authorization"/> + <code value="LOCAL_ORGANIZATION"/> + </valueCoding> + </extension> + </extension> + <!-- version managed by bpe --> + <version value="#{version}"/> + <!-- date managed by bpe --> + <date value="#{date}"/> + <!-- status managed by bpe --> + <status value="unknown"/> +</ActivityDefinition> +``` +</details> + +#### 4. Regular Elements + +The only required elements in this set are `ActivityDefinition.url` and `ActivityDefinition.kind`. Check out the documentation on [URLs](../dsf/versions-placeholders-urls.md#urls) on how to choose the correct value for `ActivityDefinition.url`. `ActivityDefinition.kind` must have the value `Task`. +All other elements can technically be omitted. Still, we recommend you include the following elements: +- `AcitivityDefinition.name` +- `AcitivityDefinition.title` +- `AcitivityDefinition.subtitle` +- `AcitivityDefinition.experimental` +- `AcitivityDefinition.publisher` +- `AcitivityDefinition.contact` +- `AcitivityDefinition.description` + +<details> +<summary>Your finished ActivityDefinition should now look something like this</summary> + +```xml +<ActivityDefinition xmlns="http://hl7.org/fhir"> + <meta> + <tag> + <system value="http://dsf.dev/fhir/CodeSystem/read-access-tag" /> + <code value="ALL" /> + </tag> + </meta> + <extension url="http://dsf.dev/fhir/StructureDefinition/extension-process-authorization"> + <extension url="message-name"> + <valueString value="myMessage"/> + </extension> + <extension url="task-profile"> + <valueCanonical value="http://dsf.dev/fhir/StructureDefinition/my-task|#{version}"/> + </extension> + <extension url="requester"> + <valueCoding> + <extension url="http://dsf.dev/fhir/StructureDefinition/extension-process-authorization-organization-practitioner"> + <extension url="organization"> + <valueIdentifier> + <system value="http://dsf.dev/sid/organization-identifier"/> + <value value="My_Organization"/> + </valueIdentifier> + </extension> + <extension url="practitioner-role"> + <valueCoding> + <system value="http://dsf.dev/fhir/CodeSystem/practitioner-role"/> + <code value="DSF_ADMIN"/> + </valueCoding> + </extension> + </extension> + <system value="http://dsf.dev/fhir/CodeSystem/process-authorization"/> + <code value="LOCAL_ORGANIZATION_PRACTITIONER"/> + </valueCoding> + </extension> + <extension url="recipient"> + <valueCoding> + <extension url="http://dsf.dev/fhir/StructureDefinition/extension-process-authorization-organization"> + <valueIdentifier> + <system value="http://dsf.dev/sid/organization-identifier"/> + <value value="My_Organization"/> + </valueIdentifier> + </extension> + <system value="http://dsf.dev/fhir/CodeSystem/process-authorization"/> + <code value="LOCAL_ORGANIZATION"/> + </valueCoding> + </extension> + </extension> + <!-- version managed by bpe --> + <version value="#{version}"/> + <!-- date managed by bpe --> + <date value="#{date}"/> + <!-- status managed by bpe --> + <status value="unknown"/> + <url value="http://dsf.dev/bpe/Process/myProcess"/> + <kind value="Task"/> + <name value="My Process"/> + <title value="My Title For My Process"/> + <subtitle value="Information Processing Process"/> + <experimental value="false"/> + <publisher value="DSF"/> + <contact> + <name value="DSF"/> + <telecom> + <system value="email"/> + <value value="noreply@dsf.dev"/> + </telecom> + </contact> + <description value="My Process processes information"/> +</ActivityDefinition> +``` +</details> \ No newline at end of file diff --git a/docs/src/process-development/api-v1/guides/creating-codesystems-for-dsf-processes.md b/docs/src/process-development/api-v1/guides/creating-codesystems-for-dsf-processes.md new file mode 100644 index 000000000..5ab6d87f1 --- /dev/null +++ b/docs/src/process-development/api-v1/guides/creating-codesystems-for-dsf-processes.md @@ -0,0 +1,42 @@ +--- +title: Creating CodeSystems for DSF Processes +icon: creative +--- + +### Creating CodeSystems for DSF Processes + +You might find yourself in a situation where you need to create a [CodeSystem](../fhir/codesystem.md). For example, when defining the type of an [Input Parameter](../fhir/task.md#task-input-parameters). [CodeSystems](../fhir/codesystem.md) for the DSF differ from regular [CodeSystems](../fhir/codesystem.md) in that some element's values are managed by the DSF BPE server. You can use the following XML as a template: +```xml +<CodeSystem xmlns="http://hl7.org/fhir"> + <meta> + <tag> + <system value="http://dsf.dev/fhir/CodeSystem/read-access-tag" /> + <code value="ALL" /> + </tag> + </meta> + <url value="http://dsf.dev/fhir/CodeSystem/my-code-system" /> <!--dummy value--> + <!-- version managed by bpe --> + <version value="#{version}" /> + <name value="My CodeSystem" /> <!--dummy value--> + <title value="My CodeSystem Title" /> <!--dummy value--> + <!-- status managed by bpe --> + <status value="unknown" /> + <experimental value="false" /> + <!-- date managed by bpe --> + <date value="#{date}" /> + <publisher value="DSF" /> <!--dummy value--> + <description value="CodeSystem with codes for me" /> <!--dummy value--> + <caseSensitive value="true" /> + <hierarchyMeaning value="grouped-by" /> + <versionNeeded value="false" /> + <content value="complete" /> + <concept> + <code value="my-code" /> <!--dummy value--> + <display value="My Code" /> <!--dummy value--> + <definition value="My code used for myself" /> <!--dummy value--> + </concept> +</CodeSystem> +``` +Replace dummy values with appropriate values of your own. Do not change elements managed by the DSF BPE server. You can add as many codes as you like by defining more `concept` elements. + +The DSF BPE server will read your [CodeSystem](../fhir/codesystem.md) from `tutorial-process/src/main/resources/fhir/CodeSystem`. \ No newline at end of file diff --git a/docs/src/process-development/api-v1/guides/creating-task-resources-based-on-a-definition.md b/docs/src/process-development/api-v1/guides/creating-task-resources-based-on-a-definition.md new file mode 100644 index 000000000..6306ab128 --- /dev/null +++ b/docs/src/process-development/api-v1/guides/creating-task-resources-based-on-a-definition.md @@ -0,0 +1,231 @@ +--- +title: Creating Task Resources Based on a Definition +icon: creative +--- + +### Creating Task Resources Based on a Definition + +This short guide should help you understand how you can create [Task](../fhir/task.md) resources for use in [Starting A Process Via Task Resources](../guides/starting-a-process-via-task-resources.md). We will employ the use of the free version of [Forge](https://simplifier.net/forge?utm_source=firely-forge) to help with visualization. You are invited to create a free account and follow along, but we will include screenshots of relevant views either way. Remember that the free version of Forge [must not be used commercially](https://simplifier.net/pricing). As an example, we will create a [Task](../fhir/task.md) resource from the `task-start-dic-process.xml` profile. + +#### 1st Step: Removing Placeholders +`task-start-dic-process.xml` includes placeholders for the `version` and `date` elements. For the duration of this guide, you can either remove or comment these elements, so Forge does not try to perform type checking on them, which would result in an error and Forge not loading the file. + +#### 2nd Step: Differential Chain +If the resource profile is only available as a [differential](https://www.hl7.org/fhir/R4/profiling.html#snapshot), like in our case, we will want to aggregate the changes made to the base resource (in this case [Task](../fhir/task.md)) by all profiles to make it more readable. To do this, we first need all the profiles involved. We already have `task-start-dic-process.xml` in our `StructureDefinition` folder. It lists a resource called `task-base` in its `baseDefinition` element. This resource is part of the DSF and can be found [here](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-task-base-1.0.0.xml). Put it into the `StructureDefinition` folder. Since `task-base` has the original FHIR Task as its `baseDefinition` element, we are done with this chain. In forge, you should now be able to open the `StructureDefinition` folder and select the `task-start-dic-process.xml` profile. It should look something like this: + +![Forge overview](/photos/developer-documentation/forge_overview.png) + +#### 3rd Step: Building the Task Resource +We will now go through each element one by one and include it into our [Task](../fhir/task.md) resource, provided it is mandatory (cardinality at least `1..1`) according to the profile. It is important that you not use any placeholders like `#{version}` for resources not read by the DSF BPE server. This is the case if we want a [Task](../fhir/task.md) resource for use with [cURL](../guides/starting-a-process-via-task-resources.md#using-curl). But, placeholders should be used in [Draft Task Resources](../dsf/draft-task-resources.md) instead of actual values wherever possible, since those are read by the DSF BPE server. This guide will create a [Task](../fhir/task.md) resource without placeholders. We will start out with the base element for all [Task](../fhir/task.md) resources: +```xml +<Task xmlns="http://hl7.org/fhir"> + +</Task> +``` + +Before we start adding any elements listed in Forge's element tree, we have to include the `Task.meta.profile` element. Its requirement cannot be seen here which is why we mention it specifically. This is the only instance you will not see it in the element tree. It should look like this: +```xml +<Task xmlns="http://hl7.org/fhir"> + <meta> + <profile value="http://dsf.dev/fhir/StructureDefinition/task-start-dic-process|1.0"/> + </meta> +</Task> +``` + +The first element which can be found in the element tree is the `instantiatesCanonical` element. To add it, we will create an XML element with the same name and the value according to [URLs](../dsf/versions-placeholders-urls.md#urls): +```xml +<Task xmlns="http://hl7.org/fhir"> + <meta> + <profile value="http://dsf.dev/fhir/StructureDefinition/task-start-dic-process|1.0"/> + </meta> + <instantiatesCanonical value="http://dsf.dev/bpe/Process/dicProcess|1.0" /> +</Task> +``` +We can continue this process for all primitive elements like these. Just make sure you pay attention to use the correct data type (e.g. proper coding value for elements with `coding` type). + +By now your [Task](../fhir/task.md) resources should look something like this: +<details> +<summary>Suggested solution</summary> + +```xml +<Task xmlns="http://hl7.org/fhir"> + <meta> + <profile value="http://dsf.dev/fhir/StructureDefinition/task-start-dic-process|1.0"/> + </meta> + <instantiatesCanonical value="http://dsf.dev/bpe/Process/dicProcess|1.0" /> + <status value="requested"/> + <intent value="order"/> + <authoredOn value="2024-02-08T10:00:00+00:00" /> +</Task> +``` +</details> + +Let us look at a more complex element like the `requester` element: + +![Forge requester view](/photos/developer-documentation/forge_requester_view.png) + +We will start the same way we started with primitive elements, by adding the `requester` element: +```xml +<Task xmlns="http://hl7.org/fhir"> + <meta> + <profile value="http://dsf.dev/fhir/StructureDefinition/task-start-dic-process|1.0"/> + </meta> + <instantiatesCanonical value="http://dsf.dev/bpe/Process/dicProcess|1.0" /> + <status value="requested"/> + <intent value="order"/> + <authoredOn value="2024-02-08T10:00:00+00:00" /> + <requester> + + </requester> +</Task> +``` + +Then, we will add primitive elements to `requester` like we did before for `Task`: +```xml +<Task xmlns="http://hl7.org/fhir"> + <meta> + <profile value="http://dsf.dev/fhir/StructureDefinition/task-start-dic-process|1.0"/> + </meta> + <instantiatesCanonical value="http://dsf.dev/bpe/Process/dicProcess|1.0" /> + <status value="requested"/> + <intent value="order"/> + <authoredOn value="2024-02-08T10:00:00+00:00" /> + <requester> + <type value="Organization"/> + </requester> +</Task> +``` +*Important to note here that the value for the `status` will always be `requested` for Tasks being posted using cURL and the `type` element for `requester` and `recipient` will always have the value `Organization` in the DSF context.* + +Next, we will add the `identifier` element and its primitive sub-elements just like we started out doing it for the `requester` element. The `identifier.value` in this case will be `dic.dsf.test`. To understand why, take a look at the topic on [organization identifiers](../dsf/organization-identifiers.md): +```xml +<Task xmlns="http://hl7.org/fhir"> + <meta> + <profile value="http://dsf.dev/fhir/StructureDefinition/task-start-dic-process|1.0"/> + </meta> + <instantiatesCanonical value="http://dsf.dev/bpe/Process/dicProcess|1.0" /> + <status value="requested"/> + <intent value="order"/> + <authoredOn value="2024-02-08T10:00:00+00:00" /> + <requester> + <type value="Organization"/> + <identifier> + <system value="http://dsf.dev/sid/organization-identifier"/> + <value value="dic.dsf.test" /> + </identifier> + </requester> +</Task> +``` +*Notice that `requester.identifier.system` has a `Fixed value` annotation. You can see what the value is supposed to be by clicking on the `system` element in Forge or looking at the XML for the right Task profile. The right side will have all information about that element, including the actual value for `Fixed value`.* + +You should now be able to fill out all elements in your [Task](../fhir/task.md) resource until you reach the [slicing](https://www.hl7.org/fhir/R4/profiling.html#slicing) for `Task.input`. Your [Task](../fhir/task.md) resource should look something like this: +<details> +<summary>Suggested solution</summary> + +```xml +<Task xmlns="http://hl7.org/fhir"> + <meta> + <profile value="http://dsf.dev/fhir/StructureDefinition/task-start-dic-process|1.0"/> + </meta> + <instantiatesCanonical value="http://dsf.dev/bpe/Process/dicProcess|1.0" /> + <status value="requested"/> + <intent value="order"/> + <authoredOn value="2024-02-08T10:00:00+00:00" /> + <requester> + <type value="Organization"/> + <identifier> + <system value="http://dsf.dev/sid/organization-identifier"/> + <value value="dic.dsf.test" /> + </identifier> + </requester> + <restriction> + <recipient> + <type value="Organization"/> + <identifier> + <system value="http://dsf.dev/sid/organization-identifier" /> + <value value="dic.dsf.test" /> + </identifier> + </recipient> + </restriction> +</Task> +``` +</details> + + +[Slicings](https://www.hl7.org/fhir/R4/profiling.html#slicing) are a bit different from regular elements. Let us look at the slice `message-name`: + +![Forge slice message name](/photos/developer-documentation/forge_slice_message_name.png) + +If we were to continue including slices to the [Task](../fhir/task.md) resource like we did so far, we would add a `message-name` element to our XML like this: + +```xml +<Task xmlns="http://hl7.org/fhir"> + ... + <input> + <message-name> + ... + </message-name> + </input> +</Task> +``` + +This approach however, would not work. FHIR processors do not use the name of the slice to map entries in your [Task](../fhir/task.md) resource to the correct slice. They use [discriminators](https://www.hl7.org/fhir/R4/profiling.html#discriminator). Discriminators define the elements a processor needs to distinguish slices by. You can see how the discriminator is configured by selecting the `input` element in Forge. In our case, a processor would look at the values for `input.type.coding.system` and `input.type.coding.code` to determine which slice this element belongs to. This only works because `input.type.coding.system` and `input.type.coding.code` are present in all slices and have a `Fixed value`. You can learn more about discriminators [here](https://www.hl7.org/fhir/R4/profiling.html#discriminator). All this means is that we effectively ignore the name of the slice as an element and start adding elements like we did before: + +```xml +<Task xmlns="http://hl7.org/fhir"> + ... + <input> + <type> + <coding> + <system value="http://dsf.dev/fhir/CodeSystem/bpmn-message" /> + <code value="message-name" /> + </coding> + </type> + <valueString value="dicProcess" /> + </input> +</Task> +``` + +Now you should be able to add all remaining mandatory elements to your [Task](../fhir/task.md) resource on your own. In the end, it should look something like this: +<details> +<summary>Suggested solution</summary> + +```xml +<Task xmlns="http://hl7.org/fhir"> + <meta> + <profile value="http://dsf.dev/fhir/StructureDefinition/task-start-dic-process|1.0"/> + </meta> + <instantiatesCanonical value="http://dsf.dev/bpe/Process/dicProcess|1.0" /> + <status value="requested"/> + <intent value="order"/> + <authoredOn value="2024-02-08T10:00:00+00:00" /> + <requester> + <type value="Organization"/> + <identifier> + <system value="http://dsf.dev/sid/organization-identifier"/> + <value value="dic.dsf.test" /> + </identifier> + </requester> + <restriction> + <recipient> + <type value="Organization"/> + <identifier> + <system value="http://dsf.dev/sid/organization-identifier" /> + <value value="dic.dsf.test" /> + </identifier> + </recipient> + </restriction> + <input> + <type> + <coding> + <system value="http://dsf.dev/fhir/CodeSystem/bpmn-message" /> + <code value="message-name" /> + </coding> + </type> + <valueString value="dicProcess"/> + </input> +</Task> +``` +</details> + +**Do not forget to restore the version and date placeholders in `task-start-dic-process.xml`!** \ No newline at end of file diff --git a/docs/src/process-development/api-v1/guides/creating-valuesets-for-dsf-processes.md b/docs/src/process-development/api-v1/guides/creating-valuesets-for-dsf-processes.md new file mode 100644 index 000000000..f273196ec --- /dev/null +++ b/docs/src/process-development/api-v1/guides/creating-valuesets-for-dsf-processes.md @@ -0,0 +1,63 @@ +--- +title: Creating ValueSets for DSF Processes +icon: creative +--- + +### Creating ValueSets for DSF Processes + +You might find yourself in the situation where you need to create a [ValueSet](../fhir/valueset.md). For example, when adding [Input Parameters](../fhir/task.md#task-input-parameters) to DSF [Task](../fhir/task.md) resources, you will also have to reference a [ValueSet](../fhir/valueset.md) resource in your binding for `Task.input.type` to be able to set the type of your [Input Parameter](../fhir/task.md#task-input-parameters). [ValueSets](../fhir/valueset.md) for the DSF differ from regular [ValueSets](../fhir/valueset.md) in that some element's values are managed by the DSF BPE server. You can use the following template for your +[ValueSet](../fhir/valueset.md): +```xml +<ValueSet xmlns="http://hl7.org/fhir"> + <meta> + <tag> + <system value="http://dsf.dev/fhir/CodeSystem/read-access-tag" /> + <code value="ALL" /> + </tag> + </meta> + <url value="http://dsf.dev/fhir/ValueSet/my-value-set"/> <!--dummy value--> + <!-- version managed by bpe --> + <version value="#{version}" /> + <name value="My ValueSet"/> <!--dummy value--> + <title value="My ValueSet Title"/> <!--dummy value--> + <!-- status managed by bpe --> + <status value="unknown" /> + <experimental value="false"/> + <!-- date managed by bpe --> + <date value="#{date}"/> + <publisher value="DSF"/> <!--dummy value--> + <description value="ValueSet with all codes from my-code-system"/> <!--dummy value--> + <immutable value="true"/> + <compose> + <include> + <system value="http://dsf.dev/fhir/CodeSystem/my-code-system"/> <!--dummy value--> + <version value="#{version}"/> + </include> + </compose> +</ValueSet> +``` +Replace dummy values with appropriate values of your own. Do not change elements managed by the DSF BPE server. The `compose` element defines the codes included in this [ValueSet](../fhir/valueset.md). It holds at least one `include` element. Each `include` element refers to a [CodeSystem](../fhir/codesystem.md) and contains a list of `concept` elements which in turn contain the actual `code` element. Using one code from `my-code-system` and one code from `my-other-code-system` would result in the following `compose` element: +```xml +<ValueSet xmlns="http://hl7.org/fhir"> + ... + <compose> + <include> + <system value="http://dsf.dev/fhir/CodeSystem/my-code-system"/> + <version value="#{version}"/> + <concept> + <code value="my-code"/> + </concept> + </include> + <include> + <system value="http://dsf.dev/fhir/CodeSystem/my-other-code-system"/> + <version value="#{version}"/> + <concept> + <code value="my-other-code"/> + </concept> + </include> + </compose> +</ValueSet> +``` +The DSF BPE server will read your [ValueSet](../fhir/valueset.md) from `tutorial-process/src/main/resources/fhir/ValueSet`. + +You might also want to check out [this guide](../guides/creating-codesystems-for-dsf-processes.md) on how to create [CodeSystems](../fhir/codesystem.md). \ No newline at end of file diff --git a/docs/src/process-development/api-v1/guides/index.md b/docs/src/process-development/api-v1/guides/index.md new file mode 100644 index 000000000..2841de106 --- /dev/null +++ b/docs/src/process-development/api-v1/guides/index.md @@ -0,0 +1,17 @@ +--- +title: Guides +icon: creative +--- + +## Details +- [Accessing BPMN Process Variables](accessing-bpmn-process-variables.md) +- [Accessing Task Resources During Execution](accessing-task-resources-during-execution.md) +- [Adding Task Input Parameters to Task Profiles](adding-task-input-parameters-to-task-profiles.md) +- [Configuring Read Access Tags](configuring-read-access-tags.md) +- [Creating ActivityDefinitions](creating-activity-definitions.md) +- [Creating CodeSystems for DSF Processes](creating-codesystems-for-dsf-processes.md) +- [Creating Task Resources Based on a Definition](creating-task-resources-based-on-a-definition.md) +- [Creating ValueSets for DSF Processes](creating-valuesets-for-dsf-processes.md) +- [Managing Multiple Incoming Messages and Missing Messages](managing-mutiple-incoming-messages-and-missing-messages.md) +- [Setting Targets for Message Events](setting-targets-for-message-events.md) +- [Starting a Process via Task Resources](starting-a-process-via-task-resources.md) \ No newline at end of file diff --git a/docs/src/process-development/api-v1/guides/managing-mutiple-incoming-messages-and-missing-messages.md b/docs/src/process-development/api-v1/guides/managing-mutiple-incoming-messages-and-missing-messages.md new file mode 100644 index 000000000..a0c8f6120 --- /dev/null +++ b/docs/src/process-development/api-v1/guides/managing-mutiple-incoming-messages-and-missing-messages.md @@ -0,0 +1,18 @@ +--- +title: Managing Multiple Incoming Messages and Missing Messages +icon: creative +--- + +### Managing Multiple Incoming Messages and Missing Messages + +If an already running process instance is waiting for a message from another organization, the corresponding FHIR [Task](../fhir/task.md) may never arrive. Either because the other organization decides to never send the message or because some technical problem prohibits the [Task](../fhir/task.md) resource from being posted to the DSF FHIR server. This would result in stale process instances that never finish. + +At the same time, you might also expect to receive one out of a number of different message types at once. + +In order to solve both problems we can add an [Event Based Gateway](../bpmn/gateways.md#event-based-gateway) to the process waiting for a response and then either handle a [Task](../fhir/task.md) resource with the response and finish the process in a success state or trigger a [Timer Intermediate Catching Event](../bpmn/timer-intermediate-catching-events.md) after a defined wait period and finish the process in an error state. The following BPMN collaboration diagram shows how the process at the first organization would look like if we wanted to react to multiple different messages or missing messages: + +<picture> + <source media="(prefers-color-scheme: dark)" srcset="/photos/developer-documentation/event_based_gateway_inverted.svg"> + <source media="(prefers-color-scheme: light)" srcset="/photos/developer-documentation/event_based_gateway.svg"> + <img alt="BPMN collaboration diagram with an Event Based Gateway" src="/photos/developer-documentation/event_based_gateway.svg"> +</picture> diff --git a/docs/src/process-development/api-v1/guides/setting-targets-for-message-events.md b/docs/src/process-development/api-v1/guides/setting-targets-for-message-events.md new file mode 100644 index 000000000..68db0b1e0 --- /dev/null +++ b/docs/src/process-development/api-v1/guides/setting-targets-for-message-events.md @@ -0,0 +1,14 @@ +--- +title: Setting Targets for Message Events +icon: creative +--- + +### Setting Targets for Message Events + +Setting a target for a message event requires a `Target` object. To create one, you require a target's organization identifier, endpoint identifier and endpoint address. You can find these values by visiting the DSF FHIR server's web interface. In the top right corner, click the `Show Bookmarks` button, then select `Endpoint`. You will be taken to a list of all Endpoints available to the FHIR server. There are two ways of adding `targets` to the BPMN execution variables: +#### 1. Adding the target in the message event implementation +In your message event implementation (the class extending `AbstractTaskMessageSend`), you can override `AbstractTaskMessageSend#doExecute`, add your targets and then call the super-method. +#### 2. Adding the target in a service task right before the message event +This is the preferred method of this tutorial but both methods will work perfectly fine. For our use cases, we usually prefer this one since there is enough complexity to warrant putting it into a separate BPMN [Service Task](../bpmn/service-tasks.md). + +In both cases you can access methods to create and set `targets` through the `Variables` instance. diff --git a/docs/src/process-development/api-v1/guides/starting-a-process-via-task-resources.md b/docs/src/process-development/api-v1/guides/starting-a-process-via-task-resources.md new file mode 100644 index 000000000..baa36a7bb --- /dev/null +++ b/docs/src/process-development/api-v1/guides/starting-a-process-via-task-resources.md @@ -0,0 +1,43 @@ +--- +title: Starting a Process via Task Resources +icon: creative +--- + +### Starting a Process via Task Resources + +To start a BPMN process, you need to create new a [Task](../fhir/task.md) resource in the DSF FHIR server by sending an HTTP request according to the [FHIR RESTful API](https://www.hl7.org/fhir/R4/http.html). Specifically, you need to [create](https://www.hl7.org/fhir/R4/http.html#create) +a resource for the first time. Also, remember that the [Task](../fhir/task.md) resource you are sending needs to comply to the [Task](../fhir/task.md) profile of the process you want to start and the [ActivityDefinition's](../fhir/activitydefinition.md) authorization rules. +There are two major ways of making this HTTP request: +1. Using cURL +2. Using the DSF FHIR server's web interface + +#### Using cURL +In order to use cURL, you will have to create an appropriate [Task](../fhir/task.md) resource to post to the DSF FHIR server. There already is a file called `example-task.xml` located in `tutorial-process/src/main/resources/fhir`. You can use this as your starting point. You can try to follow [this guide](../guides/creating-task-resources-based-on-a-definition.md), or you can check the solution branches for this file if you need ideas on how to fill it out properly. + +Below are some cURL command skeletons. Replace all <>-Placeholders with appropriate values. Host name depends on the instance you want to address. + +##### Linux: +```shell +curl https://<instance-host-name>/fhir/Task \ +--cacert <path/to/ca-certificate-file.pem> \ +--cert <path/to/client-certificate-file.pem>:password \ +--key <path/to/client-private-key-file.pem> \ +-H "Content-Type: application/fhir+xml" \ +-H "Accept: application/fhir+xml" \ +-d @<path/to/example-task.xml> +``` +##### Windows CMD: +```shell +curl https://<instance-host-name>/fhir/Task ^ +--cacert <path/to/ca-certificate-file.pem> ^ +--cert <path/to/client-certificate-file.pem>:password ^ +--key <path/to/client-private-key-file.pem> ^ +-H "Content-Type: application/fhir+xml" ^ +-H "Accept: application/fhir+xml" ^ +-d @<path/to/example-task.xml> +``` +*This may throw an error depending on which version of cURL Windows is using. If this is the case for you after making sure you entered everything correctly, you can try using Git's version of cURL instead by adding it to the very top of your system's PATH environment variable. Git's cURL is usually situated in C:\Program Files\Git\mingw64\bin.* + +#### Using the DSF FHIR Server's Web Interface + +When visiting the web interface of a DSF FHIR server instance (e.g. https://instance-name/fhir), you can query the DSF FHIR server using the [FHIR RESTful API](https://www.hl7.org/fhir/R4/http.html) to return a list of all [Draft Task Resources](../dsf/draft-task-resources.md). These [Task](../fhir/task.md) resources act like a template you can use to instantiate [Task](../fhir/task.md) resources which start BPMN processes. Instead of querying the DSF FHIR server manually, you can use a predefined bookmark to navigate to the query URL. You can find a list of Bookmarks in the top right corner of the web interface. Simply select the bookmark referencing `?_sort=_profile,identifier&status=draft` under the `Task` section, and you will be taken to the list of all [Draft Task Resources](../dsf/draft-task-resources.md). Once there, you can select the one which starts your BPMN process. It will take you to a detailed view of the resource where you will also have the chance to fill any [Task Input Parameters](../fhir/task.md#task-input-parameters) you might need to specify. If everything is filled out correctly, you may start your process by clicking `Start Process`. Keep in mind that, for [Draft Task Resources](../dsf/draft-task-resources.md) to be available, you need to include them in your mapping for your BPMN process ID in `ProcessPluginDefinition#getFhirResourcesByProcessId`. Take a look at [the Process Plugin Definition](../dsf/process-plugin-definition.md) if you need a reminder. \ No newline at end of file diff --git a/docs/src/process-development/api-v1/guides/user-tasks-in-the-dsf.md b/docs/src/process-development/api-v1/guides/user-tasks-in-the-dsf.md new file mode 100644 index 000000000..6bd4ca28b --- /dev/null +++ b/docs/src/process-development/api-v1/guides/user-tasks-in-the-dsf.md @@ -0,0 +1,57 @@ +--- +title: User Tasks in the DSF +icon: creative +--- + +### User Tasks in the DSF + +Creating a [User Task](../concepts/bpmn/user-tasks.md) in a BPMN model, causes the DSF to automatically generate a [QuestionnaireResponse](https://www.hl7.org/fhir/R4/questionnaireresponse.html) resource according to a [Questionnaire](https://www.hl7.org/fhir/R4/questionnaire.html) you provided in the [User Task's](../concepts/bpmn/user-tasks.md) `Forms` field when the process execution reaches the [User Task](../concepts/bpmn/user-tasks.md). The `Forms` field needs to have a type of `Embedded or External Task Forms` with the `Form key` being the url of your [Questionnaire](https://www.hl7.org/fhir/R4/questionnaire.html) resource. The [Questionnaire](https://www.hl7.org/fhir/R4/questionnaire.html) resource needs to be put in the `src/main/resources/fhir/Questionnaire` directory. The generated [QuestionnaireResponse](https://www.hl7.org/fhir/R4/questionnaireresponse.html) can now be answered by locating the [QuestionnaireResponse](https://www.hl7.org/fhir/R4/questionnaireresponse.html) in the DSF FHIR server UI through `https://your.dsf.fhir.server/fhir/QuestionnaireResponse?_sort=-_lastUpdated&status=in-progress`. After filling out the [QuestionnaireResponse](https://www.hl7.org/fhir/R4/questionnaireresponse.html) and submitting it, the process execution will continue with the next BPMN element after the [User Task](../concepts/bpmn/user-tasks.md) and the updated [QuestionnaireResponse](https://www.hl7.org/fhir/R4/questionnaireresponse.html) will be available through the [Process Plugin Api's](../concepts/dsf/process-api.md) `Variables` instance by calling `getLatestReceivedQuestionnaireResponse()`. + +You also have the option to register a [Task Listener](https://docs.camunda.org/manual/7.21/user-guide/process-engine/delegation-code/#task-listener) on the [User Task](../concepts/bpmn/user-tasks.md). This allows you to manipulate the [QuestionnaireResponse](https://www.hl7.org/fhir/R4/questionnaireresponse.html) before it is posted to the DSF FHIR server. You do this by extending the `DefaultUserTaskListener` class which provides overrides to interact with the [QuestionnaireResponse](https://www.hl7.org/fhir/R4/questionnaireresponse.html). Notice that dynamically changing the `item.text` value of an item in a [QuestionnaireResponse](https://www.hl7.org/fhir/R4/questionnaireresponse.html) (that is **NOT** of type `display`) is not allowed. For that, you would have to change the `item.text` value of the corresponding [Questionnaire](https://www.hl7.org/fhir/R4/questionnaire.html) resource as well. Instead, you should have an item of type `display` above the item whose text should change dynamically, like in the template, and change its `item.text` value. In this case, you may also leave out `item.text` element of the item below the display item. + +Below you can find a template for a [Questionnaire](https://www.hl7.org/fhir/R4/questionnaire.html) resource. Replace `questionnaire-name` with the name of your [Questionnaire](https://www.hl7.org/fhir/R4/questionnaire.html) and have the file be named the same. The items `business-key` and `user-task-id` are required by the DSF and are always included. You can then add any amount of items of your choosing to the [Questionnaire](https://www.hl7.org/fhir/R4/questionnaire.html). + +### Questionnaire Template +```xml +<Questionnaire xmlns="http://hl7.org/fhir"> + <meta> + <profile value="http://dsf.dev/fhir/StructureDefinition/questionnaire|1.5.0"/> + <tag> + <system value="http://dsf.dev/fhir/CodeSystem/read-access-tag"/> + <code value="ALL"/> + </tag> + </meta> + <url value="http://dsf.dev/fhir/Questionnaire/questionnaire-name"/> <!-- file name should be same as the name of your Questionnaire --> + <!-- version managed by bpe --> + <version value="#{version}"/> + <!-- date managed by bpe --> + <date value="#{date}"/> + <!-- status managed by bpe --> + <status value="unknown"/> + <item> + <!-- required --> + <linkId value="business-key"/> + <type value="string"/> + <text value="The business-key of the process execution"/> + <required value="true"/> + </item> + <item> + <!-- required --> + <linkId value="user-task-id"/> + <type value="string"/> + <text value="The user-task-id of the process execution"/> + <required value="true"/> + </item> + <item> + <linkId value="text-to-display-above-item"/> + <type value="display"/> + <text value="foo"/> + </item> + <item> + <linkId value="item"/> + <type value="boolean"/> + <text value="Item description"/> + <required value="true"/> + </item> +</Questionnaire> +``` \ No newline at end of file diff --git a/docs/src/process-development/api-v1/index.md b/docs/src/process-development/api-v1/index.md new file mode 100644 index 000000000..ca799dea6 --- /dev/null +++ b/docs/src/process-development/api-v1/index.md @@ -0,0 +1,47 @@ +--- +title: Developer Documentation +icon: creative +--- + +## BPMN +- [Conditions](bpmn/conditions.md) +- [Gateways](bpmn/gateways.md) +- [Messaging](bpmn/messaging.md) +- [Sequence Flow](bpmn/sequence-flow.md) +- [Service Tasks](bpmn/service-tasks.md) +- [Timer Intermediate Catching Events](bpmn/timer-intermediate-catching-events.md) + +## FHIR +- [ActivityDefinition](fhir/activitydefinition.md) +- [Codesystem](fhir/codesystem.md) +- [Task](fhir/task.md) +- [ValueSet](fhir/valueset.md) + +## DSF +- [BPMN Process Execution](dsf/bpmn-process-execution.md) +- [BPMN Process Variables](dsf/bpmn-process-variables.md) +- [Draft Task Resources](dsf/draft-task-resources.md) +- [Environment Variables](dsf/environment-variables.md) +- [Message Correlation](dsf/message-correlation.md) +- [Message Delegates](dsf/message-delegates.md) +- [Organization Identifiers](dsf/organization-identifiers.md) +- [Process Plugin API](dsf/process-plugin-api.md) +- [Process Plugin Definition](dsf/process-plugin-definition.md) +- [Read Access Tag](dsf/read-access-tag.md) +- [Requester and Recipient](dsf/requester-and-recipient.md) +- [Service Delegates](dsf/service-delegates.md) +- [Spring Framework Integration](dsf/spring-framework-integration.md) +- [Versions, Placeholders and URLs](dsf/versions-placeholders-urls.md) + +## Guides +- [Accessing BPMN Process Variables](guides/accessing-bpmn-process-variables.md) +- [Accessing Task Resources During Execution](guides/accessing-task-resources-during-execution.md) +- [Adding Task Input Parameters to Task Profiles](guides/adding-task-input-parameters-to-task-profiles.md) +- [Configuring Read Access Tags](guides/configuring-read-access-tags.md) +- [Creating ActivityDefinitions](guides/creating-activity-definitions.md) +- [Creating CodeSystems for DSF Processes](guides/creating-codesystems-for-dsf-processes.md) +- [Creating Task Resources Based on a Definition](guides/creating-task-resources-based-on-a-definition.md) +- [Creating ValueSets for DSF Processes](guides/creating-valuesets-for-dsf-processes.md) +- [Managing Multiple Incoming Messages and Missing Messages](guides/managing-mutiple-incoming-messages-and-missing-messages.md) +- [Setting Targets for Message Events](guides/setting-targets-for-message-events.md) +- [Starting a Process via Task Resources](guides/starting-a-process-via-task-resources.md) \ No newline at end of file From 75aa2fbf7572cdfd74f50a5876b162075691e1a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20B=C3=B6hringer?= <jan.boehringer@hs-heilbronn.de> Date: Wed, 28 May 2025 11:31:27 +0200 Subject: [PATCH 13/14] Removed old documenation folder --- docs/src/develop/bpmn/conditions.md | 8 - docs/src/develop/bpmn/gateways.md | 16 - docs/src/develop/bpmn/index.md | 15 - docs/src/develop/bpmn/messaging.md | 24 - docs/src/develop/bpmn/sequence-flow.md | 7 - docs/src/develop/bpmn/service-tasks.md | 8 - .../timer-intermediate-catching-events.md | 8 - .../src/develop/dsf/bpmn-process-execution.md | 8 - .../src/develop/dsf/bpmn-process-variables.md | 10 - docs/src/develop/dsf/draft-task-resources.md | 21 - docs/src/develop/dsf/environment-variables.md | 10 - docs/src/develop/dsf/index.md | 20 - docs/src/develop/dsf/message-correlation.md | 10 - docs/src/develop/dsf/message-delegates.md | 15 - .../develop/dsf/organization-identifiers.md | 10 - docs/src/develop/dsf/process-plugin-api.md | 32 - .../develop/dsf/process-plugin-definition.md | 16 - docs/src/develop/dsf/read-access-tag.md | 22 - .../develop/dsf/requester-and-recipient.md | 250 ------ docs/src/develop/dsf/service-delegates.md | 12 - .../dsf/spring-framework-integration.md | 14 - .../develop/dsf/versions-placeholders-urls.md | 38 - docs/src/develop/fhir/activitydefinition.md | 23 - docs/src/develop/fhir/codesystem.md | 12 - docs/src/develop/fhir/index.md | 13 - docs/src/develop/fhir/task.md | 19 - docs/src/develop/fhir/valueset.md | 10 - .../accessing-bpmn-process-variables.md | 10 - ...cessing-task-resources-during-execution.md | 12 - ...-task-input-parameters-to-task-profiles.md | 210 ----- .../guides/configuring-read-access-tags.md | 415 ---------- .../guides/creating-activity-definitions.md | 750 ------------------ .../creating-codesystems-for-dsf-processes.md | 42 - ...ng-task-resources-based-on-a-definition.md | 231 ------ .../creating-valuesets-for-dsf-processes.md | 63 -- docs/src/develop/guides/index.md | 17 - ...-incoming-messages-and-missing-messages.md | 18 - .../setting-targets-for-message-events.md | 14 - .../starting-a-process-via-task-resources.md | 43 - docs/src/develop/index.md | 47 -- 40 files changed, 2523 deletions(-) delete mode 100644 docs/src/develop/bpmn/conditions.md delete mode 100644 docs/src/develop/bpmn/gateways.md delete mode 100644 docs/src/develop/bpmn/index.md delete mode 100644 docs/src/develop/bpmn/messaging.md delete mode 100644 docs/src/develop/bpmn/sequence-flow.md delete mode 100644 docs/src/develop/bpmn/service-tasks.md delete mode 100644 docs/src/develop/bpmn/timer-intermediate-catching-events.md delete mode 100644 docs/src/develop/dsf/bpmn-process-execution.md delete mode 100644 docs/src/develop/dsf/bpmn-process-variables.md delete mode 100644 docs/src/develop/dsf/draft-task-resources.md delete mode 100644 docs/src/develop/dsf/environment-variables.md delete mode 100644 docs/src/develop/dsf/index.md delete mode 100644 docs/src/develop/dsf/message-correlation.md delete mode 100644 docs/src/develop/dsf/message-delegates.md delete mode 100644 docs/src/develop/dsf/organization-identifiers.md delete mode 100644 docs/src/develop/dsf/process-plugin-api.md delete mode 100644 docs/src/develop/dsf/process-plugin-definition.md delete mode 100644 docs/src/develop/dsf/read-access-tag.md delete mode 100644 docs/src/develop/dsf/requester-and-recipient.md delete mode 100644 docs/src/develop/dsf/service-delegates.md delete mode 100644 docs/src/develop/dsf/spring-framework-integration.md delete mode 100644 docs/src/develop/dsf/versions-placeholders-urls.md delete mode 100644 docs/src/develop/fhir/activitydefinition.md delete mode 100644 docs/src/develop/fhir/codesystem.md delete mode 100644 docs/src/develop/fhir/index.md delete mode 100644 docs/src/develop/fhir/task.md delete mode 100644 docs/src/develop/fhir/valueset.md delete mode 100644 docs/src/develop/guides/accessing-bpmn-process-variables.md delete mode 100644 docs/src/develop/guides/accessing-task-resources-during-execution.md delete mode 100644 docs/src/develop/guides/adding-task-input-parameters-to-task-profiles.md delete mode 100644 docs/src/develop/guides/configuring-read-access-tags.md delete mode 100644 docs/src/develop/guides/creating-activity-definitions.md delete mode 100644 docs/src/develop/guides/creating-codesystems-for-dsf-processes.md delete mode 100644 docs/src/develop/guides/creating-task-resources-based-on-a-definition.md delete mode 100644 docs/src/develop/guides/creating-valuesets-for-dsf-processes.md delete mode 100644 docs/src/develop/guides/index.md delete mode 100644 docs/src/develop/guides/managing-mutiple-incoming-messages-and-missing-messages.md delete mode 100644 docs/src/develop/guides/setting-targets-for-message-events.md delete mode 100644 docs/src/develop/guides/starting-a-process-via-task-resources.md delete mode 100644 docs/src/develop/index.md diff --git a/docs/src/develop/bpmn/conditions.md b/docs/src/develop/bpmn/conditions.md deleted file mode 100644 index 41447df07..000000000 --- a/docs/src/develop/bpmn/conditions.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -title: Conditions -icon: creative ---- - -### Conditions - -[Conditions](https://docs.camunda.org/manual/7.21/user-guide/process-engine/expression-language/#conditions) allow you to change the behaviour of BPMN processes during execution. There are two ways you are able to add decision logic to Conditions. The [Camunda Modeler](https://camunda.com/download/modeler/) refers to them as `Type`. You can find them in the ``Condition`` tab of certain BPMN elements. The first one is `Script`. This allows you to add arbitrary complexity to your decisions logic and is rarely used for process plugins. The more common Type is `Expression`. Expressions have the following syntax: `${expression}`. An example of a simple expression would be a boolean condition like `var == true`. For this to work during BPMN process execution, the variable you want to use for the boolean condition must be available in the BPMN process variables before [Sequence Flow](sequence-flow.md) reaches the evaluation of the expression. You can learn more advanced features of Expressions [here](https://docs.camunda.org/manual/7.21/user-guide/process-engine/expression-language/). \ No newline at end of file diff --git a/docs/src/develop/bpmn/gateways.md b/docs/src/develop/bpmn/gateways.md deleted file mode 100644 index 630b26ae0..000000000 --- a/docs/src/develop/bpmn/gateways.md +++ /dev/null @@ -1,16 +0,0 @@ ---- -title: Gateways -icon: creative ---- - -### Gateways - -[Gateways](https://docs.camunda.org/manual/7.21/reference/bpmn20/gateways/) allow you to control the [Sequence Flow](sequence-flow.md). Different types of gateways are useful for different scenarios. - -#### Exclusive Gateways - -[Exclusive Gateways](https://docs.camunda.org/manual/7.21/reference/bpmn20/gateways/exclusive-gateway/) allow you to decide which [Sequence Flow](sequence-flow.md) should be followed based on [conditions](https://docs.camunda.org/manual/7.21/user-guide/process-engine/expression-language/#conditions). [Conditions](https://docs.camunda.org/manual/7.21/user-guide/process-engine/expression-language/#conditions) are not part of the [Exclusive Gateways](https://docs.camunda.org/manual/7.21/reference/bpmn20/gateways/exclusive-gateway/) themselves. You set them through the sequence flow exiting the [Exclusive Gateway](https://docs.camunda.org/manual/7.21/reference/bpmn20/gateways/exclusive-gateway/). In the [Camunda Modeler](https://camunda.com/download/modeler/), you can add conditions to [Sequence Flow](sequence-flow.md) by selecting a [Sequence Flow](sequence-flow.md) and opening the `Condition` tab. You can find more information on how to use Conditions [here](conditions.md). - -#### Event-based Gateway - -The [Event-based Gateway](https://docs.camunda.org/manual/7.21/reference/bpmn20/gateways/event-based-gateway/) allows you model scenarios where you are expecting one out of a number of events to occur. \ No newline at end of file diff --git a/docs/src/develop/bpmn/index.md b/docs/src/develop/bpmn/index.md deleted file mode 100644 index d74ae074d..000000000 --- a/docs/src/develop/bpmn/index.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -title: BPMN -icon: creative ---- - -## Introduction -The DSF uses BPMN 2.0 to model processes. Specifically, the [Camunda 7](https://docs.camunda.org/manual/7.21/) dialect from the [Camunda Modeler](https://camunda.com/de/download/modeler/). Modeling processes for the DSF requires this modeler or any other modeler which is able to produce the correct Camunda dialect. - -## Details -- [Conditions](conditions.md) -- [Gateways](gateways.md) -- [Messaging](messaging.md) -- [Sequence Flow](sequence-flow.md) -- [Service Tasks](service-tasks.md) -- [Timer Intermediate Catching Events](timer-intermediate-catching-events.md) \ No newline at end of file diff --git a/docs/src/develop/bpmn/messaging.md b/docs/src/develop/bpmn/messaging.md deleted file mode 100644 index 97d05703b..000000000 --- a/docs/src/develop/bpmn/messaging.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -title: Messaging -icon: creative ---- - - -### Messaging - -In order to enable communication with other lanes, pools or even entirely separate processes you need to be able to exchange information. In BPMN, you can use [Message Events](https://docs.camunda.org/manual/7.21/reference/bpmn20/events/message-events/) to model this information exchange. Modeling communication with [Message Events](https://docs.camunda.org/manual/7.21/reference/bpmn20/events/message-events/) in the same diagram uses Message Flow. Message Flow is typically represented by a dashed line arrow between BPMN elements with a black (send) or white (receive) envelope icon. The following BPMN collaboration diagram shows message exchange between two processes. - -![BPMN collaboration diagram with two processes using message flow to exchange information between two organizations](/photos/developer-documentation/message_flow.svg) - -#### Message Start Event - -[Message Start Events](https://docs.camunda.org/manual/7.21/reference/bpmn20/events/message-events/#message-start-event) allow a BPMN process to be started by an incoming message. In the DSF, all BPMN processes are started via messages. Therefore, you will have to include a [Message Start Event](https://docs.camunda.org/manual/7.21/reference/bpmn20/events/message-events/#message-start-event) at the beginning of all of your BPMN models. - -#### Message Intermediate Throwing Event -[Message Intermediate Throwing Events](https://docs.camunda.org/manual/7.21/reference/bpmn20/events/message-events/#message-intermediate-throwing-event) are used to send messages during process execution. - -#### Message Intermediate Catching Event -[Message Intermediate Catching Events](https://docs.camunda.org/manual/7.21/reference/bpmn20/events/message-events/#message-intermediate-catching-event) serve as the counterpart to [Message Intermediate Throwing Events](messaging.md#message-intermediate-throwing-event). Use them whenever you expect to receive a message from another process or organization during execution. - -#### Message End Event -The [Message End Event](https://docs.camunda.org/manual/7.21/reference/bpmn20/events/message-events/#message-end-event) will stop the execution of a BPMN process and finish by sending a message. \ No newline at end of file diff --git a/docs/src/develop/bpmn/sequence-flow.md b/docs/src/develop/bpmn/sequence-flow.md deleted file mode 100644 index 3650cc635..000000000 --- a/docs/src/develop/bpmn/sequence-flow.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -title: Sequence Flow -icon: creative ---- - -### Sequence Flow -BPMN 2.0 calls the continuous arrows connecting the BPMN elements in BPMN models, Sequence Flow. Sequence Flow exits one BPMN element and points at the next BPMN element to be processed. diff --git a/docs/src/develop/bpmn/service-tasks.md b/docs/src/develop/bpmn/service-tasks.md deleted file mode 100644 index ebe8ad3c9..000000000 --- a/docs/src/develop/bpmn/service-tasks.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -title: Service Tasks -icon: creative ---- - -### Service Tasks - -One of the most common types of BPMN Tasks used for modeling DSF processes is the [Service Task](https://docs.camunda.org/manual/7.21/reference/bpmn20/tasks/service-task/). They are different from regular BPMN Tasks in that they offer the ability to link an implementation to the [Service Task](https://docs.camunda.org/manual/7.21/reference/bpmn20/tasks/service-task/) which can be called and executed by a BPMN engine. The BPE (Business Process Engine) server of the DSF leverages this engine to execute your BPMN processes. \ No newline at end of file diff --git a/docs/src/develop/bpmn/timer-intermediate-catching-events.md b/docs/src/develop/bpmn/timer-intermediate-catching-events.md deleted file mode 100644 index 49ab4a8fc..000000000 --- a/docs/src/develop/bpmn/timer-intermediate-catching-events.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -title: Timer Intermediate Catching Events -icon: creative ---- - -### Timer Intermediate Catching Events - -A [Timer Intermediate Catching Event](https://docs.camunda.org/manual/7.21/reference/bpmn20/events/timer-events/#timer-intermediate-catching-event) allows you to model stopwatch behavior. A timer is started once the BPMN execution arrives at the event. The duration until the timer runs out is specified using the [ISO 8601 Durations](http://en.wikipedia.org/wiki/ISO_8601#Durations) format. Examples can be found [here](https://docs.camunda.org/manual/7.21/reference/bpmn20/events/timer-events/#time-duration). After running out, the BPMN process executes the [Sequence Flow](sequence-flow.md) following the [Timer Intermediate Catching Event](https://docs.camunda.org/manual/7.21/reference/bpmn20/events/timer-events/#timer-intermediate-catching-event). \ No newline at end of file diff --git a/docs/src/develop/dsf/bpmn-process-execution.md b/docs/src/develop/dsf/bpmn-process-execution.md deleted file mode 100644 index 8884106e0..000000000 --- a/docs/src/develop/dsf/bpmn-process-execution.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -title: BPMN Process Execution -icon: creative ---- - -### BPMN Process Execution - -The BPMN process execution is the in-memory representation of a running BPMN process. BPMN processes have their executions structured as a tree hierarchy. Each BPMN process starts with the [process instance](https://docs.camunda.org/manual/7.21/user-guide/process-engine/process-engine-concepts/#process-instances) as its root level execution. If, for example, this root execution reaches a parallel gateway with two paths, it would spawn two child executions under itself for them to process all tasks along their paths on their own. Executions can access all the BPMN elements from the BPMN model as well as the [BPMN process variables](bpmn-process-variables.md). You have access to this representation in your Java code through the `execution` parameter when overriding certain methods in [Service](service-delegates.md) / [Message](message-delegates.md) Delegates like `doExecute` or `getAdditionalInputParameters`. \ No newline at end of file diff --git a/docs/src/develop/dsf/bpmn-process-variables.md b/docs/src/develop/dsf/bpmn-process-variables.md deleted file mode 100644 index 6170e1b1e..000000000 --- a/docs/src/develop/dsf/bpmn-process-variables.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -title: BPMN Process Variables -icon: creative ---- - -### BPMN Process Variables - -BPMN process variables hold additional information which has to be available during BPMN process execution. Variables can be directly related to BPMN elements like the boolean value for [Conditions](../bpmn/conditions.md), but do not have to be. BPMN process variables are stored as key-value pairs with the key being the variable name. They are accessible during the entirety of the execution to all [Service](service-delegates.md) / [Message](message-delegates.md) Delegates. - -You can learn how to access to the BPMN process variables [here](../guides/accessing-bpmn-process-variables.md). \ No newline at end of file diff --git a/docs/src/develop/dsf/draft-task-resources.md b/docs/src/develop/dsf/draft-task-resources.md deleted file mode 100644 index c1bcaa28c..000000000 --- a/docs/src/develop/dsf/draft-task-resources.md +++ /dev/null @@ -1,21 +0,0 @@ ---- -title: Draft Task Resources -icon: creative ---- - -### Draft Task Resources - -[Task](../fhir/task.md) resources with status `draft` are used to create the DSF FHIR server's functionality of starting processes via its web interface. They are stored in `.../tutorial-process/src/main/resources/fhir/Task`. Compared to regular [Task](../fhir/task.md) resources used to start BPMN processes, this type of [Task](../fhir/task.md) resource requires the status `draft` instead the usual `requested`. It also replaces the value for `authoredOn` with the placeholder `#{date}`, the values of organization identifiers with the placeholder `#{organization}` and all instances of version numbers with `#{version}`. Additionally, it requires setting the `Task.identifier` element. It should look something like this: - -```xml -<identifier> - <system value="http://dsf.dev/sid/task-identifier" /> - <value value="http://dsf.dev/bpe/Process/processKey/#{version}/task-name" /> -</identifier> -``` -`processKey` should be the same one used in [URLs](versions-placeholders-urls.md#urls). -`task-name` can be any String you wish to identify this task with. E.g. you can use the file name of the Draft Task. - -For a complete example you can take a look at the Draft Task Resource in one of the solution branches and compare it to the one needed for cURL. The [Task](../fhir/task.md) resource created for cURL can be found at `.../tutorial-process/src/main/resources/example-task.xml`. - -You might also want to check out [this guide](../guides/creating-task-resources-based-on-a-definition.md) if you do not know how to create [Task](../fhir/task.md) resources in general. \ No newline at end of file diff --git a/docs/src/develop/dsf/environment-variables.md b/docs/src/develop/dsf/environment-variables.md deleted file mode 100644 index fcea6697c..000000000 --- a/docs/src/develop/dsf/environment-variables.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -title: Environment Variables -icon: creative ---- - -### Environment Variables - -Environment variables offer a way to make configuration data available at the start of a [BPMN process execution](bpmn-process-execution.md). They are the same for all running process instances. They can be defined by adding a member variable with the [Spring-Framework @Value](https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#beans-value-annotations) annotation to the configuration class `TutorialConfig`. The value of the annotation uses the `${..}` notation and follows the form `${some.property:defaultValue}`, where each dot in the property name corresponds to an underscore in the equivalent environment variable. Environment variables are always written upper-case. The property `some.property` therefore corresponds to the environment variable `SOME_PROPERTY`. - -The DSF provides a feature to automatically generate documentation of environment variables during the Maven build process. You can use the `@ProcessDocumentation` annotation to automatically generate Markdown documentation for all fields with this annotation. You simply have to add [dsf-tools-documentation-generator](https://mvnrepository.com/artifact/dev.dsf/dsf-tools-documentation-generator) as a maven plugin. You can take a look at the `pom.xml` for the `tutorial-process` submodule [here](https://github.com/datasharingframework/dsf-process-tutorial/blob/main/tutorial-process/pom.xml) to see how you can add it to your own project. Keep in mind to point the `<workingPackage>` field to the package you want documentation for. \ No newline at end of file diff --git a/docs/src/develop/dsf/index.md b/docs/src/develop/dsf/index.md deleted file mode 100644 index f70d7104e..000000000 --- a/docs/src/develop/dsf/index.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -title: DSF -icon: creative ---- - -## Details -- [BPMN Process Execution](bpmn-process-execution.md) -- [BPMN Process Variables](bpmn-process-variables.md) -- [Draft Task Resources](draft-task-resources.md) -- [Environment Variables](environment-variables.md) -- [Message Correlation](message-correlation.md) -- [Message Delegates](message-delegates.md) -- [Organization Identifiers](organization-identifiers.md) -- [Process Plugin API](process-plugin-api.md) -- [Process Plugin Definition](process-plugin-definition.md) -- [Read Access Tag](read-access-tag.md) -- [Requester and Recipient](requester-and-recipient.md) -- [Service Delegates](service-delegates.md) -- [Spring Framework Integration](spring-framework-integration.md) -- [Versions, Placeholders and URLs](versions-placeholders-urls.md) \ No newline at end of file diff --git a/docs/src/develop/dsf/message-correlation.md b/docs/src/develop/dsf/message-correlation.md deleted file mode 100644 index 23b18e3e3..000000000 --- a/docs/src/develop/dsf/message-correlation.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -title: Message Correlation -icon: creative ---- - -### Message Correlation - -In order for messages to be able to be sent back and forth between organizations with potentially multiple of the same process plugin instances running at the same time and still arriving at the correct process instance, we need some mechanism to map messages to their rightful process instance. This mechanism is called Message Correlation and requires attaching a unique identifier to every process instance. This identifier is called the `business-key`. The `business-key` will get attached to every outgoing message automatically. - -It is possible that the `business-key` is insufficient to map messages to the correct process instance. This happens when you use subprocesses in your BPMN model which all expect messages to be sent to them, not the parent process. To solve this issue, [Task](../fhir/task.md) resources also come with an [Input Parameter](../fhir/task.md#task-input-parameters) called `correlation-key`. This is a secondary identifier you can attach to all messages if you need them to arrive at a specific subprocess. You can learn more about how `correlation-keys` are used by studying the [Ping-Pong Process](https://github.com/datasharingframework/dsf-process-ping-pong). \ No newline at end of file diff --git a/docs/src/develop/dsf/message-delegates.md b/docs/src/develop/dsf/message-delegates.md deleted file mode 100644 index 61a1a06f1..000000000 --- a/docs/src/develop/dsf/message-delegates.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -title: Message Delegates -icon: creative ---- - -### Message Delegates - -Message Delegates are the Java representation of the [Message Events](../bpmn/messaging.md) in your BPMN model. You link a Message Delegate to a certain [Message Event](../bpmn/messaging.md) by selecting the Message Event in the [Camunda Modeler](https://camunda.com/download/modeler/) and adding a Java class to the `Implementation` field. Make sure you use the fully qualified class name. Like this: -``` -org.package.myClass -``` - -You will only need Message Delegates for [Message Send Events](../bpmn/messaging.md). Incoming messages will be resolved to the correct [BPMN process execution](bpmn-process-execution.md) automatically using [Message Correlation](message-correlation.md) and the message inputs will be added to that execution's [process variables](bpmn-process-variables.md). - -To make a Message Delegate for [Message Send Events](../bpmn/messaging.md), your Java class needs to extend `AbstractTaskMessageSend`. Most of the time, you will not be adding any processing logic to your Message Delegates, therefore you usually won't be overwriting the `doExecute` method like with [Service Delegates](service-delegates.md). Instead, you most likely want to aggregate the information you processed in earlier steps and attach it to a message. For this you need to overwrite the `getAdditionalInputParamters` method. The DSF translates BPMN messages into FHIR [Task](../fhir/task.md) resources to execute the communication modeled by your BPMN diagrams. The information you are sending to another BPMN process is specified in the Task.input elements a.k.a. [Input Parameters](../fhir/task.md#task-input-parameters), hence the name of the method. The constructor of your delegate class should also forward a `ProcessPluginApi` instance to its superclass constructor. You can learn more about the `ProcessPluginApi` [here](process-plugin-api.md). diff --git a/docs/src/develop/dsf/organization-identifiers.md b/docs/src/develop/dsf/organization-identifiers.md deleted file mode 100644 index 70d143150..000000000 --- a/docs/src/develop/dsf/organization-identifiers.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -title: Organization Identifiers -icon: creative ---- - -### Organization Identifiers -DSF FHIR server instances always have something called an `organization identifer`. It uniquely identifies the organization the DSF FHIR server instance belongs to for its [Allow-List mechanism](https://dsf.dev/intro/info/allowList.html). It is configured as an [environment variable](https://dsf.dev/stable/maintain/fhir/configuration.html#dev-dsf-fhir-server-organization-identifier-value). You can make a GET request to `https://domain/fhir/Organization` to get a list of all organizations for the DSF FHIR server instance running under `domain`. The results will also include the `organization identifier` of each organization. - -#### Organization Identifiers in Task Resources -[Task](../fhir/task.md) resources require you to reference an organization via its identifier as the `Task.requester` and `Task.restriction.recipient` elements. The exact values for these elements depend on the [ActivityDefinition](../fhir/activitydefinition.md) the [Task](../fhir/task.md) resource should conform to. As a general rule, you will want to put the identifier of your own organization as the `Task.requester` and `Task.restriction.recipient` elements for [Task](../fhir/task.md) resources which initially start processes. All other cases depend on the context of the message being sent during process execution. \ No newline at end of file diff --git a/docs/src/develop/dsf/process-plugin-api.md b/docs/src/develop/dsf/process-plugin-api.md deleted file mode 100644 index 5d1381a5a..000000000 --- a/docs/src/develop/dsf/process-plugin-api.md +++ /dev/null @@ -1,32 +0,0 @@ ---- -title: Process Plugin API -icon: creative ---- - -### Process Plugin API v1 Maven Module - -The [DSF Process Plugin API module](https://mvnrepository.com/artifact/dev.dsf/dsf-bpe-process-api-v1) consists of a set of utility classes designed to provide easy access to solutions for process plugin use cases. This includes for example the `Variables` class, which provides access to the [BPMN process variables](bpmn-process-variables.md). - -Maven Dependency: - -```xml -<dependencies> - <dependency> - <groupId>dev.dsf</groupId> - <artifactId>dsf-bpe-process-api-v1</artifactId> - <version>${dsf.version}</version> - <scope>provided</scope> - </dependency> -</dependencies> -``` - -#### Process Plugin Api -When creating [Service Delegates](service-delegates.md) or [Message Delegates](message-delegates.md) you wil notice that you need to provide a constructor which expects a `ProcessPluginApi` object and forward it to the superclasses' constructor. -This API instance provides a variety of utility classes: -- `ProxyConfig`**:** forward proxy configuration -- `EndpointProvider`**:** access to Endpoint resources -- `FhirContext`**:** HAPI FHIR Context for parsing/serializing -- `FhirWebserviceClientProvider`**:** Webservice client to access DSF FHIR server -- `MailService`**:** for sending automatic E-Mails (if configured) -- `OrganizationProvider`**:** access to Organization resources -- `Variables`**:** access to BPMN execution variables \ No newline at end of file diff --git a/docs/src/develop/dsf/process-plugin-definition.md b/docs/src/develop/dsf/process-plugin-definition.md deleted file mode 100644 index a13bdbe26..000000000 --- a/docs/src/develop/dsf/process-plugin-definition.md +++ /dev/null @@ -1,16 +0,0 @@ ---- -title: Process Plugin Definition -icon: creative ---- - -### Process Plugin Definition - -In order for the DSF BPE server to load your plugin you need to provide it with the following information: -* A plugin [version](versions-placeholders-urls.md#version-pattern) -* A release date -* A plugin name -* The BPMN model files -* The FHIR resources grouped by BPMN process ID. Your plugin may have any number of BPMN models. Each has their own BPMN process ID and FHIR resources specific to that BPMN process (think [Task](../fhir/task.md) resources needed for messages specific to that BPMN model) -* The Class holding your [Spring Framework Configuration](spring-framework-integration.md) - -You will provide this information by implementing the `dev.dsf.bpe.ProcessPluginDefinition` interface. The DSF BPE server then searches for classes implementing this interface using the Java [ServiceLoader](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/ServiceLoader.html) mechanism. Therefore, you will have to register your interface implementation in the `src/main/resources/META-INF/services/dev.dsf.bpe.ProcessPluginDefinition` file. For this tutorial, the class implementing the `ProcessPluginDefinition` interface, `TutorialProcessPluginDefinition`, has already been added to the file. You can use it as a reference for later when you want to create your own plugin. \ No newline at end of file diff --git a/docs/src/develop/dsf/read-access-tag.md b/docs/src/develop/dsf/read-access-tag.md deleted file mode 100644 index 47a02b2c1..000000000 --- a/docs/src/develop/dsf/read-access-tag.md +++ /dev/null @@ -1,22 +0,0 @@ ---- -title: Read Access Tag -icon: creative ---- - -### Read Access Tag - -Axiomatically, nobody is allowed to write FHIR resources (except [Task](../fhir/task.md)) to the DSF FHIR server unless it is your own organization. By default, the same applies to reading FHIR resources (again except [Task](../fhir/task.md)). But since the DSF is often used to offer medical data in form of FHIR resources, you will find yourself wanting other organizations to be allowed to read the resources you are offering. The `Resource.meta.tag` element is used define access rules for all FHIR resources in the DSF, with the exception of [Task](../fhir/task.md) resources. We will explain the reason for this exception shortly. For example, allowing read access for all organizations, you would use the following `system` and `code` in your FHIR resource: - -```xml -<meta> - <tag> - <system value="http://dsf.dev/fhir/CodeSystem/read-access-tag" /> - <code value="ALL" /> - </tag> -</meta> -``` -You can find all codes for the Read Access Tag in its [CodeSystem](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/CodeSystem/dsf-read-access-tag-1.0.0.xml). - -The read access rules for [Task](../fhir/task.md) resources are defined through the `requester` and `recipient` elements of the [dsf-extension-process-authorization](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-extension-process-authorization-1.0.0.xml) in your plugin's [ActivityDefinitions](../fhir/activitydefinition.md). Therefore, no `read-access-tag` is needed. - -It is also possible to restrict read access of FHIR resources to organizations with a specific role in a parent organization or a specific identifier. If you want to find out more, you may look at the [guide on configuring the Read Access Tag](../guides/configuring-read-access-tags.md). diff --git a/docs/src/develop/dsf/requester-and-recipient.md b/docs/src/develop/dsf/requester-and-recipient.md deleted file mode 100644 index 8407bb318..000000000 --- a/docs/src/develop/dsf/requester-and-recipient.md +++ /dev/null @@ -1,250 +0,0 @@ ---- -title: Requester and Recipient -icon: creative ---- - -### Requester and Recipient Elements - -Below you will find a set of examples for each Coding used by `requester` and `recipient` elements from the [dsf-extension-process-authorization](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-extension-process-authorization-1.0.0.xml). CodeSystems referenced in the examples can be found [here](https://github.com/datasharingframework/dsf/tree/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/CodeSystem). Use this collection as a reference point when creating your own [ActivityDefinitions](../fhir/activitydefinition.md). - -#### Requester -The `requester` element uses one of the following Codings: -```xml -<profile value="http://dsf.dev/fhir/StructureDefinition/coding-process-authorization-local-all|1.0.0" /> -<profile value="http://dsf.dev/fhir/StructureDefinition/coding-process-authorization-local-all-practitioner|1.0.0" /> -<profile value="http://dsf.dev/fhir/StructureDefinition/coding-process-authorization-local-organization|1.0.0" /> -<profile value="http://dsf.dev/fhir/StructureDefinition/coding-process-authorization-local-organization-practitioner|1.0.0" /> -<profile value="http://dsf.dev/fhir/StructureDefinition/coding-process-authorization-local-parent-organization-role|1.0.0" /> -<profile value="http://dsf.dev/fhir/StructureDefinition/coding-process-authorization-local-parent-organization-role-practitioner|1.0.0" /> -<profile value="http://dsf.dev/fhir/StructureDefinition/coding-process-authorization-remote-all|1.0.0" /> -<profile value="http://dsf.dev/fhir/StructureDefinition/coding-process-authorization-remote-organization|1.0.0" /> -<profile value="http://dsf.dev/fhir/StructureDefinition/coding-process-authorization-remote-parent-organization-role|1.0.0" /> -``` - -##### Local All -```xml -<extension url="requester"> - <valueCoding> - <system value="http://dsf.dev/fhir/CodeSystem/process-authorization" /> - <code value="LOCAL_ALL" /> - </valueCoding> -</extension> -``` - -##### Local All Practitioner -```xml -<extension url="requester"> - <valueCoding> - <extension url="http://dsf.dev/fhir/StructureDefinition/extension-process-authorization-practitioner"> - <valueCoding> - <system value="http://dsf.dev/fhir/CodeSystem/practitioner-role"/> - <code value="DSF_ADMIN"/> <!-- example, replace appropriately --> - </valueCoding> - </extension> - <system value="http://dsf.dev/fhir/CodeSystem/process-authorization" /> - <code value="LOCAL_ALL_PRACTITIONER" /> - </valueCoding> -</extension> -``` - -##### Local Organization -```xml -<extension url="requester"> - <valueCoding> - <extension url="http://dsf.dev/fhir/StructureDefinition/extension-process-authorization-organization"> - <valueIdentifier> - <system value="http://dsf.dev/sid/organization-identifier"/> - <value value="My_Organization"/> <!-- example, replace appropriately --> - </valueIdentifier> - </extension> - <system value="http://dsf.dev/fhir/CodeSystem/process-authorization" /> - <code value="LOCAL_ORGANIZATION" /> - </valueCoding> -</extension> -``` - -##### Local Organization Practitioner -```xml -<extension url="requester"> - <valueCoding> - <extension url="http://dsf.dev/fhir/StructureDefinition/extension-process-authorization-organization-practitioner"> - <extension url="organization"> - <valueIdentifier> - <system value="http://dsf.dev/sid/organization-identifier"/> - <value value="My_Organization"/> <!-- example, replace appropriately --> - </valueIdentifier> - </extension> - <extension url="practitioner-role"> - <valueCoding> - <system value="http://dsf.dev/fhir/CodeSystem/practitioner-role"/> - <code value="DSF_ADMIN"/> <!-- example, replace appropriately --> - </valueCoding> - </extension> - </extension> - <system value="http://dsf.dev/fhir/CodeSystem/process-authorization" /> - <code value="LOCAL_ORGANIZATION_PRACTITIONER" /> - </valueCoding> -</extension> -``` - -##### Local Parent Organization Role -```xml -<extension url="requester"> - <valueCoding> - <extension url="http://dsf.dev/fhir/StructureDefinition/extension-process-authorization-parent-organization-role"> - <extension url="parent-organization"> - <valueIdentifier> - <system value="http://dsf.dev/sid/organization-identifier"/> - <value value="My_Parent_Organization"/> <!-- example, replace appropriately --> - </valueIdentifier> - </extension> - <extension url="organization-role"> - <valueCoding> - <system value="http://dsf.dev/fhir/CodeSystem/organization-role"/> - <code value="DIC"/> <!-- example, replace appropriately --> - </valueCoding> - </extension> - </extension> - <system value="http://dsf.dev/fhir/CodeSystem/process-authorization" /> - <code value="LOCAL_ROLE" /> - </valueCoding> -</extension> -``` - -##### Local Parent Organization Role Practitioner -```xml -<extension url="requester"> - <valueCoding> - <extension url="http://dsf.dev/fhir/StructureDefinition/extension-process-authorization-parent-organization-role-practitioner"> - <extension url="parent-organization"> - <valueIdentifier> - <system value="http://dsf.dev/sid/organization-identifier"/> - <value value="My_Parent_Organization"/> <!-- example, replace appropriately --> - </valueIdentifier> - </extension> - <extension url="organization-role"> - <valueCoding> - <system value="http://dsf.dev/fhir/CodeSystem/organization-role"/> - <code value="DIC"/> <!-- example, replace appropriately --> - </valueCoding> - </extension> - <extension url="practitioner-role"> - <valueCoding> - <system value="http://dsf.dev/fhir/CodeSystem/practitioner-role"/> - <code value="DSF_ADMIN"/> <!-- example, replace appropriately --> - </valueCoding> - </extension> - </extension> - <system value="http://dsf.dev/fhir/CodeSystem/process-authorization" /> - <code value="LOCAL_ROLE_PRACTITIONER" /> - </valueCoding> -</extension> -``` - -##### Remote All -```xml -<extension url="requester"> - <valueCoding> - <system value="http://dsf.dev/fhir/CodeSystem/process-authorization" /> - <code value="REMOTE_ALL" /> - </valueCoding> -</extension> -``` - -##### Remote Organization -```xml -<extension url="requester"> - <valueCoding> - <extension url="http://dsf.dev/fhir/StructureDefinition/extension-process-authorization-organization"> - <valueIdentifier> - <system value="http://dsf.dev/sid/organization-identifier"/> - <value value="My_Organization"/> <!-- example, replace appropriately --> - </valueIdentifier> - </extension> - <system value="http://dsf.dev/fhir/CodeSystem/process-authorization" /> - <code value="REMOTE_ORGANIZATION" /> - </valueCoding> -</extension> -``` - -##### Remote Parent Organization Role -```xml -<extension url="requester"> - <valueCoding> - <extension url="http://dsf.dev/fhir/StructureDefinition/extension-process-authorization-parent-organization-role"> - <extension url="parent-organization"> - <valueIdentifier> - <system value="http://dsf.dev/sid/organization-identifier"/> - <value value="My_Parent_Organization"/> <!-- example, replace appropriately --> - </valueIdentifier> - </extension> - <extension url="organization-role"> - <valueCoding> - <system value="http://dsf.dev/fhir/CodeSystem/organization-role"/> - <code value="DIC"/> <!-- example, replace appropriately --> - </valueCoding> - </extension> - </extension> - <system value="http://dsf.dev/fhir/CodeSystem/process-authorization" /> - <code value="REMOTE_ROLE" /> - </valueCoding> -</extension> -``` - -#### Recipient -The `recipeint` element uses one of the following Codings: -```xml -<profile value="http://dsf.dev/fhir/StructureDefinition/coding-process-authorization-local-all|1.0.0" /> -<profile value="http://dsf.dev/fhir/StructureDefinition/coding-process-authorization-local-organization|1.0.0" /> -<profile value="http://dsf.dev/fhir/StructureDefinition/coding-process-authorization-local-parent-organization-role|1.0.0" /> -``` - -##### Local All -```xml -<extension url="recipient"> - <valueCoding> - <system value="http://dsf.dev/fhir/CodeSystem/process-authorization" /> - <code value="LOCAL_ALL" /> - </valueCoding> -</extension> -``` - -##### Local Organization -```xml -<extension url="recipient"> - <valueCoding> - <extension url="http://dsf.dev/fhir/StructureDefinition/extension-process-authorization-organization"> - <valueIdentifier> - <system value="http://dsf.dev/sid/organization-identifier"/> - <value value="My_Organization"/> <!-- example, replace appropriately --> - </valueIdentifier> - </extension> - <system value="http://dsf.dev/fhir/CodeSystem/process-authorization" /> - <code value="LOCAL_ORGANIZATION" /> - </valueCoding> -</extension> -``` - -##### Local Parent Organization Role -```xml -<extension url="recipient"> - <valueCoding> - <extension url="http://dsf.dev/fhir/StructureDefinition/extension-process-authorization-parent-organization-role"> - <extension url="parent-organization"> - <valueIdentifier> - <system value="http://dsf.dev/sid/organization-identifier"/> - <value value="My_Parent_Organization"/> <!-- example, replace appropriately --> - </valueIdentifier> - </extension> - <extension url="organization-role"> - <valueCoding> - <system value="http://dsf.dev/fhir/CodeSystem/organization-role"/> - <code value="DIC"/> <!-- example, replace appropriately --> - </valueCoding> - </extension> - </extension> - <system value="http://dsf.dev/fhir/CodeSystem/process-authorization" /> - <code value="LOCAL_ROLE" /> - </valueCoding> -</extension> -``` diff --git a/docs/src/develop/dsf/service-delegates.md b/docs/src/develop/dsf/service-delegates.md deleted file mode 100644 index 278b51e34..000000000 --- a/docs/src/develop/dsf/service-delegates.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -title: Service Delegates -icon: creative ---- - -### Service Delegates - -Service Delegates are the Java representation of the [Service Tasks](../bpmn/service-tasks.md) in your BPMN model. You link a Service Delegate to a certain [Service Task](../bpmn/service-tasks.md) by selecting the [Service Task](../bpmn/service-tasks.md) in the [Camunda Modeler](https://camunda.com/download/modeler/) and adding a Java class to the `Implementation` field. Make sure you use the fully qualified class name. Like this: -``` -org.package.myClass -``` -All that is left is for your Java class to extend `AbstractServiceDelegate` and override the `doExecute` method. This is the place where you can put your actual business logic. The method will be called when the [BPMN process execution](bpmn-process-execution.md) arrives at the [Service Task](../bpmn/service-tasks.md) your Service Delegate is linked to. The constructor of your delegate class should also forward a `ProcessPluginApi` instance to its superclass constructor. You can learn more about the `ProcessPluginApi` [here](process-plugin-api.md). \ No newline at end of file diff --git a/docs/src/develop/dsf/spring-framework-integration.md b/docs/src/develop/dsf/spring-framework-integration.md deleted file mode 100644 index 55f96f342..000000000 --- a/docs/src/develop/dsf/spring-framework-integration.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -title: Spring Framework Integration -icon: creative ---- - -### Spring Framework Integration - -Since the DSF also employs the use of the [Spring Framework](https://spring.io/projects/spring-framework) you will also have to provide some Spring functionality. When deployed, every process plugin exists in its own [Spring context](https://docs.spring.io/spring-framework/reference/core/beans/introduction.html). To make the process plugin work, you have to provide [Spring Beans](https://docs.spring.io/spring-framework/reference/core/beans/definition.html) with `prototype` [scope](https://docs.spring.io/spring-framework/reference/core/beans/factory-scopes.html) for all classes which either extend or implement the following classes/interfaces (as of version 1.4.0): -- `AbstractTaskMessageSend` -- `AbstractServiceDelegate` -- `DefaultUserTaskListener` -- `ProcessPluginDeploymentStateListener` - -A [Spring-Framework configuration class](https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#beans-java-basic-concepts) located in `spring/config` is expected to provide the Spring Beans. For this tutorial, the `TutorialConfig` class will take this role. If you are unfamiliar with the Spring Framework, you might want to check out the chapter [Java-based Container Configuration](https://docs.spring.io/spring-framework/reference/core/beans/java.html) of the Spring Framework documentation, specifically the topics [Using the @Bean Annotation](https://docs.spring.io/spring-framework/reference/core/beans/java/bean-annotation.html) and [Using the @Configuration Annotation](https://docs.spring.io/spring-framework/reference/core/beans/java/configuration-annotation.html). \ No newline at end of file diff --git a/docs/src/develop/dsf/versions-placeholders-urls.md b/docs/src/develop/dsf/versions-placeholders-urls.md deleted file mode 100644 index 0381ec629..000000000 --- a/docs/src/develop/dsf/versions-placeholders-urls.md +++ /dev/null @@ -1,38 +0,0 @@ ---- -title: Versions, Placeholders and URLs -icon: creative ---- - -### Versions, Placeholders and URLs - -#### Version Pattern - -Process plugin versions have to obey the pattern: -``` -\d+\.\d+\.\d+\.\d+ Example: 1.2.3.4 -``` - -The first two numbers (`1.2`) are used in FHIR resources and signal changes which break compatibility with previous process versions. For example, altering FHIR resources usually results in a breaking change. The latter two (`3.4`) signal changes which do not break compatibility with previous process versions. Specifically, the 4th number is reserved for bug-fixes and the 3rd number includes all other non-breaking changes. - -#### Placeholders - -To avoid specifying the version and release date in multiple files, the placeholders `#{version}` and `#{date}` can be used within FHIR resources and BPMN models. They are replaced with the values returned by the methods `ProcessPluginDefinition#getResourceVersion` and `ProcessPluginDefinition#getReleaseDate` respectively during deployment of a process plugin by the DSF BPE server. There is also a placeholder for the organization the DSF instance is running in: `#{organization}`, typically use in [Draft Task Resources](draft-task-resources.md). - -#### URLs - -BPMN models have an ID call process definition key. The BPMN process definition key needs to be specified following the pattern: -``` -^[-a-zA-Z0-9]+_[-a-zA-Z0-9]+$ Example: domainorg_processKey -``` -In addition, the BPMN model needs to specify a version. You should be using the ``#{version}`` [placeholder](#placeholders) for this as well. The DSF will also reference this process in URL form in FHIR resources: -``` -http://domain.org/bpe/Process/processKey|1.2 -``` - -As you can see, the version in the URL ``|1.2`` only uses the resource version and omits the code base version. As mentioned in [Version Pattern](#version-pattern), this means that only changes to the first two version numbers are significant to signal compatibility when communicating with other process plugin instances. The process definition key and URL are also related to each other. The DSF will try to match BPMN models to FHIR resources by transforming the URL into a process definition key. That is why it is important you obey the pattern above. - -You will use the above URL as your instantiatesCanonical value for [Task](../fhir/task.md) profile definitions as well as references to [Task](../fhir/task.md) profiles in other resources. You will also use it as the URL value for your [ActivityDefinitions](../fhir/activitydefinition.md). In this case though, you have to split up the URL into two parts. You will separate the version (``|1.2``) from the URL and use it as a value for the `ActivityDefinition.version` element. Since it refers to the plugin's resource version, you should also use the `#{version}` [placeholder](#placeholders) here instead. Going by the example from above, you will be left with a URL that looks like this: -``` -http://domain.org/bpe/Process/processKey -``` -This will be the value for your `ActivityDefinition.url` element with `#{version}` as the value for your `ActivityDefinition.version` element. \ No newline at end of file diff --git a/docs/src/develop/fhir/activitydefinition.md b/docs/src/develop/fhir/activitydefinition.md deleted file mode 100644 index 5cd27ca91..000000000 --- a/docs/src/develop/fhir/activitydefinition.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -title: ActivityDefinition -icon: creative ---- - -### ActivityDefinition - -[ActivityDefinitions](http://hl7.org/fhir/R4/activitydefinition.html) are used by the DSF to advertise which processes are available at any given instance and who is allowed to request and who is allowed to execute a process. The DSF defined elements for this purpose in the [dsf-activity-definition](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-activity-definition-1.0.0.xml) profile. - - -The most important elements in ActivityDefinitions are: -- `message-name` -- `task-profile` -- `requester` -- `recipient` - -The `message-name` element contains the name of the [BPMN message start event](../bpmn/messaging.md#message-start-event) or [BPMN message intermediate catching event](../bpmn/messaging.md#message-intermediate-catching-event) which expects a [Task](task.md) resource complying to the profile defined by `task-profile`. - -The `requester` and `recipient` elements define the organisation(s) or person(s) who are allowed to request or receive the message specified by `message-name`. The receiving DSF instance is the one who will execute the process connected to the message. - -You will have to create your own [ActivityDefinitions](activitydefinition.md) when developing a process plugin. If you are fluent in reading XML FHIR definitions and translating them into XML resources, you can take a look at the DSF's profile for ActivityDefinitions [here](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-activity-definition-1.0.0.xml). ActivityDefinitions also reference other resource definitions. Depending on the resource, you will find them in one of [these folders](https://github.com/datasharingframework/dsf/tree/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir). If you are not as comfortable with these requirements you might want to check out the guide on [creating ActivityDefinitions](../guides/creating-activity-definitions.md). - -You can also find examples for all possible `requester` and `recipient` elements [here](../dsf/requester-and-recipient.md). \ No newline at end of file diff --git a/docs/src/develop/fhir/codesystem.md b/docs/src/develop/fhir/codesystem.md deleted file mode 100644 index e40a365f2..000000000 --- a/docs/src/develop/fhir/codesystem.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -title: CodeSystem -icon: creative ---- - -### CodeSystem - -[CodeSystems](https://www.hl7.org/fhir/R4/codesystem.html) usually represent a set of concepts which can be assigned to a code (think LOINC). If you want to use a Code in a resource, you will usually include them in a [ValueSet](valueset.md). - -Plugin development for the DSF requires the use of [CodeSystems](https://www.hl7.org/fhir/R4/codesystem.html) in two major ways: -1. Using existing [DSF CodeSystems](https://github.com/datasharingframework/dsf/tree/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/CodeSystem) in other FHIR resources like the [dsf-extension-process-authorization](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-extension-process-authorization-1.0.0.xml). -2. Creating your own CodeSystem to add additional [Input Parameters](task.md#task-input-parameters) to your [Task](task.md) profiles. \ No newline at end of file diff --git a/docs/src/develop/fhir/index.md b/docs/src/develop/fhir/index.md deleted file mode 100644 index 47e4a6cda..000000000 --- a/docs/src/develop/fhir/index.md +++ /dev/null @@ -1,13 +0,0 @@ ---- -title: FHIR -icon: creative ---- - -## Introduction -The DSF uses a variety of [FHIR resources](https://dsf.dev/intro/info/basics.html#why-are-we-using-fhir-and-bpmn). The DSF uses XML as the format for FHIR resources. The most important resources for plugin development are [ActivityDefinitions](activitydefinition.md), [CodeSystems](codesystem.md), [Tasks](task.md) and [ValueSets](valueset.md). There is also a catalog of DSF-specific FHIR resources including CodeSystems, ValueSets and Extensions. For now, you can find them in the official DSF GitHub repository [here](https://github.com/datasharingframework/dsf/tree/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir). - -## Details -- [ActivityDefinition](activitydefinition.md) -- [CodeSystem](codesystem.md) -- [Task](task.md) -- [ValueSet](valueset.md) \ No newline at end of file diff --git a/docs/src/develop/fhir/task.md b/docs/src/develop/fhir/task.md deleted file mode 100644 index a647fc46c..000000000 --- a/docs/src/develop/fhir/task.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -title: Task -icon: creative ---- - -### Task - -The [FHIR Task](https://www.hl7.org/fhir/R4/task.html) resource enables the DSF's distributed communication. Whenever a BPMN process instance communicates with a different process instance, the DSF will create a Task resource based on parameters you set in the BPMN model and during execution. It will then automatically send the Task resource to the recipient to start or continue whatever process the Task resource referred to. All Task resources used in the DSF derive from the [dsf-task-base](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-task-base-1.0.0.xml). This profile includes a splicing for `Task.input` with three additional [Input Parameters](task.md#task-input-parameters): -- `message-name` -- `business-key` -- `correlation-key` - -When creating your own plugin, you will want to create your own profiles based on the [dsf-task-base](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-task-base-1.0.0.xml). - -#### Task Input Parameters - -Task Input Parameters allow you to add additional information to [Task](task.md#task) resources. For example, if your particular data exchange requires additional medical data, you would add a slice to your Task profile in the same way the [dsf-task-base](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-task-base-1.0.0.xml) adds slices to the original [FHIR Task](https://www.hl7.org/fhir/R4/task.html) resource. Notice that this also requires creating a [CodeSystem](codesystem.md) and including it in a [ValueSet](valueset.md) to be able to use it in the Task resource. - -If these instructions are insufficient you can check out the guide on [how to add Task Input Parameters](../guides/adding-task-input-parameters-to-task-profiles.md). \ No newline at end of file diff --git a/docs/src/develop/fhir/valueset.md b/docs/src/develop/fhir/valueset.md deleted file mode 100644 index 6be03a3fb..000000000 --- a/docs/src/develop/fhir/valueset.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -title: ValueSet -icon: creative ---- - -### ValueSet - -[ValueSets](https://www.hl7.org/fhir/R4/valueset.html) bind codes from [CodeSystems](codesystem.md) to coded elements like `code`, `Coding` or `CodeableConcept`. - -[ValueSets](https://www.hl7.org/fhir/R4/valueset.html) are mostly needed to use the [Concepts](https://www.hl7.org/fhir/R4/codesystem-definitions.html#CodeSystem.concept) from [CodeSystems](codesystem.md) in your [Task](task.md) profiles. \ No newline at end of file diff --git a/docs/src/develop/guides/accessing-bpmn-process-variables.md b/docs/src/develop/guides/accessing-bpmn-process-variables.md deleted file mode 100644 index f03bee5d0..000000000 --- a/docs/src/develop/guides/accessing-bpmn-process-variables.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -title: Accessing BPMN Process Variables -icon: creative ---- - -### Accessing BPMN Process Variables - -After creating a [Service Delegate](../dsf/service-delegates.md) or [Message Delegate](../dsf/message-delegates.md), you might want to retrieve data from or store data in the [BPMN process variables](../dsf/bpmn-process-variables.md). You can achieve this either through the [BPMN process execution](../dsf/bpmn-process-execution.md) or via the `Variables` class. *It is very much recommended to use the latter method*. - -The `Variables` class provides lots of utility methods to read or write certain types of [BPMN process variables](../dsf/bpmn-process-variables.md). If for some reason you need to fall back on the [BPMN process execution](../dsf/bpmn-process-execution.md) to solve your problem, we would like to learn how the current API of the `Variables` class is limiting you. Contact us, and we might turn it into a feature request ([Contribute](https://dsf.dev/stable/contribute)). diff --git a/docs/src/develop/guides/accessing-task-resources-during-execution.md b/docs/src/develop/guides/accessing-task-resources-during-execution.md deleted file mode 100644 index 196e16381..000000000 --- a/docs/src/develop/guides/accessing-task-resources-during-execution.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -title: Accessing Task Resources During Execution -icon: creative ---- - -### Accessing Task Resources During Execution - -If you want access to the [Task](../fhir/task.md) resources in your [Service](../dsf/service-delegates.md) / [Message](../dsf/message-delegates.md) Delegates, the `Variables` class will provide methods which return certain kinds of [Task](../fhir/task.md) resources. The most commonly used ones are the start [Task](../fhir/task.md), referring to the [Task](../fhir/task.md) / [Message Start Event](../bpmn/messaging.md#message-start-event) responsible for starting the process, and the latest [Task](../fhir/task.md), referring to most recently received [Task](../fhir/task.md) / Message. -In principle, this is sufficient to access all information in a [Task](../fhir/task.md) resource, since you have the [Task](../fhir/task.md) resource's Java object, but very cumbersome. -Instead of navigating the [Task](../fhir/task.md) resource's element tree, you should first try to use the [ProcessPluginApi's](../dsf/process-plugin-api.md) `TaskHelper` in conjunction with the method above. The `TaskHelper` class offers specific methods related to [Task](../fhir/task.md) resources. -The most common use case for this is retrieving data from a [Task's](../fhir/task.md) [Input Parameter](../fhir/task.md#task-input-parameters) or creating a new [Input Parameter](../fhir/task.md#task-input-parameters) for a [Message Delegate's](../dsf/message-delegates.md) `getAdditionalInputParameters` method. When retrieving data from a [Task's](../fhir/task.md) Input Parameter you first have to get to the [Input Parameter](../fhir/task.md#task-input-parameters) you are looking to extract data from. You can use one of the `TaskHelper's` getters for [Input Parameters](../fhir/task.md#task-input-parameters) to find the right one. The methods will try to match the provided [CodeSystem](../fhir/codesystem.md) and Code to any [Input Parameter](../fhir/task.md#task-input-parameters) of the provided [Task](../fhir/task.md) resource. Depending on the method you chose you will for example receive all matches or just the first one. -To create new [Input Parameters](../fhir/task.md#task-input-parameters) to attach to a [Task](../fhir/task.md) resource, you may invoke the `TaskHelper#createInput` method. This is most often used when overriding the `getAdditionalInputParamters` method of you [Message Delegate](../dsf/message-delegates.md). \ No newline at end of file diff --git a/docs/src/develop/guides/adding-task-input-parameters-to-task-profiles.md b/docs/src/develop/guides/adding-task-input-parameters-to-task-profiles.md deleted file mode 100644 index 7a625d5f4..000000000 --- a/docs/src/develop/guides/adding-task-input-parameters-to-task-profiles.md +++ /dev/null @@ -1,210 +0,0 @@ ---- -title: Adding Task Input Parameters to Task Profiles -icon: creative ---- - -### Adding Task Input Parameters to Task Profiles - -When adding a new [Input Parameter](../fhir/task.md#task-input-parameters) to a [Task](../fhir/task.md) profile, you are essentially adding a new slice to `Task.input`. [Slicing](https://www.hl7.org/fhir/R4/profiling.html#slicing) is part of [profiling](https://www.hl7.org/fhir/R4/profiling.html) in FHIR. Profiling lets you create your own FHIR definitions based on pre-existing FHIR definitions. A slicing defines constraints on element lists like `Task.input` e.g. by only allowing the elements to be of certain types. -For example, you might have a list of fruits in a `FruitBasket` resource. Constraining that list to only include fruits of type `Apple`, `Banana` and `Orange` would be considered [slicing](https://www.hl7.org/fhir/R4/profiling.html#slicing). -This guide will not cover how slicing works in general, only for the case presented by the DSF FHIR resource context. Our goal will be to add a new [Input Parameter](../fhir/task.md#task-input-parameters) of type `example-input` to the `task-start-dic-process.xml` profile which will be used to submit `integer` values to our `dicProcess`. - -Let us start out by adding a slice to `task-start-dic-process.xml`. Since there is already a slicing defined on `Task.input` by `task-start-dic-process.xml`'s `baseDefinition`, we have to check out this resource first. As a part of the [differential](https://www.hl7.org/fhir/R4/profiling.html#snapshot) statement, slicing also uses [Element Definitions](https://www.hl7.org/fhir/R4/elementdefinition.html). -The slicing for `Task.input` is defined in this part of the `baseDefinition`: -```xml -<element id="Task.input"> - <extension url="http://hl7.org/fhir/StructureDefinition/structuredefinition-explicit-type-name"> - <valueString value="Parameter" /> - </extension> - <path value="Task.input" /> - <slicing> - <discriminator> - <type value="value" /> - <path value="type.coding.system" /> - </discriminator> - <discriminator> - <type value="value" /> - <path value="type.coding.code" /> - </discriminator> - <rules value="openAtEnd" /> - </slicing> - <min value="1" /> -</element> -``` -*The resource can be found [here](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-task-base-1.0.0.xml)* - -We will only need to take a look at the `discrimitator` tag for now. Discriminators define the elements a FHIR processor needs to distinguish slices by. In our case, a processor would look at the values for `type.coding.system` and `type.coding.code` to determine which slice this element belongs to. The discriminator type `value` implies that `type.coding.system` and `type.coding.code` have to be present in all slices and need to have a fixed value. You can learn more about discriminators [here](https://www.hl7.org/fhir/R4/profiling.html#discriminator). - -Let us revisit `task-start-dic-process.xml` and start adding a slice called `example-input` to it: -```xml -<StructureDefinition xmlns="http://hl7.org/fhir"> - ... - <differential> - ... - <element id="Task.input:example-input"> - <path value="Task.input" /> - <sliceName value="example-input" /> - <min value="1" /> - <max value="1" /> - </element> - </differential> -</StructureDefinition> -``` -*Irrelevant elements for this guide are hidden by ... placeholders.* - -We have now defined a slice on `Task.input` with the name and id of `example-input` and cardinality of `1..1`. You might want a different cardinality for your use case. We recommend you also take a look at the documentation for [ElementDefinition.id](https://www.hl7.org/fhir/R4/elementdefinition.html#id) and [ElementDefinition.path](https://www.hl7.org/fhir/R4/elementdefinition.html#path). They explain how to create the proper values for these elements. Cardinality is also part of the [element definition](https://www.hl7.org/fhir/R4/elementdefinition.html) hierarchy (see [ElementDefinition.min](https://www.hl7.org/fhir/R4/elementdefinition-definitions.html#ElementDefinition.min) and [ElementDefinition.max](https://www.hl7.org/fhir/R4/elementdefinition-definitions.html#ElementDefinition.max)). - -Next up, we need to define the binding for `Task.input:example-input.type`. Because `Task.input.type` is a `CodeableConcept` which uses codings from a [ValueSet](../fhir/valueset.md), the [discriminator](https://www.hl7.org/fhir/R4/profiling.html#discriminator) requires us to use `required` as the binding strength: -```xml -<StructureDefinition xmlns="http://hl7.org/fhir"> - ... - <differential> - ... - <element id="Task.input:example-input"> - <path value="Task.input" /> - <sliceName value="example-input" /> - <min value="1" /> - <max value="1" /> - </element> - <element id="Task.input:example-input.type"> - <path value="Task.input.type" /> - <binding> - <strength value="required"/> - <valueSet value="http://dsf.dev/fhir/ValueSet/example" /> - </binding> - </element> - </differential> -</StructureDefinition> -``` -As you can see, we referenced a [ValueSet](../fhir/valueset.md) in this binding. When adding an actual slice for your use case, you will have to reference an existing [ValueSet](../fhir/valueset.md) resource or create a new one. A guide on how to create them can be found [here](../guides/creating-valuesets-for-dsf-processes.md). - -Since the [discriminator](https://www.hl7.org/fhir/R4/profiling.html#discriminator) requires `Task.input.coding.code` and `Task.input.coding.system` to be present, we will make `Task.input.coding` mandatory as well: -```xml -<StructureDefinition xmlns="http://hl7.org/fhir"> - ... - <differential> - ... - <element id="Task.input:example-input"> - <path value="Task.input" /> - <sliceName value="example-input" /> - <min value="1" /> - <max value="1" /> - </element> - <element id="Task.input:example-input.type"> - <path value="Task.input.type" /> - <binding> - <strength value="required"/> - <valueSet value="http://dsf.dev/fhir/ValueSet/example" /> - </binding> - </element> - <element id="Task.input:example-input.type.coding"> - <path value="Task.input.type.coding"/> - <min value="1" /> - </element> - </differential> -</StructureDefinition> -``` - -In the beginning we mentioned how `Task.input.type.coding.system` and `Task.input.type.coding.code` have to use fixed values. Here is how we accomplish this: - -```xml -<StructureDefinition xmlns="http://hl7.org/fhir"> - ... - <differential> - ... - <element id="Task.input:example-input"> - <path value="Task.input" /> - <sliceName value="example-input" /> - <min value="1" /> - <max value="1" /> - </element> - <element id="Task.input:example-input.type"> - <path value="Task.input.type" /> - <binding> - <strength value="required"/> - <valueSet value="http://dsf.dev/fhir/ValueSet/example" /> - </binding> - </element> - <element id="Task.input:example-input.type.coding"> - <path value="Task.input.type.coding"/> - <min value="1" /> - </element> - <element id="Task.input:example-input.type.coding.system"> - <path value="Task.input.type.coding.system"/> - <min value="1"/> - <fixedUri value="http://dsf.dev/fhir/CodeSystem/example"/> - </element> - <element id="Task.input:example-input.type.coding.code"> - <path value="Task.input.type.coding.code"/> - <min value="1"/> - <fixedCode value="example-input" /> - </element> - </differential> -</StructureDefinition> -``` -*Notice that we also made the two elements mandatory because they are required by the discriminator.* - -For the `type.coding.system` element we referenced a [CodeSystem](../fhir/codesystem.md). The `type.coding.code` element uses a code from this [CodeSystem](../fhir/codesystem.md) called `example-input`. This is the mechanism by which you actually "name" your [Input Parameter](../fhir/task.md#task-input-parameters). The `type.coding.code` value will identify your [Input Parameter](../fhir/task.md#task-input-parameters) when you use it in an actual [Task](../fhir/task.md#task-input-parameters) resource. Here is how this would look like: - -```xml -<Task xmlns="http://hl7.org/fhir"> - ... - <input> - <type> - <coding> - <system value="http://dsf.dev/fhir/CodeSystem/example"/> - <code value="example-input" /> - </coding> - </type> - ... - </input> -</Task> -``` - -When adding an actual slice for your use case, you will also need to reference an existing [CodeSystem](../fhir/codesystem.md) resource or create a new one to reference. A guide on how to create them can be found [here](../guides/creating-codesystems-for-dsf-processes.md). - -`Task.input.value[x]` is the actual value you will submit using your Input Parameter. You can make it any of [these](https://www.hl7.org/fhir/R4/datatypes.html#open) data types. This is because `Type.input.value[x]` refers to `*` instead of any particular type in its [definition](https://www.hl7.org/fhir/R4/task-definitions.html#Task.input.value_x_). Let us define it as an `integer` type`: - -```xml -<StructureDefinition xmlns="http://hl7.org/fhir"> - ... - <differential> - ... - <element id="Task.input:example-input"> - <path value="Task.input" /> - <sliceName value="example-input" /> - <min value="1" /> - <max value="1" /> - </element> - <element id="Task.input:example-input.type"> - <path value="Task.input.type" /> - <binding> - <strength value="required"/> - <valueSet value="http://dsf.dev/fhir/ValueSet/example" /> - </binding> - </element> - <element id="Task.input:example-input.type.coding"> - <path value="Task.input.type.coding"/> - <min value="1" /> - </element> - <element id="Task.input:example-input.type.coding.system"> - <path value="Task.input.type.coding.system"/> - <min value="1"/> - <fixedUri value="http://dsf.dev/fhir/CodeSystem/example"/> - </element> - <element id="Task.input:example-input.type.coding.code"> - <path value="Task.input.type.coding.code"/> - <min value="1"/> - <fixedCode value="example-input" /> - </element> - <element id="Task.input:example-input.value[x]"> - <path value="Task.input.value[x]"/> - <type> - <code value="integer"/> - </type> - </element> - </differential> -</StructureDefinition> -``` - -Now we have a new Input Parameter of type `example-input` which accepts any `integer` as its value. diff --git a/docs/src/develop/guides/configuring-read-access-tags.md b/docs/src/develop/guides/configuring-read-access-tags.md deleted file mode 100644 index 404f2286e..000000000 --- a/docs/src/develop/guides/configuring-read-access-tags.md +++ /dev/null @@ -1,415 +0,0 @@ ---- -title: Configuring Read Access Tags -icon: creative ---- - -### Configuring Read Access Tags - -To start off, you want to take a look at the [CodeSystem](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/CodeSystem/dsf-read-access-tag-1.0.0.xml) defined for the [Read Access Tag](../dsf/read-access-tag.md) and choose one of the codes from it: -```xml -<CodeSystem xmlns="http://hl7.org/fhir"> - ... - <url value="http://dsf.dev/fhir/CodeSystem/read-access-tag"/> - ... - <concept> - <code value="LOCAL"/> - <display value="Local"/> - <definition value="Read access for local users"/> - </concept> - <concept> - <code value="ORGANIZATION"/> - <display value="Organization"/> - <definition value="Read access for organization specified via extension http://dsf.dev/fhir/StructureDefinition/extension-read-access-organization"/> - </concept> - <concept> - <code value="ROLE"/> - <display value="Role"/> - <definition value="Read access for member organizations with role in consortium (parent organization) specified via extension http://dsf.dev/fhir/StructureDefinition/extension-read-access-consortium-role"/> - </concept> - <concept> - <code value="ALL"/> - <display value="All"/> - <definition value="Read access for remote and local users"/> - </concept> -</CodeSystem> -``` - -The codes `LOCAL` and `ALL` are trivial. Their [Read Access Tag](../dsf/read-access-tag.md) would look like this: -```xml -<meta> - <tag> - <system value="http://dsf.dev/fhir/CodeSystem/read-access-tag"/> - <code value="ALL"/> <!-- or value="LOCAL" respectively--> - </tag> -</meta> -``` - -Let us try to configure a Read Access Tag whose code uses an extension. We will choose `ROLE` for this example. We start out the same way as before: -```xml -<meta> - <tag> - <system value="http://dsf.dev/fhir/CodeSystem/read-access-tag"/> - <code value="ROLE"/> - </tag> -</meta> -``` - -The `definition` element of the `ROLE` code references an extension called [dsf-extension-read-access-parent-organization-role](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-extension-read-access-parent-organization-role-1.0.0.xml). - -The most important part of it is the `differential` statement. It uses [element definitions](https://www.hl7.org/fhir/R4/elementdefinition.html) to describe how we need to implement the extension: -```xml -<StructureDefinition xmlns="http://hl7.org/fhir"> - ... - <differential> - <element id="Extension.extension"> - <path value="Extension.extension" /> - <slicing> - <discriminator> - <type value="value" /> - <path value="url" /> - </discriminator> - <rules value="open" /> - </slicing> - </element> - <element id="Extension.extension:parentOrganization"> - <path value="Extension.extension" /> - <sliceName value="parentOrganization" /> - <min value="1" /> - <max value="1" /> - </element> - <element id="Extension.extension:parentOrganization.url"> - <path value="Extension.extension.url" /> - <fixedUri value="parent-organization" /> - </element> - <element id="Extension.extension:parentOrganization.value[x]"> - <path value="Extension.extension.value[x]" /> - <min value="1" /> - <type> - <code value="Identifier" /> - </type> - </element> - <element id="Extension.extension:parentOrganization.value[x].system"> - <path value="Extension.extension.value[x].system" /> - <min value="1" /> - <fixedUri value="http://dsf.dev/sid/organization-identifier" /> - </element> - <element id="Extension.extension:parentOrganization.value[x].value"> - <path value="Extension.extension.value[x].value" /> - <min value="1" /> - </element> - <element id="Extension.extension:organizationRole"> - <path value="Extension.extension" /> - <sliceName value="organizationRole" /> - <min value="1" /> - <max value="1" /> - </element> - <element id="Extension.extension:organizationRole.url"> - <path value="Extension.extension.url" /> - <fixedUri value="organization-role" /> - </element> - <element id="Extension.extension:organizationRole.value[x]"> - <path value="Extension.extension.value[x]" /> - <min value="1" /> - <type> - <code value="Coding" /> - </type> - </element> - <element id="Extension.extension:organizationRole.value[x].system"> - <path value="Extension.extension.value[x].system" /> - <min value="1" /> - </element> - <element id="Extension.extension:organizationRole.value[x].code"> - <path value="Extension.extension.value[x].code" /> - <min value="1" /> - </element> - <element id="Extension.url"> - <path value="Extension.url" /> - <fixedUri value="http://dsf.dev/fhir/StructureDefinition/extension-read-access-parent-organization-role" /> - </element> - <element id="Extension.value[x]"> - <path value="Extension.value[x]" /> - <max value="0" /> - </element> - </differential> -</StructureDefinition> -``` - -All extensions for the [Read Access Tag](../dsf/read-access-tag.md) CodeSystem are defined on the `meta.tag.extension` element through the extension's `context` element: -```xml -<context> - <type value="element" /> - <expression value="Coding" /> <!-- meta.tag is of type Coding--> -</context> -``` - -That is why the first element we are adding to `meta.tag` is an `extension` element: -```xml -<meta> - <tag> - <extenion> - - </extenion> - <system value="http://dsf.dev/fhir/CodeSystem/read-access-tag"/> - <code value="ROLE"/> - </tag> -</meta> -``` - -We will now go through the `differential` statement one element at a time, starting at the top: -```xml -<StructureDefinition xmlns="http://hl7.org/fhir"> - ... - <differential> - <element id="Extension.extension"> - <path value="Extension.extension" /> - <slicing> - <discriminator> - <type value="value" /> - <path value="url" /> - </discriminator> - <rules value="open" /> - </slicing> - </element> - ... - </differential> -</StructureDefinition> -``` - -It defines a [slicing](https://www.hl7.org/fhir/R4/profiling.html#slicing) for the `Extension.extension` element, meaning we are dealing with a nested extension. The `discriminator` element tells us that slices will be identified by the value of their `url` attribute. A `rules` element with value `open` means other types of slices may be added later on e.g. when creating a profile. We do not have to add any elements from here to the `meta.tag.extension` element. Next up is the first slice called `parentOrganization`: - -```xml -<StructureDefinition xmlns="http://hl7.org/fhir"> - ... - <differential> - ... - <element id="Extension.extension:parentOrganization"> - <path value="Extension.extension" /> - <sliceName value="parentOrganization" /> - <min value="1" /> - <max value="1" /> - </element> - <element id="Extension.extension:parentOrganization.url"> - <path value="Extension.extension.url" /> - <fixedUri value="parent-organization" /> - </element> - <element id="Extension.extension:parentOrganization.value[x]"> - <path value="Extension.extension.value[x]" /> - <min value="1" /> - <type> - <code value="Identifier" /> - </type> - </element> - <element id="Extension.extension:parentOrganization.value[x].system"> - <path value="Extension.extension.value[x].system" /> - <min value="1" /> - <fixedUri value="http://dsf.dev/sid/organization-identifier" /> - </element> - <element id="Extension.extension:parentOrganization.value[x].value"> - <path value="Extension.extension.value[x].value" /> - <min value="1" /> - </element> - ... - </differential> -</StructureDefinition> -``` - -The first element defines a slice called `parentOrganization` on the `Extension.extension` element with cardinality `1..1`. The second element defines the url attribute of the `parentOrganization` slice to be fixed to the value `parent-organization`. With this information we can add the next element to `meta.tag`. Since it is defined on `Extension.extension` we will add it to `meta.tag.extension.extension` like this: -```xml -<meta> - <tag> - <extension> - <extension url="parent-organization"> - - </extension> - </extension> - <system value="http://dsf.dev/fhir/CodeSystem/read-access-tag"/> - <code value="ROLE"/> - </tag> -</meta> -``` - -After that, it defines `parentOrganization.value[x]` to occur at least once and have a type of `Identifier`. To turn this into an element to add to `meta.tag.extension.extension` we have to replace `[x]` with our code in `value[x].type`, which in this case is `Identifier`. It is important to note, that should the value in the code element be lowercase, you will have make it uppercase before replacement. In our case this means we will have a `meta.tag.extension.extension.valueIdentifier` element: -```xml -<meta> - <tag> - <extension> - <extension url="parent-organization"> - <valueIdentifier> - - </valueIdentifier> - </extension> - </extension> - <system value="http://dsf.dev/fhir/CodeSystem/read-access-tag"/> - <code value="ROLE"/> - </tag> -</meta> -``` - -The last two elements define a `system` element with a fixed value and `value` element we can fill in on our own, since it does not have any constraints applied. Notice that the element definition still uses `value[x].system` and `value[x].value`. The replacement mentioned earlier does not happen in the element definition, but since `value[x]` is defined to have the type `Identifier` it is inferred that we mean to reference `Identifier.system` and `Identifier.value`. We will choose an arbitrary `Idenfier` value, but you should be using an actual organization identifier depending on who you want to allow read access to the resource. - -```xml -<meta> - <tag> - <extension> - <extension url="parent-organization"> - <valueIdentifier> - <system value="http://dsf.dev/sid/organization-identifier"/> - <value value="My_Organization"/> - </valueIdentifier> - </extension> - </extension> - <system value="http://dsf.dev/fhir/CodeSystem/read-access-tag"/> - <code value="ROLE"/> - </tag> -</meta> -``` - -Next is the slice is called `organizationRole`: -```xml -<StructureDefinition xmlns="http://hl7.org/fhir"> - ... - <differential> - ... - <element id="Extension.extension:organizationRole"> - <path value="Extension.extension" /> - <sliceName value="organizationRole" /> - <min value="1" /> - <max value="1" /> - </element> - <element id="Extension.extension:organizationRole.url"> - <path value="Extension.extension.url" /> - <fixedUri value="organization-role" /> - </element> - <element id="Extension.extension:organizationRole.value[x]"> - <path value="Extension.extension.value[x]" /> - <min value="1" /> - <type> - <code value="Coding" /> - </type> - </element> - <element id="Extension.extension:organizationRole.value[x].system"> - <path value="Extension.extension.value[x].system" /> - <min value="1" /> - </element> - <element id="Extension.extension:organizationRole.value[x].code"> - <path value="Extension.extension.value[x].code" /> - <min value="1" /> - </element> - ... - </differential> -</StructureDefinition> -``` - -Like with `parentOrganization`, we will add an extension element to `meta.tag.extension` with the fixed url value defined above: -```xml -<meta> - <tag> - <extension> - <extension url="parent-organization"> - <valueIdentifier> - <system value="http://dsf.dev/sid/organization-identifier"/> - <value value="My_Organization"/> - </valueIdentifier> - </extension> - <extension url="organization-role"> - - </extension> - </extension> - <system value="http://dsf.dev/fhir/CodeSystem/read-access-tag"/> - <code value="ROLE"/> - </tag> -</meta> -``` - -Instead of `Identifier`, the `value[x]` element is now defined as a `Coding` type. This means we will add a `valueCoding` element to the extension: -```xml -<meta> - <tag> - <extension> - <extension url="parent-organization"> - <valueIdentifier> - <system value="http://dsf.dev/sid/organization-identifier"/> - <value value="My_Organization"/> - </valueIdentifier> - </extension> - <extension url="organization-role"> - <valueCoding> - - </valueCoding> - </extension> - </extension> - <system value="http://dsf.dev/fhir/CodeSystem/read-access-tag"/> - <code value="ROLE"/> - </tag> -</meta> -``` - -A `Coding` has to belong to some [CodeSystem](../fhir/codesystem.md). The DSF has a CodeSystem called [dsf-organization-role](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/CodeSystem/dsf-organization-role-1.0.0.xml). Before creating your own CodeSystem, it is worth taking a look at it to see if an appropriate role already exists for your organization. For demonstration purposes, we will be using the `DIC` role: -```xml -<meta> - <tag> - <extension> - <extension url="parent-organization"> - <valueIdentifier> - <system value="http://dsf.dev/sid/organization-identifier"/> - <value value="My_Organization"/> - </valueIdentifier> - </extension> - <extension url="organization-role"> - <valueCoding> - <system value="http://dsf.dev/fhir/CodeSystem/organization-role"/> - <code value="DIC"/> - </valueCoding> - </extension> - </extension> - <system value="http://dsf.dev/fhir/CodeSystem/read-access-tag"/> - <code value="ROLE"/> - </tag> -</meta> -``` - -Now we only have two elements left in the `differential` statement: - -```xml -<StructureDefinition xmlns="http://hl7.org/fhir"> - ... - <differential> - ... - <element id="Extension.url"> - <path value="Extension.url" /> - <fixedUri value="http://dsf.dev/fhir/StructureDefinition/extension-read-access-parent-organization-role" /> - </element> - <element id="Extension.value[x]"> - <path value="Extension.value[x]" /> - <max value="0" /> - </element> - </differential> -</StructureDefinition> -``` - -The `Extension.url` element tells us to add a url attribute to `meta.tag.extension`. The last element makes it so we must not add a `meta.tag.extension.value[x]` element. This leaves us with this final Read Access Tag: - -```xml -<meta> - <tag> - <extension url="http://dsf.dev/fhir/StructureDefinition/extension-read-access-parent-organization-role"> - <extension url="parent-organization"> - <valueIdentifier> - <system value="http://dsf.dev/sid/organization-identifier"/> - <value value="My_Organization"/> - </valueIdentifier> - </extension> - <extension url="organization-role"> - <valueCoding> - <system value="http://dsf.dev/fhir/CodeSystem/organization-role"/> - <code value="DIC"/> - </valueCoding> - </extension> - </extension> - <system value="http://dsf.dev/fhir/CodeSystem/read-access-tag"/> - <code value="ROLE"/> - </tag> -</meta> -``` - -You can follow the same method to configure the other types of Read Access Tags as well. \ No newline at end of file diff --git a/docs/src/develop/guides/creating-activity-definitions.md b/docs/src/develop/guides/creating-activity-definitions.md deleted file mode 100644 index 40a7cfb2e..000000000 --- a/docs/src/develop/guides/creating-activity-definitions.md +++ /dev/null @@ -1,750 +0,0 @@ ---- -title: Creating ActivityDefinitions -icon: creative ---- - -### Creating ActivityDefinitions - -This guide will teach you how to create an ActivityDefinition based on the [dsf-activity-definition](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-activity-definition-1.0.0.xml) profile for your process plugin. -It is divided into steps for each of the main components of ActivityDefinitions: -1. Read Access Tag -2. Extension: process authorization -3. BPE Managed Elements -4. Regular Elements - -*Regular elements* are all elements not part of the first 3 main components. - -*We will assume you know how to translate [ElementDefinitions](https://www.hl7.org/fhir/R4/elementdefinition.html) to actual elements in a FHIR resource. If you do not, you might want to check out the guide on [creating Task resources](../guides/creating-task-resources-based-on-a-definition.md) first.* - -#### 1. Read Access Tag -Let us start out with an empty [ActivityDefinition](../fhir/activitydefinition.md): -```xml -<ActivityDefinition xmlns="http://hl7.org/fhir"> - -</ActivityDefinition> -``` - -The first element in DSF FHIR resources is always the [Read Access Tag](../dsf/read-access-tag.md). It describes who is allowed to read this resource through the DSF FHIR server's REST API. You can learn more complex configurations of the [Read Access Tag](../dsf/read-access-tag.md) in [this guide](../dsf/read-access-tag.md). In this case, we will allow read access to everyone: - -```xml -<ActivityDefinition xmlns="http://hl7.org/fhir"> - <meta> - <tag> - <system value="http://dsf.dev/fhir/CodeSystem/read-access-tag" /> - <code value="ALL" /> - </tag> - </meta> -</ActivityDefinition> -``` - -#### 2. Extension: Process Authorization -This part of your ActivityDefinition will tell the DSF who is allowed to request and receive messages ([Task](../fhir/task.md) resources) for your BPMN process. If your plugin contains more than one BPMN process, you will have to create one [ActivityDefinition](../fhir/activitydefinition.md) for each BPMN process. It is important to note that you need to include authorization rules for **ALL** messages received in your BPMN process. This includes the message starting your BPMN process initially. You can find the extension [here](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-extension-process-authorization-1.0.0.xml). Let us continue by adding the [extension element](http://hl7.org/fhir/R4/extensibility.html#extension) with the correct URL. You can get the value for the URL from the `Extension.url` element: -```xml -<ActivityDefinition xmlns="http://hl7.org/fhir"> - ... - <extension url="http://dsf.dev/fhir/StructureDefinition/extension-process-authorization"> - - </extension> -</ActivityDefinition> -``` -*Elements not relevant to the current component are hidden with ... to increase readability.* - -The [differential](https://www.hl7.org/fhir/R4/profiling.html#snapshot) statement starts by defining the [slicing](https://www.hl7.org/fhir/R4/profiling.html#snapshot) for the `Extension.extension` element: - -```xml -<StructureDefinition xmlns="http://hl7.org/fhir"> - ... - <differential> - <element id="Extension"> - <path value="Extension" /> - <min value="1" /> - </element> - <element id="Extension.extension"> - <path value="Extension.extension" /> - <slicing> - <discriminator> - <type value="value" /> - <path value="url" /> - </discriminator> - <rules value="open" /> - </slicing> - </element> - ... - </differential> -</StructureDefinition> -``` - -The above states that whenever this extension is used in a profile, the profile needs to include this extension at least once (`<min value="1" />`). The [slicing](https://www.hl7.org/fhir/R4/profiling.html#snapshot) on `Extension.extension` tells us that elements of this [slicing](https://www.hl7.org/fhir/R4/profiling.html#snapshot) are identified by the value of their URL (`<discriminator>`), which is always the case for extensions, and that other extensions can be added to the [slicing](https://www.hl7.org/fhir/R4/profiling.html#snapshot) (`<rules value="open" />`). Since there is a [slicing](https://www.hl7.org/fhir/R4/profiling.html#snapshot) on `Extension.extension`, we are dealing with a nested extension. - -After these initial element definitions come the elements relevant for your process plugin. The first one is the `message-name` slice: -```xml -<StructureDefinition xmlns="http://hl7.org/fhir"> - ... - <differential> - ... - <element id="Extension.extension:message-name"> - <path value="Extension.extension" /> - <sliceName value="message-name" /> - <min value="1" /> - <max value="1" /> - </element> - <element id="Extension.extension:message-name.url"> - <path value="Extension.extension.url" /> - <fixedUri value="message-name" /> - </element> - <element id="Extension.extension:message-name.value[x]"> - <path value="Extension.extension.value[x]" /> - <min value="1" /> - <type> - <code value="string" /> - </type> - </element> - ... - </differential> -</StructureDefinition> -``` - -This section tells us that we need to include exactly one extension element from the `message-name` slice in our [ActivityDefinition](../fhir/activitydefinition.md). The extension element will have a URL value of `message-name`. If you remember the `discriminator` configuration, this URL value identifies the element to belong to the `message-name` slice on `Extension.extension`. Lastly, the extension element includes a `valueString` element. In case you are wondering how `value[x]` turned into `valueString`, FHIR does not allow using `value[x]` as actual element. The value in `value[x]` is always strictly bound to some kind of type. FHIR uses the `value[x].type.code` value to determine this type and replaces `[x]` with an uppercase version of `element.type.code`. This results in the following extension element we will add to our [ActivityDefinition](../fhir/activitydefinition.md): -```xml -<extension url="message-name"> - <valueString value="myMessage"/> -</extension> -``` - -For your use case, you have to replace `myMessage` with the name of the [BPMN message event](../bpmn/messaging.md) that is expecting this message. - -<details> -<summary>This is how your ActivityDefinition should look like so far</summary> - -```xml -<ActivityDefinition xmlns="http://hl7.org/fhir"> - <meta> - <tag> - <system value="http://dsf.dev/fhir/CodeSystem/read-access-tag" /> - <code value="ALL" /> - </tag> - </meta> - <extension url="http://dsf.dev/fhir/StructureDefinition/extension-process-authorization"> - <extension url="message-name"> - <valueString value="myMessage"/> - </extension> - </extension> -</ActivityDefinition> -``` -</details> - -The next slice is called `task-profile`: -```xml -<StructureDefinition xmlns="http://hl7.org/fhir"> - ... - <differential> - ... - <element id="Extension.extension:task-profile"> - <path value="Extension.extension" /> - <sliceName value="task-profile" /> - <min value="1" /> - <max value="1" /> - </element> - <element id="Extension.extension:task-profile.url"> - <path value="Extension.extension.url" /> - <fixedUri value="task-profile" /> - </element> - <element id="Extension.extension:task-profile.value[x]"> - <path value="Extension.extension.value[x]" /> - <min value="1" /> - <type> - <code value="canonical" /> - </type> - </element> - ... - </differential> -</StructureDefinition> -``` - -This section has almost the same structure as `message-name`. The only difference is the value for `value[x].type.code`. This means that instead of `valueString`, we will have to use a `valueCanonical` element for `task-profile.value[x]`. Canonical values referring to [Task](../fhir/task.md) profiles in ActivityDefinitions have to conform to the rules outlined by the documentation on [URLs](../dsf/versions-placeholders-urls.md#urls). From the definition above, we will create the following extension element and add it to our [ActivityDefinition](../fhir/activitydefinition.md): -```xml -<extension url="task-profile"> - <valueCanonical value="http://dsf.dev/fhir/StructureDefinition/my-task|#{version}"/> -</extension> -``` - -<details> -<summary>This is how your ActivityDefinition should look like so far</summary> - -```xml -<ActivityDefinition xmlns="http://hl7.org/fhir"> - <meta> - <tag> - <system value="http://dsf.dev/fhir/CodeSystem/read-access-tag" /> - <code value="ALL" /> - </tag> - </meta> - <extension url="http://dsf.dev/fhir/StructureDefinition/extension-process-authorization"> - <extension url="message-name"> - <valueString value="myMessage"/> - </extension> - <extension url="task-profile"> - <valueCanonical value="http://dsf.dev/fhir/StructureDefinition/my-task|#{version}"/> - </extension> - </extension> -</ActivityDefinition> -``` -</details> - -The next slice is `requester`: -```xml -<StructureDefinition xmlns="http://hl7.org/fhir"> - ... - <differential> - ... - <element id="Extension.extension:requester"> - <path value="Extension.extension" /> - <sliceName value="requester" /> - <min value="1" /> - </element> - <element id="Extension.extension:requester.url"> - <path value="Extension.extension.url" /> - <fixedUri value="requester" /> - </element> - <element id="Extension.extension:requester.value[x]"> - <path value="Extension.extension.value[x]" /> - <min value="1" /> - <type> - <code value="Coding" /> - <profile value="http://dsf.dev/fhir/StructureDefinition/coding-process-authorization-local-all|1.0.0" /> - <profile value="http://dsf.dev/fhir/StructureDefinition/coding-process-authorization-local-all-practitioner|1.0.0" /> - <profile value="http://dsf.dev/fhir/StructureDefinition/coding-process-authorization-local-organization|1.0.0" /> - <profile value="http://dsf.dev/fhir/StructureDefinition/coding-process-authorization-local-organization-practitioner|1.0.0" /> - <profile value="http://dsf.dev/fhir/StructureDefinition/coding-process-authorization-local-parent-organization-role|1.0.0" /> - <profile value="http://dsf.dev/fhir/StructureDefinition/coding-process-authorization-local-parent-organization-role-practitioner|1.0.0" /> - <profile value="http://dsf.dev/fhir/StructureDefinition/coding-process-authorization-remote-all|1.0.0" /> - <profile value="http://dsf.dev/fhir/StructureDefinition/coding-process-authorization-remote-organization|1.0.0" /> - <profile value="http://dsf.dev/fhir/StructureDefinition/coding-process-authorization-remote-parent-organization-role|1.0.0" /> - </type> - <binding> - <strength value="required" /> - <valueSet value="http://dsf.dev/fhir/ValueSet/process-authorization-requester|1.0.0" /> - </binding> - </element> - ... - </differential> -</StructureDefinition> -``` -Instead of a `string` or `canonical` type for `value[x]` we now have a `Coding` type. See the [FHIR documentation on Codings](https://www.hl7.org/fhir/R4/datatypes.html#Coding) for more in-depth information. `Codings` are elements which contain, among other things, a `code` and the `system` the code belongs to. In the same way we transformed `value[x]` into `valueString` or `valueCanonical` before, we will also have to turn `value[x]` into `valueCoding`. To use `Codings` in `valueCoding` elements, they are usually bound to the element through a [ValueSet](../fhir/valueset.md). This is the responsibility of the `binding` element. You can also see that `value[x].type.profile` lists a number of profiles. Instead of defining the elements in the same file, they were defined in different files for better readability. Depending on your use case, you have to pick one of the profiles. -Here is what they mean: -- `local-all`: All local requests will be allowed. Local requests are identified by matching the requester's certificate to a thumbprint which was internally marked by the DSF FHIR server as belonging to a local organization. -- `local-organization`: All local requests made from an organization with a specific `organization-identifier` will be allowed. -- `local-parent-organization-role`: All local requests made from an organization having a specific role inside a specific parent organization will be allowed. -- `remote` versions of the above rules work the same but the requester's certificate is instead required to match a thumbprint marked as a remote organization. -- `practitioner` suffixes all work the same. They include the same rules as their prefixes but now additionally require the requester to match a certain `practitioner-role`. A list of them - can be found [here](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/CodeSystem/dsf-practitioner-role-1.0.0.xml). This allows - for more granularity when defining authorization rules within an organization and can be integrated into local user management via [OpenID Connect](https://dsf.dev/stable/maintain/fhir/access-control.html). - -As you can see, there are no `practitioner` versions of `remote` authorization rules. From the perspective of the receiving DSF instance, remote requests are always issued by an organization. They do not hold any information about the local user management of the requesting organization. You can also find examples of all Codings from above [here](../dsf/requester-and-recipient.md). - -It is also good to keep in mind that you are allowed to add any number of `requester` elements into your [ActivityDefinition](../fhir/activitydefinition.md). Let us start out by adding a `requester` element like we did for previous elements: - -```xml -<extension url="requester"> - <valueCoding> - - </valueCoding> -</extension> -``` - -We now have to look at the elements that are defined in one of the profiles to fill in the remaining elements since they are not defined by the `requester` extension. For demonstration purposes, we will choose the [dsf-coding-process-authorization-local-organization-practitioner](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-coding-process-authorization-local-organization-practitioner-1.0.0.xml) profile. Since all elements listed in the [Coding definition](https://www.hl7.org/fhir/R4/datatypes.html#codesystem) are optional, we only have to look at the `differential` element from the profile we just selected: -<a id="coding-differential"></a> -```xml -<differential> - <element id="Coding.extension"> - <path value="Coding.extension" /> - <slicing> - <discriminator> - <type value="value" /> - <path value="url" /> - </discriminator> - <rules value="open" /> - </slicing> - </element> - <element id="Coding.extension:organization-practitioner"> - <path value="Coding.extension" /> - <sliceName value="organization-practitioner" /> - <min value="1" /> - <max value="1" /> - <type> - <code value="Extension" /> - <profile value="http://dsf.dev/fhir/StructureDefinition/extension-process-authorization-organization-practitioner|1.0.0" /> - </type> - </element> - <element id="Coding.system"> - <path value="Coding.system" /> - <min value="1" /> - <fixedUri value="http://dsf.dev/fhir/CodeSystem/process-authorization" /> - </element> - <element id="Coding.code"> - <path value="Coding.code" /> - <min value="1" /> - <fixedCode value="LOCAL_ORGANIZATION_PRACTITIONER" /> - </element> -</differential> -``` -It defines an extension called `organization-practitioner` which is identified through its url attribute. Again, the extension is only referenced, its location is in a different file. You can find it [here](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-extension-process-authorization-organization-practitioner-1.0.0.xml). Let us look at its `differential` element in the extension file to see how we need to populate the extension: -```xml -<differential> - <element id="Extension"> - <path value="Extension" /> - <min value="1" /> - <max value="1" /> - </element> - <element id="Extension.extension"> - <path value="Extension.extension" /> - <slicing> - <discriminator> - <type value="value" /> - <path value="url" /> - </discriminator> - <rules value="open" /> - </slicing> - </element> - <element id="Extension.extension:organization"> - <path value="Extension.extension" /> - <sliceName value="organization" /> - <min value="1" /> - <max value="1" /> - </element> - <element id="Extension.extension:organization.url"> - <path value="Extension.extension.url" /> - <fixedUri value="organization" /> - </element> - <element id="Extension.extension:organization.value[x]"> - <path value="Extension.extension.value[x]" /> - <min value="1" /> - <type> - <code value="Identifier" /> - </type> - </element> - <element id="Extension.extension:organization.value[x].system"> - <path value="Extension.extension.value[x].system" /> - <min value="1" /> - <fixedUri value="http://dsf.dev/sid/organization-identifier" /> - </element> - <element id="Extension.extension:organization.value[x].value"> - <path value="Extension.extension.value[x].value" /> - <min value="1" /> - </element> - <element id="Extension.extension:practitionerRole"> - <path value="Extension.extension" /> - <sliceName value="practitionerRole" /> - <min value="1" /> - <max value="1" /> - </element> - <element id="Extension.extension:practitionerRole.url"> - <path value="Extension.extension.url" /> - <fixedUri value="practitioner-role" /> - </element> - <element id="Extension.extension:practitionerRole.value[x]"> - <path value="Extension.extension.value[x]" /> - <min value="1" /> - <type> - <code value="Coding" /> - </type> - </element> - <element id="Extension.extension:practitionerRole.value[x].system"> - <path value="Extension.extension.value[x].system" /> - <min value="1" /> - </element> - <element id="Extension.extension:practitionerRole.value[x].code"> - <path value="Extension.extension.value[x].code" /> - <min value="1" /> - </element> - <element id="Extension.url"> - <path value="Extension.url" /> - <fixedUri value="http://dsf.dev/fhir/StructureDefinition/extension-process-authorization-organization-practitioner" /> - </element> - <element id="Extension.value[x]"> - <path value="Extension.value[x]" /> - <max value="0" /> - </element> -</differential> -``` - -This extension does not reference any other files. This means we reached the "deepest" level. So now we can start working our way back up again from here, by translating this definition into actual extension elements, then inserting it into the Coding we selected, translating the rest of the element definitions from the Coding resource and adding everything to our [ActivityDefinition](../fhir/activitydefinition.md). - -We will start with the `Extension.url` element, since the `Extension` element is the parent element for all slices on the `Extension.extension` elements: -```xml -<extension url="http://dsf.dev/fhir/StructureDefinition/extension-process-authorization-organization-practitioner"> - -</extension> -``` - -Next, we will add the `organization` slice: -```xml -<extension url="http://dsf.dev/fhir/StructureDefinition/extension-process-authorization-organization-practitioner"> - <extension url="organization"> - <valueIdentifier> - <system value="http://dsf.dev/sid/organization-identifier"/> - <value value="My_Organization"/> - </valueIdentifier> - </extension> -</extension> -``` -Finally, we will add the `practitionerRole` slice: - -```xml -<extension url="http://dsf.dev/fhir/StructureDefinition/extension-process-authorization-organization-practitioner"> - <extension url="organization"> - <valueIdentifier> - <system value="http://dsf.dev/sid/organization-identifier"/> - <value value="My_Organization"/> - </valueIdentifier> - </extension> - <extension url="practitioner-role"> - <valueCoding> - <system value="http://dsf.dev/fhir/CodeSystem/practitioner-role"/> - <code value="DSF_ADMIN"/> - </valueCoding> - </extension> -</extension> -``` - -Notice that there is no `binding` element specified for `practitionerRole.value[x]`. This is intentional. In the example we used a code from the [dsf-practitioner-role](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/CodeSystem/dsf-practitioner-role-1.0.0.xml) CodeSystem. This CodeSystem includes a standard set of codes which are often sufficient for DSF use cases. You can freely add other CodeSystems if you find these codes do not apply for your use case. The code you set here can be used in the [DSF role config](https://dsf.dev/stable/maintain/fhir/access-control.html) to allow certain users with this `practitioner-role` to send requests. - -Working our way back up to the Coding we selected, we will now add the extension we just created as the `Coding.extension:organization-practitioner` element: -```xml -<extension url="requester"> - <valueCoding> - <extension url="http://dsf.dev/fhir/StructureDefinition/extension-process-authorization-organization-practitioner"> - <extension url="organization"> - <valueIdentifier> - <system value="http://dsf.dev/sid/organization-identifier"/> - <value value="My_Organization"/> - </valueIdentifier> - </extension> - <extension url="practitioner-role"> - <valueCoding> - <system value="http://dsf.dev/fhir/CodeSystem/practitioner-role"/> - <code value="DSF_ADMIN"/> - </valueCoding> - </extension> - </extension> - </valueCoding> -</extension> -``` -Now might be a good time to look at the [differential](#coding-differential) from the Coding again. Our next elements to be added are `Coding.system` and `Coding.code`: -```xml -<extension url="requester"> - <valueCoding> - <extension url="http://dsf.dev/fhir/StructureDefinition/extension-process-authorization-organization-practitioner"> - <extension url="organization"> - <valueIdentifier> - <system value="http://dsf.dev/sid/organization-identifier"/> - <value value="My_Organization"/> - </valueIdentifier> - </extension> - <extension url="practitioner-role"> - <valueCoding> - <system value="http://dsf.dev/fhir/CodeSystem/practitioner-role"/> - <code value="DSF_ADMIN"/> - </valueCoding> - </extension> - </extension> - <system value="http://dsf.dev/fhir/CodeSystem/process-authorization"/> - <code value="LOCAL_ORGANIZATION_PRACTITIONER"/> - </valueCoding> -</extension> -``` -Now we are finished with the `requester` extension and can add it to our [ActivityDefinition](../fhir/activitydefinition.md) under the [dsf-extension-process-authorization](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-extension-process-authorization-1.0.0.xml). - -<details> -<summary>This is how your ActivityDefinition should look like so far</summary> - -```xml -<ActivityDefinition xmlns="http://hl7.org/fhir"> - <meta> - <tag> - <system value="http://dsf.dev/fhir/CodeSystem/read-access-tag" /> - <code value="ALL" /> - </tag> - </meta> - <extension url="http://dsf.dev/fhir/StructureDefinition/extension-process-authorization"> - <extension url="message-name"> - <valueString value="myMessage"/> - </extension> - <extension url="task-profile"> - <valueCanonical value="http://dsf.dev/fhir/StructureDefinition/my-task|#{version}"/> - </extension> - <extension url="requester"> - <valueCoding> - <extension url="http://dsf.dev/fhir/StructureDefinition/extension-process-authorization-organization-practitioner"> - <extension url="organization"> - <valueIdentifier> - <system value="http://dsf.dev/sid/organization-identifier"/> - <value value="My_Organization"/> - </valueIdentifier> - </extension> - <extension url="practitioner-role"> - <valueCoding> - <system value="http://dsf.dev/fhir/CodeSystem/practitioner-role"/> - <code value="DSF_ADMIN"/> - </valueCoding> - </extension> - </extension> - <system value="http://dsf.dev/fhir/CodeSystem/process-authorization"/> - <code value="LOCAL_ORGANIZATION_PRACTITIONER"/> - </valueCoding> - </extension> - </extension> -</ActivityDefinition> -``` -</details> - -Now we are back to looking at the [dsf-extension-process-authorization](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-extension-process-authorization-1.0.0.xml) again. The last slice for this extension is `recipient`: -```xml -<StructureDefinition xmlns="http://hl7.org/fhir"> - ... - <differential> - ... - <element id="Extension.extension:recipient"> - <path value="Extension.extension" /> - <sliceName value="recipient" /> - <min value="1" /> - </element> - <element id="Extension.extension:recipient.url"> - <path value="Extension.extension.url" /> - <fixedUri value="recipient" /> - </element> - <element id="Extension.extension:recipient.value[x]"> - <path value="Extension.extension.value[x]" /> - <min value="1" /> - <type> - <code value="Coding" /> - <profile value="http://dsf.dev/fhir/StructureDefinition/coding-process-authorization-local-all|1.0.0" /> - <profile value="http://dsf.dev/fhir/StructureDefinition/coding-process-authorization-local-organization|1.0.0" /> - <profile value="http://dsf.dev/fhir/StructureDefinition/coding-process-authorization-local-parent-organization-role|1.0.0" /> - </type> - <binding> - <strength value="required" /> - <valueSet value="http://dsf.dev/fhir/ValueSet/process-authorization-recipient|1.0.0" /> - </binding> - </element> - ... - </differential> -</StructureDefinition> -``` - -The `recipient` will decide which DSF instance is allowed to process that message. That is the reason why you will not find any Codings for `remote` or `practitioner` here. For `requester`, we already decided that we will only allow users with a certain role from our own (local) organization to send this message. So now we will only allow the DSF instance run by that same local organization to process the message. The right Coding for this job is the [coding-process-authorization-local-organization](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-coding-process-authorization-local-organization-1.0.0.xml). The configuration of a local requester and local receiver is often used for the message that starts up the first BPMN process of the plugin. The process of adding the `recipient` slice is the exact same as it is for `requester`. You can follow the steps for the `requester` slice again but just use a different Coding. - -<details> -<summary>Using the Coding we just decided on, this is how your ActivityDefinition should look like</summary> - -```xml -<ActivityDefinition xmlns="http://hl7.org/fhir"> - <meta> - <tag> - <system value="http://dsf.dev/fhir/CodeSystem/read-access-tag" /> - <code value="ALL" /> - </tag> - </meta> - <extension url="http://dsf.dev/fhir/StructureDefinition/extension-process-authorization"> - <extension url="message-name"> - <valueString value="myMessage"/> - </extension> - <extension url="task-profile"> - <valueCanonical value="http://dsf.dev/fhir/StructureDefinition/my-task|#{version}"/> - </extension> - <extension url="requester"> - <valueCoding> - <extension url="http://dsf.dev/fhir/StructureDefinition/extension-process-authorization-organization-practitioner"> - <extension url="organization"> - <valueIdentifier> - <system value="http://dsf.dev/sid/organization-identifier"/> - <value value="My_Organization"/> - </valueIdentifier> - </extension> - <extension url="practitioner-role"> - <valueCoding> - <system value="http://dsf.dev/fhir/CodeSystem/practitioner-role"/> - <code value="DSF_ADMIN"/> - </valueCoding> - </extension> - </extension> - <system value="http://dsf.dev/fhir/CodeSystem/process-authorization"/> - <code value="LOCAL_ORGANIZATION_PRACTITIONER"/> - </valueCoding> - </extension> - <extension url="recipient"> - <valueCoding> - <extension url="http://dsf.dev/fhir/StructureDefinition/extension-process-authorization-organization"> - <valueIdentifier> - <system value="http://dsf.dev/sid/organization-identifier"/> - <value value="My_Organization"/> - </valueIdentifier> - </extension> - <system value="http://dsf.dev/fhir/CodeSystem/process-authorization"/> - <code value="LOCAL_ORGANIZATION"/> - </valueCoding> - </extension> - </extension> -</ActivityDefinition> -``` -</details> - -The last element defined in the [process authorization extension](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-extension-process-authorization-1.0.0.xml) is `Extension.url`. But since we added this element at the very beginning of the working through the extension, we are finished with it here. - -#### 3. BPE Managed Elements - -Some elements of [ActivityDefinitions](../fhir/activitydefinition.md) are managed by the DSF BPE and replaced with certain values at appropriate times. - -The following elements are managed by the DSF BPE: -- `ActivityDefinition.version` should use the [placeholder](../dsf/versions-placeholders-urls.md#placeholders) `#{version}` -- `ActivityDefinition.date` is not required, but should you decide to include it, use the [placeholder](../dsf/versions-placeholders-urls.md#placeholders) `#{date}` -- `ActivityDefinition.status` must have a value of `unknown` - -<details> -<summary>Your ActivityDefinition should now look like this</summary> - -```xml -<ActivityDefinition xmlns="http://hl7.org/fhir"> - <meta> - <tag> - <system value="http://dsf.dev/fhir/CodeSystem/read-access-tag" /> - <code value="ALL" /> - </tag> - </meta> - <extension url="http://dsf.dev/fhir/StructureDefinition/extension-process-authorization"> - <extension url="message-name"> - <valueString value="myMessage"/> - </extension> - <extension url="task-profile"> - <valueCanonical value="http://dsf.dev/fhir/StructureDefinition/my-task|#{version}"/> - </extension> - <extension url="requester"> - <valueCoding> - <extension url="http://dsf.dev/fhir/StructureDefinition/extension-process-authorization-organization-practitioner"> - <extension url="organization"> - <valueIdentifier> - <system value="http://dsf.dev/sid/organization-identifier"/> - <value value="My_Organization"/> - </valueIdentifier> - </extension> - <extension url="practitioner-role"> - <valueCoding> - <system value="http://dsf.dev/fhir/CodeSystem/practitioner-role"/> - <code value="DSF_ADMIN"/> - </valueCoding> - </extension> - </extension> - <system value="http://dsf.dev/fhir/CodeSystem/process-authorization"/> - <code value="LOCAL_ORGANIZATION_PRACTITIONER"/> - </valueCoding> - </extension> - <extension url="recipient"> - <valueCoding> - <extension url="http://dsf.dev/fhir/StructureDefinition/extension-process-authorization-organization"> - <valueIdentifier> - <system value="http://dsf.dev/sid/organization-identifier"/> - <value value="My_Organization"/> - </valueIdentifier> - </extension> - <system value="http://dsf.dev/fhir/CodeSystem/process-authorization"/> - <code value="LOCAL_ORGANIZATION"/> - </valueCoding> - </extension> - </extension> - <!-- version managed by bpe --> - <version value="#{version}"/> - <!-- date managed by bpe --> - <date value="#{date}"/> - <!-- status managed by bpe --> - <status value="unknown"/> -</ActivityDefinition> -``` -</details> - -#### 4. Regular Elements - -The only required elements in this set are `ActivityDefinition.url` and `ActivityDefinition.kind`. Check out the documentation on [URLs](../dsf/versions-placeholders-urls.md#urls) on how to choose the correct value for `ActivityDefinition.url`. `ActivityDefinition.kind` must have the value `Task`. -All other elements can technically be omitted. Still, we recommend you include the following elements: -- `AcitivityDefinition.name` -- `AcitivityDefinition.title` -- `AcitivityDefinition.subtitle` -- `AcitivityDefinition.experimental` -- `AcitivityDefinition.publisher` -- `AcitivityDefinition.contact` -- `AcitivityDefinition.description` - -<details> -<summary>Your finished ActivityDefinition should now look something like this</summary> - -```xml -<ActivityDefinition xmlns="http://hl7.org/fhir"> - <meta> - <tag> - <system value="http://dsf.dev/fhir/CodeSystem/read-access-tag" /> - <code value="ALL" /> - </tag> - </meta> - <extension url="http://dsf.dev/fhir/StructureDefinition/extension-process-authorization"> - <extension url="message-name"> - <valueString value="myMessage"/> - </extension> - <extension url="task-profile"> - <valueCanonical value="http://dsf.dev/fhir/StructureDefinition/my-task|#{version}"/> - </extension> - <extension url="requester"> - <valueCoding> - <extension url="http://dsf.dev/fhir/StructureDefinition/extension-process-authorization-organization-practitioner"> - <extension url="organization"> - <valueIdentifier> - <system value="http://dsf.dev/sid/organization-identifier"/> - <value value="My_Organization"/> - </valueIdentifier> - </extension> - <extension url="practitioner-role"> - <valueCoding> - <system value="http://dsf.dev/fhir/CodeSystem/practitioner-role"/> - <code value="DSF_ADMIN"/> - </valueCoding> - </extension> - </extension> - <system value="http://dsf.dev/fhir/CodeSystem/process-authorization"/> - <code value="LOCAL_ORGANIZATION_PRACTITIONER"/> - </valueCoding> - </extension> - <extension url="recipient"> - <valueCoding> - <extension url="http://dsf.dev/fhir/StructureDefinition/extension-process-authorization-organization"> - <valueIdentifier> - <system value="http://dsf.dev/sid/organization-identifier"/> - <value value="My_Organization"/> - </valueIdentifier> - </extension> - <system value="http://dsf.dev/fhir/CodeSystem/process-authorization"/> - <code value="LOCAL_ORGANIZATION"/> - </valueCoding> - </extension> - </extension> - <!-- version managed by bpe --> - <version value="#{version}"/> - <!-- date managed by bpe --> - <date value="#{date}"/> - <!-- status managed by bpe --> - <status value="unknown"/> - <url value="http://dsf.dev/bpe/Process/myProcess"/> - <kind value="Task"/> - <name value="My Process"/> - <title value="My Title For My Process"/> - <subtitle value="Information Processing Process"/> - <experimental value="false"/> - <publisher value="DSF"/> - <contact> - <name value="DSF"/> - <telecom> - <system value="email"/> - <value value="noreply@dsf.dev"/> - </telecom> - </contact> - <description value="My Process processes information"/> -</ActivityDefinition> -``` -</details> \ No newline at end of file diff --git a/docs/src/develop/guides/creating-codesystems-for-dsf-processes.md b/docs/src/develop/guides/creating-codesystems-for-dsf-processes.md deleted file mode 100644 index 5ab6d87f1..000000000 --- a/docs/src/develop/guides/creating-codesystems-for-dsf-processes.md +++ /dev/null @@ -1,42 +0,0 @@ ---- -title: Creating CodeSystems for DSF Processes -icon: creative ---- - -### Creating CodeSystems for DSF Processes - -You might find yourself in a situation where you need to create a [CodeSystem](../fhir/codesystem.md). For example, when defining the type of an [Input Parameter](../fhir/task.md#task-input-parameters). [CodeSystems](../fhir/codesystem.md) for the DSF differ from regular [CodeSystems](../fhir/codesystem.md) in that some element's values are managed by the DSF BPE server. You can use the following XML as a template: -```xml -<CodeSystem xmlns="http://hl7.org/fhir"> - <meta> - <tag> - <system value="http://dsf.dev/fhir/CodeSystem/read-access-tag" /> - <code value="ALL" /> - </tag> - </meta> - <url value="http://dsf.dev/fhir/CodeSystem/my-code-system" /> <!--dummy value--> - <!-- version managed by bpe --> - <version value="#{version}" /> - <name value="My CodeSystem" /> <!--dummy value--> - <title value="My CodeSystem Title" /> <!--dummy value--> - <!-- status managed by bpe --> - <status value="unknown" /> - <experimental value="false" /> - <!-- date managed by bpe --> - <date value="#{date}" /> - <publisher value="DSF" /> <!--dummy value--> - <description value="CodeSystem with codes for me" /> <!--dummy value--> - <caseSensitive value="true" /> - <hierarchyMeaning value="grouped-by" /> - <versionNeeded value="false" /> - <content value="complete" /> - <concept> - <code value="my-code" /> <!--dummy value--> - <display value="My Code" /> <!--dummy value--> - <definition value="My code used for myself" /> <!--dummy value--> - </concept> -</CodeSystem> -``` -Replace dummy values with appropriate values of your own. Do not change elements managed by the DSF BPE server. You can add as many codes as you like by defining more `concept` elements. - -The DSF BPE server will read your [CodeSystem](../fhir/codesystem.md) from `tutorial-process/src/main/resources/fhir/CodeSystem`. \ No newline at end of file diff --git a/docs/src/develop/guides/creating-task-resources-based-on-a-definition.md b/docs/src/develop/guides/creating-task-resources-based-on-a-definition.md deleted file mode 100644 index 6306ab128..000000000 --- a/docs/src/develop/guides/creating-task-resources-based-on-a-definition.md +++ /dev/null @@ -1,231 +0,0 @@ ---- -title: Creating Task Resources Based on a Definition -icon: creative ---- - -### Creating Task Resources Based on a Definition - -This short guide should help you understand how you can create [Task](../fhir/task.md) resources for use in [Starting A Process Via Task Resources](../guides/starting-a-process-via-task-resources.md). We will employ the use of the free version of [Forge](https://simplifier.net/forge?utm_source=firely-forge) to help with visualization. You are invited to create a free account and follow along, but we will include screenshots of relevant views either way. Remember that the free version of Forge [must not be used commercially](https://simplifier.net/pricing). As an example, we will create a [Task](../fhir/task.md) resource from the `task-start-dic-process.xml` profile. - -#### 1st Step: Removing Placeholders -`task-start-dic-process.xml` includes placeholders for the `version` and `date` elements. For the duration of this guide, you can either remove or comment these elements, so Forge does not try to perform type checking on them, which would result in an error and Forge not loading the file. - -#### 2nd Step: Differential Chain -If the resource profile is only available as a [differential](https://www.hl7.org/fhir/R4/profiling.html#snapshot), like in our case, we will want to aggregate the changes made to the base resource (in this case [Task](../fhir/task.md)) by all profiles to make it more readable. To do this, we first need all the profiles involved. We already have `task-start-dic-process.xml` in our `StructureDefinition` folder. It lists a resource called `task-base` in its `baseDefinition` element. This resource is part of the DSF and can be found [here](https://github.com/datasharingframework/dsf/blob/main/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/StructureDefinition/dsf-task-base-1.0.0.xml). Put it into the `StructureDefinition` folder. Since `task-base` has the original FHIR Task as its `baseDefinition` element, we are done with this chain. In forge, you should now be able to open the `StructureDefinition` folder and select the `task-start-dic-process.xml` profile. It should look something like this: - -![Forge overview](/photos/developer-documentation/forge_overview.png) - -#### 3rd Step: Building the Task Resource -We will now go through each element one by one and include it into our [Task](../fhir/task.md) resource, provided it is mandatory (cardinality at least `1..1`) according to the profile. It is important that you not use any placeholders like `#{version}` for resources not read by the DSF BPE server. This is the case if we want a [Task](../fhir/task.md) resource for use with [cURL](../guides/starting-a-process-via-task-resources.md#using-curl). But, placeholders should be used in [Draft Task Resources](../dsf/draft-task-resources.md) instead of actual values wherever possible, since those are read by the DSF BPE server. This guide will create a [Task](../fhir/task.md) resource without placeholders. We will start out with the base element for all [Task](../fhir/task.md) resources: -```xml -<Task xmlns="http://hl7.org/fhir"> - -</Task> -``` - -Before we start adding any elements listed in Forge's element tree, we have to include the `Task.meta.profile` element. Its requirement cannot be seen here which is why we mention it specifically. This is the only instance you will not see it in the element tree. It should look like this: -```xml -<Task xmlns="http://hl7.org/fhir"> - <meta> - <profile value="http://dsf.dev/fhir/StructureDefinition/task-start-dic-process|1.0"/> - </meta> -</Task> -``` - -The first element which can be found in the element tree is the `instantiatesCanonical` element. To add it, we will create an XML element with the same name and the value according to [URLs](../dsf/versions-placeholders-urls.md#urls): -```xml -<Task xmlns="http://hl7.org/fhir"> - <meta> - <profile value="http://dsf.dev/fhir/StructureDefinition/task-start-dic-process|1.0"/> - </meta> - <instantiatesCanonical value="http://dsf.dev/bpe/Process/dicProcess|1.0" /> -</Task> -``` -We can continue this process for all primitive elements like these. Just make sure you pay attention to use the correct data type (e.g. proper coding value for elements with `coding` type). - -By now your [Task](../fhir/task.md) resources should look something like this: -<details> -<summary>Suggested solution</summary> - -```xml -<Task xmlns="http://hl7.org/fhir"> - <meta> - <profile value="http://dsf.dev/fhir/StructureDefinition/task-start-dic-process|1.0"/> - </meta> - <instantiatesCanonical value="http://dsf.dev/bpe/Process/dicProcess|1.0" /> - <status value="requested"/> - <intent value="order"/> - <authoredOn value="2024-02-08T10:00:00+00:00" /> -</Task> -``` -</details> - -Let us look at a more complex element like the `requester` element: - -![Forge requester view](/photos/developer-documentation/forge_requester_view.png) - -We will start the same way we started with primitive elements, by adding the `requester` element: -```xml -<Task xmlns="http://hl7.org/fhir"> - <meta> - <profile value="http://dsf.dev/fhir/StructureDefinition/task-start-dic-process|1.0"/> - </meta> - <instantiatesCanonical value="http://dsf.dev/bpe/Process/dicProcess|1.0" /> - <status value="requested"/> - <intent value="order"/> - <authoredOn value="2024-02-08T10:00:00+00:00" /> - <requester> - - </requester> -</Task> -``` - -Then, we will add primitive elements to `requester` like we did before for `Task`: -```xml -<Task xmlns="http://hl7.org/fhir"> - <meta> - <profile value="http://dsf.dev/fhir/StructureDefinition/task-start-dic-process|1.0"/> - </meta> - <instantiatesCanonical value="http://dsf.dev/bpe/Process/dicProcess|1.0" /> - <status value="requested"/> - <intent value="order"/> - <authoredOn value="2024-02-08T10:00:00+00:00" /> - <requester> - <type value="Organization"/> - </requester> -</Task> -``` -*Important to note here that the value for the `status` will always be `requested` for Tasks being posted using cURL and the `type` element for `requester` and `recipient` will always have the value `Organization` in the DSF context.* - -Next, we will add the `identifier` element and its primitive sub-elements just like we started out doing it for the `requester` element. The `identifier.value` in this case will be `dic.dsf.test`. To understand why, take a look at the topic on [organization identifiers](../dsf/organization-identifiers.md): -```xml -<Task xmlns="http://hl7.org/fhir"> - <meta> - <profile value="http://dsf.dev/fhir/StructureDefinition/task-start-dic-process|1.0"/> - </meta> - <instantiatesCanonical value="http://dsf.dev/bpe/Process/dicProcess|1.0" /> - <status value="requested"/> - <intent value="order"/> - <authoredOn value="2024-02-08T10:00:00+00:00" /> - <requester> - <type value="Organization"/> - <identifier> - <system value="http://dsf.dev/sid/organization-identifier"/> - <value value="dic.dsf.test" /> - </identifier> - </requester> -</Task> -``` -*Notice that `requester.identifier.system` has a `Fixed value` annotation. You can see what the value is supposed to be by clicking on the `system` element in Forge or looking at the XML for the right Task profile. The right side will have all information about that element, including the actual value for `Fixed value`.* - -You should now be able to fill out all elements in your [Task](../fhir/task.md) resource until you reach the [slicing](https://www.hl7.org/fhir/R4/profiling.html#slicing) for `Task.input`. Your [Task](../fhir/task.md) resource should look something like this: -<details> -<summary>Suggested solution</summary> - -```xml -<Task xmlns="http://hl7.org/fhir"> - <meta> - <profile value="http://dsf.dev/fhir/StructureDefinition/task-start-dic-process|1.0"/> - </meta> - <instantiatesCanonical value="http://dsf.dev/bpe/Process/dicProcess|1.0" /> - <status value="requested"/> - <intent value="order"/> - <authoredOn value="2024-02-08T10:00:00+00:00" /> - <requester> - <type value="Organization"/> - <identifier> - <system value="http://dsf.dev/sid/organization-identifier"/> - <value value="dic.dsf.test" /> - </identifier> - </requester> - <restriction> - <recipient> - <type value="Organization"/> - <identifier> - <system value="http://dsf.dev/sid/organization-identifier" /> - <value value="dic.dsf.test" /> - </identifier> - </recipient> - </restriction> -</Task> -``` -</details> - - -[Slicings](https://www.hl7.org/fhir/R4/profiling.html#slicing) are a bit different from regular elements. Let us look at the slice `message-name`: - -![Forge slice message name](/photos/developer-documentation/forge_slice_message_name.png) - -If we were to continue including slices to the [Task](../fhir/task.md) resource like we did so far, we would add a `message-name` element to our XML like this: - -```xml -<Task xmlns="http://hl7.org/fhir"> - ... - <input> - <message-name> - ... - </message-name> - </input> -</Task> -``` - -This approach however, would not work. FHIR processors do not use the name of the slice to map entries in your [Task](../fhir/task.md) resource to the correct slice. They use [discriminators](https://www.hl7.org/fhir/R4/profiling.html#discriminator). Discriminators define the elements a processor needs to distinguish slices by. You can see how the discriminator is configured by selecting the `input` element in Forge. In our case, a processor would look at the values for `input.type.coding.system` and `input.type.coding.code` to determine which slice this element belongs to. This only works because `input.type.coding.system` and `input.type.coding.code` are present in all slices and have a `Fixed value`. You can learn more about discriminators [here](https://www.hl7.org/fhir/R4/profiling.html#discriminator). All this means is that we effectively ignore the name of the slice as an element and start adding elements like we did before: - -```xml -<Task xmlns="http://hl7.org/fhir"> - ... - <input> - <type> - <coding> - <system value="http://dsf.dev/fhir/CodeSystem/bpmn-message" /> - <code value="message-name" /> - </coding> - </type> - <valueString value="dicProcess" /> - </input> -</Task> -``` - -Now you should be able to add all remaining mandatory elements to your [Task](../fhir/task.md) resource on your own. In the end, it should look something like this: -<details> -<summary>Suggested solution</summary> - -```xml -<Task xmlns="http://hl7.org/fhir"> - <meta> - <profile value="http://dsf.dev/fhir/StructureDefinition/task-start-dic-process|1.0"/> - </meta> - <instantiatesCanonical value="http://dsf.dev/bpe/Process/dicProcess|1.0" /> - <status value="requested"/> - <intent value="order"/> - <authoredOn value="2024-02-08T10:00:00+00:00" /> - <requester> - <type value="Organization"/> - <identifier> - <system value="http://dsf.dev/sid/organization-identifier"/> - <value value="dic.dsf.test" /> - </identifier> - </requester> - <restriction> - <recipient> - <type value="Organization"/> - <identifier> - <system value="http://dsf.dev/sid/organization-identifier" /> - <value value="dic.dsf.test" /> - </identifier> - </recipient> - </restriction> - <input> - <type> - <coding> - <system value="http://dsf.dev/fhir/CodeSystem/bpmn-message" /> - <code value="message-name" /> - </coding> - </type> - <valueString value="dicProcess"/> - </input> -</Task> -``` -</details> - -**Do not forget to restore the version and date placeholders in `task-start-dic-process.xml`!** \ No newline at end of file diff --git a/docs/src/develop/guides/creating-valuesets-for-dsf-processes.md b/docs/src/develop/guides/creating-valuesets-for-dsf-processes.md deleted file mode 100644 index f273196ec..000000000 --- a/docs/src/develop/guides/creating-valuesets-for-dsf-processes.md +++ /dev/null @@ -1,63 +0,0 @@ ---- -title: Creating ValueSets for DSF Processes -icon: creative ---- - -### Creating ValueSets for DSF Processes - -You might find yourself in the situation where you need to create a [ValueSet](../fhir/valueset.md). For example, when adding [Input Parameters](../fhir/task.md#task-input-parameters) to DSF [Task](../fhir/task.md) resources, you will also have to reference a [ValueSet](../fhir/valueset.md) resource in your binding for `Task.input.type` to be able to set the type of your [Input Parameter](../fhir/task.md#task-input-parameters). [ValueSets](../fhir/valueset.md) for the DSF differ from regular [ValueSets](../fhir/valueset.md) in that some element's values are managed by the DSF BPE server. You can use the following template for your -[ValueSet](../fhir/valueset.md): -```xml -<ValueSet xmlns="http://hl7.org/fhir"> - <meta> - <tag> - <system value="http://dsf.dev/fhir/CodeSystem/read-access-tag" /> - <code value="ALL" /> - </tag> - </meta> - <url value="http://dsf.dev/fhir/ValueSet/my-value-set"/> <!--dummy value--> - <!-- version managed by bpe --> - <version value="#{version}" /> - <name value="My ValueSet"/> <!--dummy value--> - <title value="My ValueSet Title"/> <!--dummy value--> - <!-- status managed by bpe --> - <status value="unknown" /> - <experimental value="false"/> - <!-- date managed by bpe --> - <date value="#{date}"/> - <publisher value="DSF"/> <!--dummy value--> - <description value="ValueSet with all codes from my-code-system"/> <!--dummy value--> - <immutable value="true"/> - <compose> - <include> - <system value="http://dsf.dev/fhir/CodeSystem/my-code-system"/> <!--dummy value--> - <version value="#{version}"/> - </include> - </compose> -</ValueSet> -``` -Replace dummy values with appropriate values of your own. Do not change elements managed by the DSF BPE server. The `compose` element defines the codes included in this [ValueSet](../fhir/valueset.md). It holds at least one `include` element. Each `include` element refers to a [CodeSystem](../fhir/codesystem.md) and contains a list of `concept` elements which in turn contain the actual `code` element. Using one code from `my-code-system` and one code from `my-other-code-system` would result in the following `compose` element: -```xml -<ValueSet xmlns="http://hl7.org/fhir"> - ... - <compose> - <include> - <system value="http://dsf.dev/fhir/CodeSystem/my-code-system"/> - <version value="#{version}"/> - <concept> - <code value="my-code"/> - </concept> - </include> - <include> - <system value="http://dsf.dev/fhir/CodeSystem/my-other-code-system"/> - <version value="#{version}"/> - <concept> - <code value="my-other-code"/> - </concept> - </include> - </compose> -</ValueSet> -``` -The DSF BPE server will read your [ValueSet](../fhir/valueset.md) from `tutorial-process/src/main/resources/fhir/ValueSet`. - -You might also want to check out [this guide](../guides/creating-codesystems-for-dsf-processes.md) on how to create [CodeSystems](../fhir/codesystem.md). \ No newline at end of file diff --git a/docs/src/develop/guides/index.md b/docs/src/develop/guides/index.md deleted file mode 100644 index 2841de106..000000000 --- a/docs/src/develop/guides/index.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -title: Guides -icon: creative ---- - -## Details -- [Accessing BPMN Process Variables](accessing-bpmn-process-variables.md) -- [Accessing Task Resources During Execution](accessing-task-resources-during-execution.md) -- [Adding Task Input Parameters to Task Profiles](adding-task-input-parameters-to-task-profiles.md) -- [Configuring Read Access Tags](configuring-read-access-tags.md) -- [Creating ActivityDefinitions](creating-activity-definitions.md) -- [Creating CodeSystems for DSF Processes](creating-codesystems-for-dsf-processes.md) -- [Creating Task Resources Based on a Definition](creating-task-resources-based-on-a-definition.md) -- [Creating ValueSets for DSF Processes](creating-valuesets-for-dsf-processes.md) -- [Managing Multiple Incoming Messages and Missing Messages](managing-mutiple-incoming-messages-and-missing-messages.md) -- [Setting Targets for Message Events](setting-targets-for-message-events.md) -- [Starting a Process via Task Resources](starting-a-process-via-task-resources.md) \ No newline at end of file diff --git a/docs/src/develop/guides/managing-mutiple-incoming-messages-and-missing-messages.md b/docs/src/develop/guides/managing-mutiple-incoming-messages-and-missing-messages.md deleted file mode 100644 index a0c8f6120..000000000 --- a/docs/src/develop/guides/managing-mutiple-incoming-messages-and-missing-messages.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -title: Managing Multiple Incoming Messages and Missing Messages -icon: creative ---- - -### Managing Multiple Incoming Messages and Missing Messages - -If an already running process instance is waiting for a message from another organization, the corresponding FHIR [Task](../fhir/task.md) may never arrive. Either because the other organization decides to never send the message or because some technical problem prohibits the [Task](../fhir/task.md) resource from being posted to the DSF FHIR server. This would result in stale process instances that never finish. - -At the same time, you might also expect to receive one out of a number of different message types at once. - -In order to solve both problems we can add an [Event Based Gateway](../bpmn/gateways.md#event-based-gateway) to the process waiting for a response and then either handle a [Task](../fhir/task.md) resource with the response and finish the process in a success state or trigger a [Timer Intermediate Catching Event](../bpmn/timer-intermediate-catching-events.md) after a defined wait period and finish the process in an error state. The following BPMN collaboration diagram shows how the process at the first organization would look like if we wanted to react to multiple different messages or missing messages: - -<picture> - <source media="(prefers-color-scheme: dark)" srcset="/photos/developer-documentation/event_based_gateway_inverted.svg"> - <source media="(prefers-color-scheme: light)" srcset="/photos/developer-documentation/event_based_gateway.svg"> - <img alt="BPMN collaboration diagram with an Event Based Gateway" src="/photos/developer-documentation/event_based_gateway.svg"> -</picture> diff --git a/docs/src/develop/guides/setting-targets-for-message-events.md b/docs/src/develop/guides/setting-targets-for-message-events.md deleted file mode 100644 index 68db0b1e0..000000000 --- a/docs/src/develop/guides/setting-targets-for-message-events.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -title: Setting Targets for Message Events -icon: creative ---- - -### Setting Targets for Message Events - -Setting a target for a message event requires a `Target` object. To create one, you require a target's organization identifier, endpoint identifier and endpoint address. You can find these values by visiting the DSF FHIR server's web interface. In the top right corner, click the `Show Bookmarks` button, then select `Endpoint`. You will be taken to a list of all Endpoints available to the FHIR server. There are two ways of adding `targets` to the BPMN execution variables: -#### 1. Adding the target in the message event implementation -In your message event implementation (the class extending `AbstractTaskMessageSend`), you can override `AbstractTaskMessageSend#doExecute`, add your targets and then call the super-method. -#### 2. Adding the target in a service task right before the message event -This is the preferred method of this tutorial but both methods will work perfectly fine. For our use cases, we usually prefer this one since there is enough complexity to warrant putting it into a separate BPMN [Service Task](../bpmn/service-tasks.md). - -In both cases you can access methods to create and set `targets` through the `Variables` instance. diff --git a/docs/src/develop/guides/starting-a-process-via-task-resources.md b/docs/src/develop/guides/starting-a-process-via-task-resources.md deleted file mode 100644 index baa36a7bb..000000000 --- a/docs/src/develop/guides/starting-a-process-via-task-resources.md +++ /dev/null @@ -1,43 +0,0 @@ ---- -title: Starting a Process via Task Resources -icon: creative ---- - -### Starting a Process via Task Resources - -To start a BPMN process, you need to create new a [Task](../fhir/task.md) resource in the DSF FHIR server by sending an HTTP request according to the [FHIR RESTful API](https://www.hl7.org/fhir/R4/http.html). Specifically, you need to [create](https://www.hl7.org/fhir/R4/http.html#create) -a resource for the first time. Also, remember that the [Task](../fhir/task.md) resource you are sending needs to comply to the [Task](../fhir/task.md) profile of the process you want to start and the [ActivityDefinition's](../fhir/activitydefinition.md) authorization rules. -There are two major ways of making this HTTP request: -1. Using cURL -2. Using the DSF FHIR server's web interface - -#### Using cURL -In order to use cURL, you will have to create an appropriate [Task](../fhir/task.md) resource to post to the DSF FHIR server. There already is a file called `example-task.xml` located in `tutorial-process/src/main/resources/fhir`. You can use this as your starting point. You can try to follow [this guide](../guides/creating-task-resources-based-on-a-definition.md), or you can check the solution branches for this file if you need ideas on how to fill it out properly. - -Below are some cURL command skeletons. Replace all <>-Placeholders with appropriate values. Host name depends on the instance you want to address. - -##### Linux: -```shell -curl https://<instance-host-name>/fhir/Task \ ---cacert <path/to/ca-certificate-file.pem> \ ---cert <path/to/client-certificate-file.pem>:password \ ---key <path/to/client-private-key-file.pem> \ --H "Content-Type: application/fhir+xml" \ --H "Accept: application/fhir+xml" \ --d @<path/to/example-task.xml> -``` -##### Windows CMD: -```shell -curl https://<instance-host-name>/fhir/Task ^ ---cacert <path/to/ca-certificate-file.pem> ^ ---cert <path/to/client-certificate-file.pem>:password ^ ---key <path/to/client-private-key-file.pem> ^ --H "Content-Type: application/fhir+xml" ^ --H "Accept: application/fhir+xml" ^ --d @<path/to/example-task.xml> -``` -*This may throw an error depending on which version of cURL Windows is using. If this is the case for you after making sure you entered everything correctly, you can try using Git's version of cURL instead by adding it to the very top of your system's PATH environment variable. Git's cURL is usually situated in C:\Program Files\Git\mingw64\bin.* - -#### Using the DSF FHIR Server's Web Interface - -When visiting the web interface of a DSF FHIR server instance (e.g. https://instance-name/fhir), you can query the DSF FHIR server using the [FHIR RESTful API](https://www.hl7.org/fhir/R4/http.html) to return a list of all [Draft Task Resources](../dsf/draft-task-resources.md). These [Task](../fhir/task.md) resources act like a template you can use to instantiate [Task](../fhir/task.md) resources which start BPMN processes. Instead of querying the DSF FHIR server manually, you can use a predefined bookmark to navigate to the query URL. You can find a list of Bookmarks in the top right corner of the web interface. Simply select the bookmark referencing `?_sort=_profile,identifier&status=draft` under the `Task` section, and you will be taken to the list of all [Draft Task Resources](../dsf/draft-task-resources.md). Once there, you can select the one which starts your BPMN process. It will take you to a detailed view of the resource where you will also have the chance to fill any [Task Input Parameters](../fhir/task.md#task-input-parameters) you might need to specify. If everything is filled out correctly, you may start your process by clicking `Start Process`. Keep in mind that, for [Draft Task Resources](../dsf/draft-task-resources.md) to be available, you need to include them in your mapping for your BPMN process ID in `ProcessPluginDefinition#getFhirResourcesByProcessId`. Take a look at [the Process Plugin Definition](../dsf/process-plugin-definition.md) if you need a reminder. \ No newline at end of file diff --git a/docs/src/develop/index.md b/docs/src/develop/index.md deleted file mode 100644 index ca799dea6..000000000 --- a/docs/src/develop/index.md +++ /dev/null @@ -1,47 +0,0 @@ ---- -title: Developer Documentation -icon: creative ---- - -## BPMN -- [Conditions](bpmn/conditions.md) -- [Gateways](bpmn/gateways.md) -- [Messaging](bpmn/messaging.md) -- [Sequence Flow](bpmn/sequence-flow.md) -- [Service Tasks](bpmn/service-tasks.md) -- [Timer Intermediate Catching Events](bpmn/timer-intermediate-catching-events.md) - -## FHIR -- [ActivityDefinition](fhir/activitydefinition.md) -- [Codesystem](fhir/codesystem.md) -- [Task](fhir/task.md) -- [ValueSet](fhir/valueset.md) - -## DSF -- [BPMN Process Execution](dsf/bpmn-process-execution.md) -- [BPMN Process Variables](dsf/bpmn-process-variables.md) -- [Draft Task Resources](dsf/draft-task-resources.md) -- [Environment Variables](dsf/environment-variables.md) -- [Message Correlation](dsf/message-correlation.md) -- [Message Delegates](dsf/message-delegates.md) -- [Organization Identifiers](dsf/organization-identifiers.md) -- [Process Plugin API](dsf/process-plugin-api.md) -- [Process Plugin Definition](dsf/process-plugin-definition.md) -- [Read Access Tag](dsf/read-access-tag.md) -- [Requester and Recipient](dsf/requester-and-recipient.md) -- [Service Delegates](dsf/service-delegates.md) -- [Spring Framework Integration](dsf/spring-framework-integration.md) -- [Versions, Placeholders and URLs](dsf/versions-placeholders-urls.md) - -## Guides -- [Accessing BPMN Process Variables](guides/accessing-bpmn-process-variables.md) -- [Accessing Task Resources During Execution](guides/accessing-task-resources-during-execution.md) -- [Adding Task Input Parameters to Task Profiles](guides/adding-task-input-parameters-to-task-profiles.md) -- [Configuring Read Access Tags](guides/configuring-read-access-tags.md) -- [Creating ActivityDefinitions](guides/creating-activity-definitions.md) -- [Creating CodeSystems for DSF Processes](guides/creating-codesystems-for-dsf-processes.md) -- [Creating Task Resources Based on a Definition](guides/creating-task-resources-based-on-a-definition.md) -- [Creating ValueSets for DSF Processes](guides/creating-valuesets-for-dsf-processes.md) -- [Managing Multiple Incoming Messages and Missing Messages](guides/managing-mutiple-incoming-messages-and-missing-messages.md) -- [Setting Targets for Message Events](guides/setting-targets-for-message-events.md) -- [Starting a Process via Task Resources](guides/starting-a-process-via-task-resources.md) \ No newline at end of file From e1051bf0115f7506f7cb39fd4e99d6d3acc1dfe9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20B=C3=B6hringer?= <jan.boehringer@hs-heilbronn.de> Date: Wed, 28 May 2025 11:39:26 +0200 Subject: [PATCH 14/14] Fixed broken links --- docs/src/community/README.md | 2 +- .../api-v1/guides/user-tasks-in-the-dsf.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/src/community/README.md b/docs/src/community/README.md index e057b760c..fe99a37cb 100644 --- a/docs/src/community/README.md +++ b/docs/src/community/README.md @@ -7,5 +7,5 @@ icon: creative - [Consultation Hours](./consultation-hours.md) - [Team](./team.md) - [Communication](./communication.md) -- [Contribute](./contribute/readme.md) +- [Contribute](./contribute/README.md) - [DSF Ecosystem](./ecosystem.md) diff --git a/docs/src/process-development/api-v1/guides/user-tasks-in-the-dsf.md b/docs/src/process-development/api-v1/guides/user-tasks-in-the-dsf.md index 6bd4ca28b..3c987de8a 100644 --- a/docs/src/process-development/api-v1/guides/user-tasks-in-the-dsf.md +++ b/docs/src/process-development/api-v1/guides/user-tasks-in-the-dsf.md @@ -5,9 +5,9 @@ icon: creative ### User Tasks in the DSF -Creating a [User Task](../concepts/bpmn/user-tasks.md) in a BPMN model, causes the DSF to automatically generate a [QuestionnaireResponse](https://www.hl7.org/fhir/R4/questionnaireresponse.html) resource according to a [Questionnaire](https://www.hl7.org/fhir/R4/questionnaire.html) you provided in the [User Task's](../concepts/bpmn/user-tasks.md) `Forms` field when the process execution reaches the [User Task](../concepts/bpmn/user-tasks.md). The `Forms` field needs to have a type of `Embedded or External Task Forms` with the `Form key` being the url of your [Questionnaire](https://www.hl7.org/fhir/R4/questionnaire.html) resource. The [Questionnaire](https://www.hl7.org/fhir/R4/questionnaire.html) resource needs to be put in the `src/main/resources/fhir/Questionnaire` directory. The generated [QuestionnaireResponse](https://www.hl7.org/fhir/R4/questionnaireresponse.html) can now be answered by locating the [QuestionnaireResponse](https://www.hl7.org/fhir/R4/questionnaireresponse.html) in the DSF FHIR server UI through `https://your.dsf.fhir.server/fhir/QuestionnaireResponse?_sort=-_lastUpdated&status=in-progress`. After filling out the [QuestionnaireResponse](https://www.hl7.org/fhir/R4/questionnaireresponse.html) and submitting it, the process execution will continue with the next BPMN element after the [User Task](../concepts/bpmn/user-tasks.md) and the updated [QuestionnaireResponse](https://www.hl7.org/fhir/R4/questionnaireresponse.html) will be available through the [Process Plugin Api's](../concepts/dsf/process-api.md) `Variables` instance by calling `getLatestReceivedQuestionnaireResponse()`. +Creating a [User Task](../bpmn/user-tasks.md) in a BPMN model, causes the DSF to automatically generate a [QuestionnaireResponse](https://www.hl7.org/fhir/R4/questionnaireresponse.html) resource according to a [Questionnaire](https://www.hl7.org/fhir/R4/questionnaire.html) you provided in the [User Task's](../bpmn/user-tasks.md) `Forms` field when the process execution reaches the [User Task](../bpmn/user-tasks.md). The `Forms` field needs to have a type of `Embedded or External Task Forms` with the `Form key` being the url of your [Questionnaire](https://www.hl7.org/fhir/R4/questionnaire.html) resource. The [Questionnaire](https://www.hl7.org/fhir/R4/questionnaire.html) resource needs to be put in the `src/main/resources/fhir/Questionnaire` directory. The generated [QuestionnaireResponse](https://www.hl7.org/fhir/R4/questionnaireresponse.html) can now be answered by locating the [QuestionnaireResponse](https://www.hl7.org/fhir/R4/questionnaireresponse.html) in the DSF FHIR server UI through `https://your.dsf.fhir.server/fhir/QuestionnaireResponse?_sort=-_lastUpdated&status=in-progress`. After filling out the [QuestionnaireResponse](https://www.hl7.org/fhir/R4/questionnaireresponse.html) and submitting it, the process execution will continue with the next BPMN element after the [User Task](../bpmn/user-tasks.md) and the updated [QuestionnaireResponse](https://www.hl7.org/fhir/R4/questionnaireresponse.html) will be available through the [Process Plugin Api's](../dsf/process-plugin-api.md) `Variables` instance by calling `getLatestReceivedQuestionnaireResponse()`. -You also have the option to register a [Task Listener](https://docs.camunda.org/manual/7.21/user-guide/process-engine/delegation-code/#task-listener) on the [User Task](../concepts/bpmn/user-tasks.md). This allows you to manipulate the [QuestionnaireResponse](https://www.hl7.org/fhir/R4/questionnaireresponse.html) before it is posted to the DSF FHIR server. You do this by extending the `DefaultUserTaskListener` class which provides overrides to interact with the [QuestionnaireResponse](https://www.hl7.org/fhir/R4/questionnaireresponse.html). Notice that dynamically changing the `item.text` value of an item in a [QuestionnaireResponse](https://www.hl7.org/fhir/R4/questionnaireresponse.html) (that is **NOT** of type `display`) is not allowed. For that, you would have to change the `item.text` value of the corresponding [Questionnaire](https://www.hl7.org/fhir/R4/questionnaire.html) resource as well. Instead, you should have an item of type `display` above the item whose text should change dynamically, like in the template, and change its `item.text` value. In this case, you may also leave out `item.text` element of the item below the display item. +You also have the option to register a [Task Listener](https://docs.camunda.org/manual/7.21/user-guide/process-engine/delegation-code/#task-listener) on the [User Task](../bpmn/user-tasks.md). This allows you to manipulate the [QuestionnaireResponse](https://www.hl7.org/fhir/R4/questionnaireresponse.html) before it is posted to the DSF FHIR server. You do this by extending the `DefaultUserTaskListener` class which provides overrides to interact with the [QuestionnaireResponse](https://www.hl7.org/fhir/R4/questionnaireresponse.html). Notice that dynamically changing the `item.text` value of an item in a [QuestionnaireResponse](https://www.hl7.org/fhir/R4/questionnaireresponse.html) (that is **NOT** of type `display`) is not allowed. For that, you would have to change the `item.text` value of the corresponding [Questionnaire](https://www.hl7.org/fhir/R4/questionnaire.html) resource as well. Instead, you should have an item of type `display` above the item whose text should change dynamically, like in the template, and change its `item.text` value. In this case, you may also leave out `item.text` element of the item below the display item. Below you can find a template for a [Questionnaire](https://www.hl7.org/fhir/R4/questionnaire.html) resource. Replace `questionnaire-name` with the name of your [Questionnaire](https://www.hl7.org/fhir/R4/questionnaire.html) and have the file be named the same. The items `business-key` and `user-task-id` are required by the DSF and are always included. You can then add any amount of items of your choosing to the [Questionnaire](https://www.hl7.org/fhir/R4/questionnaire.html).