Documentation

Workspaces

Workspaces are designed to enable collaborative work on decision models. For example, workspaces can be shared with other users to work together or to get some feedback. As you will see, declab's features are always associated to a single workspace. This ensures that changes made by one user to his project do not affect other users and their projects.

Viewing all Workspaces

When you open declab for the first time, you will be redirected to the workspace overview where all existing workspaces are displayed. Alternatively, if you are already inside the workspace, you can access the workspace overview from the navigation bar by clicking on the declab icon.

For each workspace, its name, description and access mode is displayed. Since the list of existing workspaces can quickly become confusing, there is a search feature at the top of the list that can be used to filter it. When you have found the workspace you were looking for, you can enter it by clicking on its name.

If the workspace is private and therefore protected with a password, you will be requested to enter it. For more information about protecting a workspace with a password, please refer to the section Creating a Workspace.

Creating a Workspace

When creating a workspace, several settings can be made. Some of them are required, others are optional.

The first two input fields are the name (required) and description (optional) of the workspace. They are displayed in the list of all existing workspaces and help to identify them. The third input field is the access mode (required) of the workspace. There are three different modes to choose from:

Access Mode Description
Public Anonymous users can create, read, update and delete entities inside this workspace.
Protected Anonymous users can read, authenticated users can also create, update and delete entities inside this workspace.
Private Anonymous users can't enter the workspace, authenticated users can create, read, update and delete entities inside this workspace.

The fourth input field is the password (required if the access mode is set to protected or private, otherwise optional) of the workspace. It allows the user to authenticate within the workspace to access entities that would otherwise be, based on the access mode of the workspace, not available to anonymous users.

Editing a Workspace

All settings that were made during the creation of the workspace can be changed in the workspace settings. To do this, you first have to enter the workspace. Afterwards, there is a gear wheel on the right side of the navigation bar () that will redirect you to the workspace settings.

For detailed information on the first four settings, please refer to the section Creating a Workspace. The fifth input field allows you to enable the developer mode. The developer mode allows you to use features such as raw JSON in the builder. It is intended for developers and should be used with caution.

Deleting a Workspace

To delete a workspace, you first have to enter it. After you do so, there is a gear wheel on the right side of the navigation bar () that will redirect you to the workspace settings. On the right side of the workspace settings, you will find a card titled Deletion. By clicking on the button titled Delete inside the card, the workspace will be deleted and you will be redirected to the list of all existing workspaces. Please note that the deletion of workspaces is permanent and cannot be undone.

Models

The model page is designed to provide an overview of all models and their entities within the workspace. In addition, the page can also be used to manage them: You can import new models, change the order of the imported models, download imported models and delete imported models that are no longer needed.

When you enter a workspace, you will be redirected to the model page. Alternatively, if you are already inside the workspace, you can access the model page from the navigation bar by selecting Execution πŸ‘’ Model.

Viewing all Models

To illustrate declab's features in the next sections, we will use the decision models from the test case 0086-import of the Decision Model and Notation Technology Compatibility Kit. The test case consists of two .dmn files. The first .dmn file is Imported_Model.dmn that contains a business knowledge model named Say Hello. The second .dmn file is 0086-import.dmn that contains an input named A Person and a decision named A Decision Ctx with DT that will reference the business knowledge model named Say Hello from the first .dmn file to return a greeting based on the input.

Creating a Model

For some time now, declab also offers the possibility to create models directly. You can do so by clicking on the icon.

The created model is then displayed directly above the clicked icon and is given a randomly generated name and namespace. Don't worry, you can change the name and namespace later! To do so, just click on the icon and wait for the editor to load. Afterwards, you will find the pencil icon (1) on the right side. If you click on it, you will find the relevant input fields to change the name (2) and the namespace (3) in the opening sidebar.

To get more information about the editor, please refer to the section Editing a Model.

Importing a Model

To import decision models into declab, you can drag and drop them onto the icon. Please note that the order of importing the models is important. Since the second .dmn file references the first .dmn file, the first .dmn file must be uploaded first, otherwise, the reference of the second .dmn file cannot be resolved.

If the models could be imported successfully, information about the Decisions, Inputs, Business Knowledge Models and Decision Services inside the model is displayed.

If messages occurred during the import of the models, detailed information about the underlying cause is displayed. If, for example, the order of importing is not respected by importing the second .dmn file before the first one, the import will fail and an error will be displayed.

There are currently three types of messages that can be returned during the import:

Message Type Description
Indicates that the message is only an information to help the user to understand what happened during the import.
Indicates that the message is a warning that can potentially lead to unexpected behavior but does not prevent the import.
Indicates that the message is an error that prevents the import. It must be corrected by the user.

If the import of a model failed, declab cannot extract any information from the model, a corresponding error message is displayed. Please note that in this state, other declab features will also not work as expected.

The good news is that even in this state, the model can still be opened with the editor. After all errors within the model have been corrected, the information is displayed again.

Editing a Model

If you want to edit imported models, just click on the icon and wait for the editor to load. The used editor is an integrated version of the Kogito Editor that is provided by Red Hat. The documentation for the editor can be found at https://docs.jboss.org/kogito/release/latest/html_single/#collection-kogito-developing-decision-services. We have extended the editor slightly to make some of declab's functionality usable directly from the editor:

This means, for example, that you can see after each change whether the model can be imported in its current state and whether it contains any errors. If you want to see more information as to why the import failed, just click on the button (1), additional information will be displayed. Another helpful feature is the model synchronization. If changes are made to the model, it is imported directly and is available for all other declab features without manually reloading the page. This is even the case across users. If you want to work collaboratively on the model with colleagues, their page will also recognize the change. You can see the current state of the collaboration under (2). Although it should not be necessary, you can also start the synchronization manually by clicking on it. If you have made any changes by mistake, you can also undo or redo them by using the respective buttons (3).

Builder

The builder is probably the most used page during modeling. It allows you to enter some sample input, send it to the imported model and analyze the outputs. This way, you can be assured that the modeled decisions perform correct calculations.

To illustrate the builder, we will use the decision model from the test case 0003-input-data-string-allowed-values of the Decision Model and Notation Technology Compatibility Kit. The test case consists of one .dmn file that contains an input named Employment Status and a decision named Employment Status Statement Β that will return a greeting based on the input.

There is a lot going on, but you will see in the next paragraphs how everything is working together to create quite a powerful utility.

The use usually begins on the left side. There, you can fill out the form that is displayed based on the input structure and will ultimately generate the input that will be sent to the imported model (1). The calculated outputs can then be found on the right side (2). The convenient part is that the outputs are automatically recalculated whenever you make changes on the left side so you can see in real-time what effects your changes have. If you are interested in how the outputs are calculated, the Access Log could be quite helpful (3). It shows what data is entering a decision (or a knowledge model) and what data is returned. If you have created a combination of input and output that would represent a good test case, you can use the save button (5). A dialog will appear where both input and outputs can be named.

If you have already created an input and would like to edit it further, you can do so by selecting it from the drop-down list (6). Finally, if the screen becomes too small to display input and output at the same time, you can split the page into two pages by clicking the split button (7). To exit the split mode, you can simply close the second page.

Playground

The playground provides users with the opportunity to discover FEEL at their own pace. You can define inputs and experiment with the way FEEL expressions operate on it. This gives users the opportunity to test FEEL expressions for Business Knowledge Models and Decisions before using them in real DMN applications.

To get started, navigate to the playground page under Education πŸ‘’ Playground.

The most relevant area is the expression editor (1), where you can specify the FEEL expression you want to experiment with. The editor offers syntax highlighting, by pressing Ctrl + Space, you can view all the available FEEL functions. Below the expression editor is the context editor (2). This is where you can define the inputs on which the FEEL expressions operate. The individual inputs always consist of a key and a value. The key can be used in the FEEL expression to reference the value. For more information about the context editor, please refer to the section Using the JSON Builder. The entered FEEL expression and the entered inputs combined produce an output which is displayed on the right side (3). You can also select which engine is used to calculate the output (4). By default, the Drools engine from Red Hat is used, which currently has the most complete implementation of the FEEL specification. But if you like, you can also choose the DMN Decision Engine from Camunda or the jDMN engine from Goldman Sachs.

You can also save and load your playgrounds. To save a playground, simply enter a name (required) and a description (optional) in the top bar, then click on the save icon (). To load a playground, select the desired option from the "Playground" dropdown menu. If you wish to clone a playground, simply load it, make your changes and click on the clone icon (). This will allow you to save the playground under a new, different name. The playgrounds can also be managed using the playground designer under Design πŸ‘’ Playgrounds. As such, these two pages go hand in hand.

Documentation

The documentation page offers an interactive documentation, which can, for example, serve as a reference or as a basis for discussion. The following features are supported:

  • The dependencies between the different models are illustrated using a Model Import Diagram.
  • All data types are visualized. It is indicated if the data type is a list or if there is a list of allowed values. If the data type is complex, its children are also shown.
  • All inputs are displayed with reference to the relevant data type.
  • All knowledge models are visualized. In each case, the expected parameters and the return type are specified. All types of expressions are supported: Literal Expressions, Contexts, Decision Tables, Relations, Functions, Invocations and Lists.
  • All decisions are displayed. In each case, the return type is specified. All types of expressions are supported: Literal Expressions, Contexts, Decision Tables, Relations, Functions, Invocations and Lists.
  • All decision services are shown, with reference to the attached inputs, encapsulated decisions and output decisions.

To get started, navigate to the documentation page under Execution πŸ‘’ Documentation. To illustrate some of the features, we will use two test cases of the Decision Model and Notation Technology Compatibility Kit (TCK). When opening the documentation for the test case 0019-flight-rebooking, for example, you can see the following Model Import Diagram that illustrates the dependencies between the different models:

The knowledge model passenger priority of the test case 0019-flight-rebooking looks like this and should reflect the representation in your editor:

Formatting the Descriptions

The DMN specification allows you to add descriptions various parts of the model. To have more freedom while describing the model, the descriptions can be formatted with a fixed set of HTML tags. The following tags are supported:

<b>This line rendered as bold text.</b>
<i>This line rendered as italicized text.</i>
<u>This line of text will render as underlined.</u>
<s>This line of text is meant to be treated as no longer accurate.</s>
You can use the mark tag to <mark>highlight</mark> text.

If this description is added to a decision, for example, the respective documentation will look like this:

Printing the Documentation

The documentation is optimized for printing. After starting the print dialog via Ctrl + P or the corresponding option in the browser menu, the desired paper size can be selected:

It is also recommended to disable page margins and to enable background graphics:

Challenger

The challenger page (found under Education πŸ‘’ Challenger) is a place for users to practice their FEEL (Friendly Enough Expression Language) skills in small programming challenges. The challenges can also be managed using the challenge designer page under Design πŸ‘’ Challenges. As such, these two pages go hand in hand.

Every challenge has a name (required), a description (optional), a list of hints (optional), a list of test cases (required) and a solution (required). Users can test their own FEEL solutions against the list of test cases, view hints if they are given and compare their solutions to that provided by the challenge creator. This gives users the ability to create interactive FEEL programming classes. The knowledge gained from this can be applied in DMN development.

To create a challenge, you must first enter a workspace. Next, navigate to Design πŸ‘’ Challenges in the navigation bar. Click the + button in the top right to create a new challenge. This will provide you with a form where you can enter the name and description, create an optional list of hints, specify a solution and create a list of test cases. Each test case consists of an input and an output, and the FEEL code that users provide must convert the given input to the given output.

Creating a challenge

After creating a challenge, you can invite others to navigate to Education πŸ‘’ Challenges and try to solve the previously created challenge.

Each time the FEEL expression is changed, the challenge is checked again to see if it has been solved yet. If the challenge has not been solved yet, it will be shown exactly which test cases still fail:

Not solving a challenge

If all test cases are successful, the user has solved the challenge!

Solving a challenge

FEEL Functions

substring(string, start position, length?)

Returns length (or all) characters in string, starting at start position. First position is 1, last position is -1.

Parameters

Name Type Required
string string yes
start position number yes
length number no

Examples

substring("foobar", 3) = "obar"
substring("foobar", 3, 3) = "oba"
substring("foobar", -2, 1) = "a"

string length(string)

Returns number of characters (or code points) in string.

Parameters

Name Type Required
string string yes

Examples

string length("foo") = 3

upper case(string)

Returns uppercased string.

Parameters

Name Type Required
string string yes

Examples

upper case("aBc4") = "ABC4"

lower case(string)

Returns lowercased string.

Parameters

Name Type Required
string string yes

Examples

lower case("aBc4") = "abc4"

substring before(string, match)

Return substring of string before match in string.

Parameters

Name Type Required
string string yes
match string yes

Examples

substring before("foobar","bar") = "foo"
substring before("foobar","xyz") = ""

substring after(string, match)

Return substring of string after match in string.

Parameters

Name Type Required
string string yes
match string yes

Examples

substring after("foobar", "ob") = "ar"
substring after("", "a") = ""

replace(input, pattern, replacement, flags?)

Regular expression pattern matching and replacement.

Parameters

Name Type Required
input string yes
pattern string yes
replacement string yes
flags string no

Examples

replace("banana","a","o") = "bonono"
replace("abcd", "(ab)|(a)", "[1=$1][2=$2]") = "[1=ab][2=]cd"

contains(string, match)

Does string contain match?

Parameters

Name Type Required
string string yes
match string yes

Examples

contains("foobar", "of") = false

starts with(string, match)

Does string start with match?

Parameters

Name Type Required
string string yes
match string yes

Examples

starts with("foobar", "fo") = true

ends with(string, match)

Does string end with match?

Parameters

Name Type Required
string string yes
match string yes

Examples

ends with("foobar", "r") = true

matches(input, pattern, flags?)

Does input match the regular expression pattern?

Parameters

Name Type Required
input string yes
pattern string yes
flags string no

Examples

matches("foobar", "^fo*b") = true

split(string, delimiter)

Splits string into a list of substrings, breaking at each occurrence of delimiter.

Parameters

Name Type Required
string string yes
match string yes

Examples

split("John Doe", "\\s") = ["John", "Doe"]
split("a;b;c;;", ";") = ["a", "b", "c", "", ""]

string join(list, delimiter)

Returns a string which is composed by joining all the string elements from the list parameter, separated by the delimiter. The delimiter can be an empty string. Null elements in the list parameter are ignored. If list is empty, the result is the empty string. If delimiter is null, the string elements are joined without a separator.

Parameters

Name Type Required
list string[] yes
delimiter string yes

Examples

string join(["a", "b", "c"], "_and_") = "a_and_b_and_c"
string join(["a", "b", "c"], "") = "abc"
string join(["a", "b", "c"], null) = "abc"
string join(["a"], "X") = "a"
string join(["a", null, "c"], "X") = "aXc"
string join([], "X") = ""

string join(list)

Returns a string which is composed by joining all the string elements from the list parameter Null elements in the list parameter are ignored. If list is empty, the result is the empty string

Parameters

Name Type Required
list string[] yes

Examples

string join(["a", "b", "c"]) = "abc"
string join(["a", null, "c"]) = "ac"
string join([]) = ""

not(negand)

Returns length (or all) characters in string, starting at start position. First position is 1, last position is -1.

Parameters

Name Type Required
negand boolean yes

Examples

not(true) = false
not(null) = null

list contains(list, element)

Does the list contain the element?

Parameters

Name Type Required
list any[] yes
element any yes

Examples

list contains([1, 2, 3], 2) = true

count(list)

Return size of list, or zero if list is empty.

Parameters

Name Type Required
list any[] yes

Examples

count([1, 2, 3]) = 3
count([]) = 0
count([1, [2, 3]]) = 2

min(list)

Returns minimum item, or null if list is empty.

Parameters

Name Type Required
list any[] yes

Examples

min([1, 2, 3]) = 1
min(1, 2, 3) = 1

max(list)

Returns maximum item, or null if list is empty.

Parameters

Name Type Required
list any[] yes

Examples

max([1, 2, 3]) = 3
max(1, 2, 3) = 3

sum(list)

Returns sum of numbers, or null if list is empty.

Parameters

Name Type Required
list number[] yes

Examples

sum([1, 2, 3]) = 6
sum(1, 2, 3) = 6
sum(1) = 1
sum([]) = null

mean(list)

Returns arithmetic mean (average) of numbers.

Parameters

Name Type Required
list number[] yes

Examples

mean([1, 2, 3]) = 2
mean(1, 2, 3) = 2
mean(1) = 1
mean([]) = null

all(list)

Returns false if any item is false, else true if empty or all items are true, else null.

Parameters

Name Type Required
list boolean[] yes

Examples

all([false, null, true]) = false
all(true) = all([true]) = true
all([]) = true
all(0) = null

any(list)

Returns true if any item is true, else false if empty or all items are false, else null.

Parameters

Name Type Required
list boolean[] yes

Examples

any([false,null,true]) = true
any(false) = false
any([]) = false
any(0) = null

sublist(list, start position, length?)

Returns list of length (or all if omitted) elements of list, starting with list[start position]. First position is 1, last position is -1.

Parameters

Name Type Required
list any[] yes
start position number yes
length number no

Examples

sublist([4, 5, 6], 1, 2) = [4, 5]

append(list, item...)

Return new list with all items appended.

Parameters

Name Type Required
list any[] yes
item any... yes

Examples

append([1], 2, 3) = [1, 2, 3]

concatenate(list...)

Return new list that is a concatenation of the arguments.

Parameters

Name Type Required
list any... yes

Examples

concatenate([1, 2], [3]) = [1, 2, 3]

insert before(list, position, newItem)

Returns list with newItem inserted at position.

Parameters

Name Type Required
list any[] yes
position number yes
newItem any yes

Examples

insert before([1, 3], 1, 2) = [2, 1, 3]

remove(list, position)

Returns list with item at position removed.

Parameters

Name Type Required
list any[] yes
position number yes

Examples

remove([1, 2, 3], 2) = [1, 3]

reverse(list)

Returns list in reverse order.

Parameters

Name Type Required
list any[] yes

Examples

reverse([1, 2, 3]) = [3, 2, 1]

index of(list, match)

Returns ascending list of positions containing match.

Parameters

Name Type Required
list any[] yes
match any yes

Examples

index of([1, 2, 3, 2], 2) = [2, 4]