Introduction

Flows are automated pathways an application follows in response to specific triggers or events. They represent a logical sequence of steps to achieve a particular outcome within an application. Each flow can contain various elements, such as triggers, conditions, activities, and loops, that dictate how the application should respond under certain circumstances.

How Flows Define App Behavior

  1. Triggers: Flows begin with triggers. These triggers can be a schedule (happening at a specified time or interval), a webhook (initiated by an exposed API endpoint front-end or other backend call), or an event (occurring due to user actions or system conditions).
  2. Events: Flows can be designed to respond to or send events, allowing for a sequence of flows to be executed.
  3. Activities: Various activities can be defined within a flow to manipulate data. These can include creating, changing, or committing objects in a database, creating transient objects in the system memory, performing list operations, or handling variables and responding to requests on exposed API endpoints.

Flows in Wizzdi Cloud can be tested against test data. Users can examine the data state at each stage of the flow.

Flows in Wizzdi Cloud

To add a flow to an App, click on flows and then click on ‘+ Add Flow.’

 

[F1] Flows – main view before any flow is created

Flows How to

Create a Flow

[F2]A flow name is a word starting with a capital letter.

Once the flow is created, the screen below is opened:

[F3] Empty flow with start and end activities
Note: the yellow flag indicates that you must define the returned Object for this flow.

In a flow diagram, lines connecting activities represent the direction and progression of actions within the flow. Each activity represents a discrete step or task in the overall process. When lines link activities, it indicates the sequence in which these tasks are executed and how control passes from one activity to the next.

Here’s how the lines and icons depict the flow of action:

  1. Start Point: The flow typically begins at a start point, represented by a lightning bolt for a trigger. This indicates where the flow initiates.
  2. Directional Lines: Lines that extend from the start point of one activity to another are usually arrows. These arrows show the direction of the workflow. The flow of action follows the direction of these arrows, moving from one activity to the next.
  3. Activity Icons: Each step in the process is represented by an icon or symbol that denotes the type of activity.
  4. Sequential Flow: When an arrow connects one activity directly to another, it indicates that the second activity will commence immediately after the first one is completed. This linear sequence shows a clear start and end point for each activity.
  5. Branching and Decision Points: Some lines may split into two or more paths, signifying a decision point where the flow can branch off based on certain conditions. Each branch will lead to different activities, showing conditional paths of action.
  6. Convergence Points: Conversely, lines from different activities may converge into a single line, indicating that multiple activities may need to be completed before moving on to the next step in the flow.
  7. Loops: Loops in the flow diagram allow for repeating a sequence of activities until a specific condition is met.
  8. End Point: The flow of action concludes at an endpoint, represented by the endEvent icon; this indicates the completion of the process or that the flow has reached a state where no further action is taken. The endEvent must include an Object returned by the flow. This can be, for instance, return the response in a webhook. All lines must converge before the flow ends.

Technical Note: When the app is committed, a flow is converted to a Java class. In Wizzdi Cloud, committing includes compilation.

Flow Diagram Tools

[F4] Flow general view legend.
Below is a list of diagram tools and activities that may be placed in a flow diagram. Items 1-5 and 16 through 18 are diagram tools.

  1. Go Back: Quit editing
  2. Flow Name.
  3. Edit Flow Details: edit name, description, and package name. Please do not change the package name unless you understand its purpose and you adhere to Java package name rules.
  4. Undo: revert a diagram change.
  5. Redo: revert undo.
  6. Triggers: Select one of the following triggers:
    • Schedule Trigger: triggers a flow at intervals or at a specific time of a selected day of the week.
    • WebHook Trigger: triggers a flow from a custom exposed API endpoint.
    • Event Trigger: triggers the flow from another flow. The other flow sends the event.
    • Other triggers may appear when integrations are added to the app; see below.
  7. Events: These are activities to control the flow.
    • Continue Event: In a loop, ignore the remaining activities and start a new iteration.
    • Break Event: In a loop, leave the loop.
    • End Event: quit the flow and pass the result to the caller.
  8. Object Activities: These are activities dealing with Objects.
    • Create: Creates a new instance of some type.
    • Change: Change the properties of an existing object.
    • Retrieve: Fetch one or more instances from the database.
    • Call Custom Query: Fetch instances using an existing Custom Query.
  9. List Operations:
    • Create List: create a new list of homogenous types.
    • Change List: Apply changes to a list.
    • List operations: perform operations on a list, such as a find.
    • Aggregate List: Aggregation Functions on a list.
  10. Variable Operations:
    • Create a Variable: Create a variable for some object type.
    • Change a Variable: Change a Variable value.
  11. Gateways: A gateway controls the processing flow.
    • Condition gateway: testing a value and processing one of two possible branches.
    • Enum Gateway: Select a different branch for each possible value for an enum variable (a finite list of possible values).
    • Type Gateway: Select a different branch based on the type of an Object.
  12. Code: For the code-inclined, write any code using the built-in editor with Intellisense support. Coding is always optional and is available for people preferring it for some tasks.
    • Define a method: define a Java method.
    • Call a method. Such a Method can be defined in the Apps your App depends on or a Java artifact referenced in Dependencies.
  13. Loops: Create loops. Loops can be nested to any level.
  14. Call External API: Access pre-defined and custom APIs in the App.
  15. Integrations:  Use any of the current integrations added to the app.
    • Kafka: A high-throughput, scalable streaming and messaging platform.
    • MinIO: Distributed, high-performance object storage system.
    • WebSocket: Protocol for full-duplex communication over TCP.
    • MQTT: Lightweight, publish-subscribe network protocol for devices.
  16. Restore zoom value.
  17. Zoom In.
  18. Zoom Out.

The flow diagram in the image above appears as a default view upon creation. It includes two connected activity icons

    A. Schedule Trigger: A flow starts with a trigger; the default trigger is a schedule trigger.

    B. End Event: A flow must end with an End Event. This is where processing terminates, and a result is returned to the caller.

  • Drag any icon on the diagram canvas to a new location.
  • Click on any icon to edit it.
  • Use the mouse wheel to zoom in or out of the diagram.
  • Use the bottom right tools to fit to the screen, zoom in, and zoom out.
  • Use the top left tools to edit the name and package name of the flow, undo, and redo.
  • When dragging an icon from the left toolbar, position it on an existing line to insert it between two icons.  Move the new icon over the line till the line is lit up, then release the icon.
[F5] Dropping an icon on a connection line.
[F6] The in-between icon is connected from both sides.

When a Trigger icon is placed on a connection line, all icons to the left become disconnected and should be removed from the diagram.

Expressions

Whenever a value must be set in a flow activity, trigger, or event, an expression editor can get it from a calculation, existing data, or a combination of both.

Sometimes, these values can be set without accessing the expression editor. This depends on the complexity of the required value.

In Wizzdi Cloud, the management of object fields—whether setting them for new objects, altering them in existing objects, or applying filters for retrieval—may be handled through an expression editor. This editor functions in a way that’s analogous to the formula features found in spreadsheet applications like Microsoft Excel and Google Sheets, where expressions are used to perform calculations or manipulate data.

The expression editor in Wizzdi Cloud utilizes the syntax of Spring SpEL (Spring Expression Language), a powerful expression language that supports querying and manipulating an object graph at runtime. Spring SpEL expressions can be used for a wide range of operations in Wizzdi Cloud, from setting default values for object fields to defining the logic for filtering data during retrieval.

When Wizzdi Cloud generates code, the expressions written in Spring SpEL are translated into standard Java code. This conversion process ensures that the high-level, user-friendly expressions are turned into executable code that can run within the Java environment.

The appendix provided in the Wizzdi Cloud documentation likely contains various examples of how Spring SpEL can be used within the platform. These examples serve as a practical guide for users to understand and craft their expressions for different purposes.

The SpEL editor in Wizzdi Cloud has features like Intellisense, an intelligent code completion tool. Intellisense assists users by suggesting functions, methods, and property names as they type, helping to prevent syntax errors and speeding up the expression writing process. This feature is particularly useful for those who may not be familiar with the full syntax and capabilities of Spring SpEL, as it can guide them through the process and improve their efficiency when working with data in Wizzdi Cloud.

See some samples

Note:
A more straightforward approach was introduced in many places where expressions can be used. This can be either an explicit value or a selection of an existing variable from the flow-defined variables. When the value required is an Object Type, setting its inner field values is possible without accessing the expression editor.

 

Flow Icons

Triggers

 

[F7] Triggers
Select the start icon to indicate how the flow is triggered. Additional triggers can be available when integrations are added to the App, such as for websocket messages.

Schedule trigger

 

Available fields:

Name: The trigger name must be a valid variable name, starting with a lowercase letter and containing no spaces.

Description: document this trigger.

Run: Select the scheduling type for the trigger at regular intervals or on days of the week.

Trigger at Intervals

This trigger can run in intervals, say, every 15 minutes.

Intervals are always in minutes.

Trigger at Intervals

Trigger at a specific time of the day.

The ScheduleTrigger can be set to trigger at specific times and repeat daily at a particular time.

Select the days of the week using the ShceduleTrigger type.

[F8]

Available Fields:

Weekdays:  select the days of the week you want the trigger to fire.

When: select the time of the day you want the trigger to fire.

Proceed to select the time of the day.

Select the hour and minutes using 0-23 notation

[F9]

Webhook Trigger

A WebHook trigger is activated from an exposed REST endpoint.

Integrating a WebHook with a business service establishes a direct connection between a custom, exposed REST API endpoint and a Flow.

This flow is triggered when the custom endpoint receives a request. The endpoint can optionally pass a request body, headers, path parameters, and query parameters to the Flow.

The end event of the flow includes the response generated by the Flow. The response should match the response defined in the custom endpoint.

Creating a flow bound to a custom API.

This can be created from the API endpoint or the flow creation.

Create or select the flow from the API endpoint (recommended)

[F10]
  1. Tags under which the custom endpoint appears in the exposed endpoints list.
  2. The Request object
  3. The Response object
  4. Select a Query or a Flow. It can be an existing one or a new one.
[F11]
                                                                                              Select a Flow or a Query
[F12] Search for an existing or create a new Flow.
                                                                         

 

 

 

                                                         Type the new Flow name and click ‘Create’.
[F13] Select ‘Go To’ to access the new flow from the exposed API endpoint.

                 

 

[F14] A new flow is created.
                                              

Go to the flow from the custom API endpoint.

The new flow has a Webhook trigger instead of the default schedule trigger.

A WebHook trigger triggers the new flow, the required variables for the request body (if it exists), and the parameters the endpoint passes are already defined based on the exposed API endpoint Request Object.

[F15]

The new Flow has the correct Object type on the trigger as defined on the API endpoint. In the above picture, the variable name of the passed object is ‘body’. Other flow activities can use this variable.

Create the Webhook on a new Flow.

Place a new WebHook trigger on a new flow connection line. The connection line connects the default trigger with the end event. Delete the existing trigger.

[F16] Edit a new Webhook trigger
                                                                                          

[F17] Select a custom exposed API endpoint
On the Webhook drop-down menu, select an existing custom API. Then save the Webhook trigger.

An API endpoint can trigger a single flow. A warning dialog is presented if the selected endpoint is already connected to a different flow.

Note: To trigger multiple flows from a single endpoint, you can fire an event that multiple flows can handle from this single flow.

Once the webhook is saved, the required variables are auto-created based on the Endpoint definitions.

Webhook Trigger fields.

[F18]
  1. The trigger name should be a valid Java field name.
  2. Description, use for documenting the activity.
  3. The path to the connected API endpoint (WebHook).
  4. The Object type passed to the flow.
  5. The object’s name passed: use this name when referring to the passed body and its fields.
  6. Mapping for endpoint parameters: Query, Path, and Headers if defined at the endpoint.

Event Trigger

Wizzdi Cloud systems use an event trigger to start a flow when a particular event occurs. This event is represented by an event object, which can either be predefined by the system or defined by the user. Typically, events are triggered by actions like creating or updating an entity. Custom events can also be defined, where some conditions can be tested to check if the flow should be executed.

The same event can trigger multiple flows.

Flows can also be explicitly called from other flows; see below.

Create an Event Trigger

You can drag an event trigger from the toolbar to the connection line and delete any existing trigger.

[F19]

The event-trigger dialog.

Event trigger fields

  1. The type of the trigger.
  2. The name of the trigger
  3. The description for this trigger.
  4. The type of object firing this event. In our case, a Teacher object Type..
  5. The name of the Object Type.
  6. Specify the instance name of the object triggering the flow, which will be referred to in subsequent activities.
  7. Condition: It will only fire on the following conditions: Create, Update, or Custom.
    • Create: This flow is triggered whenever an object of the specified type is created.
    • Update:  This flow is triggered whenever an object of the specified type is updated.
    • Custom: This option allows you to use an expression to filter for a custom condition. When the condition is evaluated as true, the flow processing commences.

When events are fired?

Events are fired based on the runtime selected and some other conditions.

  • If the fireEvent activity is used in one flow to activate another, the object type used in the fireEvent should match the one selected on the event trigger; the event trigger condition should be set to none or evaluated to true.
    • The above works on both runtimes, Spring Boot and Flexicore Boot.
  • Spring Boot:
    • If the object type is an Entity, the flow will be activated when there is no condition.
    • If there is a condition, it should be evaluated as ‘true ‘ in the custom condition.
    • To use Create or Update conditions, the entity must have two fields defined as Creation Date and Update Date, respectively. See the field’s purpose when defining the domain model.
  • Flexicore Boot, Flexicore
    • If the Object type is an entity, the entity is sent to the triggered event.
    • CREATE and UPDATE can be used as conditions; there is no need to set a creation date and update the date on entities in Flexicore derived from Basic. See elsewhere on this document on FlexiCore extensions over Spring Boot.

Sending a custom Object from one Flow to another flow.

  • When an Event Trigger is defined, there is no option to define an object type. Only existing types can be selected.
  • If you need to create a new object type, you must do so from consumed or exposed APIs.
  • Once you create such an Object on a dummy endpoint, you may delete the endpoint; the definition remains available

. Note: The soon-to-be-released version of Wizzdi Cloud offers a new Object definition inside the flow.

Integrations Triggers

When Integrations are added to an App, additional triggers may become available from the flow toolbar. For example, Kafka, Websocket, and MQTT integrations add triggers.

[F20]
Triggers added by Integrations

Triggers and Activities when integrations are added.

The idea is the same for Kafka, WebSocket, and Mqtt triggers: an instance of an object sent by the integration is passed to trigger the event.

Events

[F21]


Events

Events are used at the end of the flow (End Event or inside loops (Break Event, Continue Event). 

The Break Event and Continue Event are located under the Loop Icon.

End Event

A flow must end with at least one end event. The EndEvent defines a response value in a predefined Object type.

When a WebHook triggers the flow, the response type in the EndEvent must match the defined response for the associated endpoint.

When an event triggers the Flow, for instance, one fired by another flow, the response has no meaning. A common practice is to change the received object to contain the required data the publisher requires.

How to

Drag an event icon and place it on the flow; new flows include such activity already.

[F22]
Click on the icon and handle the required fields below.

End Event – example returning Time and Date (with proper timezone)

Objects

[F23]

   The Object Activities

Think of an Object Type as a mold in a factory. This mold can be used to create multiple instances of the Object Type, similar to how a mold for a toy might be used to make many identical toys. However, each instance created from this mold can have different characteristics or attributes filled in. For example, if the mold is for making a toy car, each car can be painted differently, have other types of wheels, or feature various stickers. Each toy car is an instance of the mold, and while they all share the same basic structure, they can each have unique attributes. In the Wizzdi cloud, instances of Object Type are called Objects.

Each object in the workflow would have attributes and statuses that reflect its current position or role in the overall business flow. For instance, an object could represent a customer order that moves through various stages like order placement, fulfillment, shipment, and delivery. Different operations might be performed on the object instance at each step in the process, such as updating its status, modifying its details, or moving it to the next stage in the workflow.

Here’s how the functions in the interface relate to managing the lifecycle of an object within a business flow:

  • Create Object: Initiates a new instance in the workflow. For example, this could be used to start a new customer order.
  • Change Object: This function alters the details of an existing object as it progresses through the flow. For example, it might update the status of an order from “pending” to “fulfilled.”
  • Retrieve Object: Looks up and retrieves object instances. This applies to entities only.
  • Call Custom Query: Executes predefined queries tailored to the business’s needs, which may involve complex data retrieval across different stages of the business flow. For example, a custom query might gather all orders ready for shipment.
Create Object 

The dialog below shows the Create Object activity before any selection.

[F24] The Create Object Activity
  1. Activity Name: Every activity within the flow is assigned a name. This name is used to identify the activity and typically reflects the action or step in the business process it represents. For example, an activity might be named “invoiceGeneration” or “qualityCheck.” Note that names have built-in restrictions, such as no spaces.
  2. Activity Description: Each activity has a description along with its name. This description offers additional details about the activity’s purpose or action and is displayed as a tooltip when a user hovers over it within the flow. This feature aids users in understanding the function of each step without cluttering the visual representation of the flow. Furthermore, there is functionality to embed these descriptions as comments in the source code generated by the Wizzdi Cloud, enhancing code readability and maintenance.
  3. Object Type: This refers to the type of object that the activity creates or manipulates. The object type must be pre-defined within the App and is part of the digital representation of the business process. For example, the object in a sales process flow could be “CustomerOrder” or “PaymentReceipt.” For Entities, there is an option to create a new Entity from the Create Object activity.
  4. Output Name: once an object is created or modified by an activity, it must have an output name, which serves as a handle or reference to that particular instance for the duration of the flow. This allows the object to be identified and accessed by subsequent activities within the flow. For example, if an object named “orderDetails” is created, it can be referenced by that name in downstream activities such as ChangeObject, etc.

Once the Object Type is selected, the user can fill in its fields.

[F25]
                                 Create-Object activity after the Object Type is selected.

Note: The selected object type is a Book, as shown in the screenshot above. Although it was arbitrarily chosen, it helps to understand how field types affect the user interface.

Field Editors

Based on your needs, each field can be filled using one of three tools, encircled under 10  above:

  • Pencil: This is the default tool for simple types and allows for the literary setting of a field’s value based on its type. For example, a boolean field editor is a checkbox, and a list of fixed values (ENUM) is a drop-down.
  • Expression Editor (Ex): The Expression Editor can be used when you need a more complex value, such as the current value from an iterating list. Familiarity with SpEL syntax, at least the basics, is required.
  • Variable Picker(V): When the required value fits any defined variables in the flow upstream activities.

Note: The expression editor can define a field value with any combination of literals, functions, and variables.

Legend:

  1. Activity Name – must conform to Java field naming.
  2. Activity Description 
  3. Object Type – the selected Object Type can be any app or system-defined Object Type. Once selected, the user interface reflects its fields. We have selected a Book entity; this is arbitrary and has no special significance.
  4. Output Name – the variable name to which this object is assigned can be referenced in the flow downstream activities.
  5. The Object Type Header – a title for the fields below. This bottom part is collapsible.
  6. Name —In our example, the book’s name field is displayed as a text field because it is a String type.
  7. Genre- In our example, the book’s genre field appears as a dropdown field because it is an Enum type.
  8. Translated – In our example, the translated field of the book is shown as a checkbox field since it is a boolean type.
  9. Author – The default dropdown editor displays available Author type variables defined upstream because the field type is an Object Type.
  10.  Available tools for a text field.
  11. Available tools for an enum field.
  12. Available tools for a boolean field.
  13. Available tools for an Object field.
  14. Scroll to expose more fields of the selected Object Type (3).
Change Object 

Once objects are instantiated in upstream activities (designed to be executed before the current activity), the Change object Activity can change them.

Drop the Change Object activity on an execution line or an empty diagram area and open it.

[F26]
  1. The Object Type of the changed Object.
  2. The Object is to be changed. If the Object Type is selected, the list of Objects is filtered by that Type. If the Object Type isn’t selected, selecting an Object sets the Object Type.
  3. Edit a field. See (4) below. Object fields should be selected first. Click on the icon to edit the field.
  4. Select a field to be changed.
  5. When selecting a field, the list now includes unselected ones.
Retrieve Object(s)

This activity pertains to obtaining data from a database, an everyday necessity in software systems, especially when dealing with data-driven responses or processes.

  • Use in Custom APIs: When the App exposes custom API endpoints for use by other systems or user interface clients, it often needs to retrieve specific entities from its database to compile the data necessary for the API’s response. For example, if the API is designed to provide customer details, the activity would fetch customer entities containing information like names, addresses, and transaction histories.
  • Batch Processing: There are situations where a set of entities needs to be processed as a group. This could involve batch updating records, performing calculations, or generating reports. For instance, a financial system may fetch all transactions for the end-of-day processing to calculate interest or fees.
  • Integration with External APIs: Entities from the local database often must be sent to external APIs. This is common in integrations where two different systems communicate with each other, such as sending order details from an e-commerce system to a shipping provider’s API to arrange delivery.

When retrieving entities, if the requirement is straightforward, such as fetching a list of all products in a catalog, the resulting list will contain entities of a single type, all sharing the same structure or schema. In this case, the Retrieve Object is a good fit for the job.

However, there are instances when the needed information is not contained within a single entity type. In such cases, the “Call Custom Query” activity (below) can fetch data from multiple entities that must be combined. Custom Queries are potent tools that specify complex data retrieval operations, such as joining data from multiple entity types. Custom Queries enable you to define a custom structure for the output list, including fields from various related entities. For example, you might need a list that combines customer information with their respective order histories and payment statuses. Custom Queries would allow you to define and retrieve a complex list tailored to your requirements.

Drop a Retrieve Object activity on an execution line or a diagram space.

[F27] An empty Retrieve Object(s) Dialog.
                                                      

  1. The Activity name.
  2. The Activity Description.
  3. Object Type Selection.
  4. Output Name selection: This variable name will be used for the result of the Retrieve Object activity. Depending on the Retrieve Type, it will be either the selected Object Type or a List of the selected Object Type.
  5. Select the Retrieve Type. It has the following options: allfirst, or any.
  • ALL: The returned object type is a filtered list of the selected object type, such as a list of authors. The list is always returned, but it may be empty.
  • First, Any: the returned type is the Object Type selected, such as a teacher. This instance may be valid or null.
[F28] Retrieve Object Activity, Object Type Selected
  1. The Activity name.
  2. The Activity Description.
  3. The selected object type in the above screenshot is Author.
  4. The selected output name in the above screenshot is ‘authors.’ The type of this output name will be a List as the Retrieve Type in (5) is All. The selection
  5. Retrieve type is All.
  6. A title for the filter: in the screenshot above, the filter is unpopulated.

7-12 These are unpopulated filter fields.

The retrieve object activity offers the same field editors for setting filter fields, similar to the create object activity.

 Adding Filters

Retrieving entities from a database typically requires careful consideration to avoid performance issues. Fetching all entities of a particular type at once is generally inefficient and can lead to resource strain. Filtering mechanisms are employed to mitigate this.

Filtering allows for narrowing down the dataset to only those entities necessary for a particular operation or requirement. It can be based on specific criteria, such as a date range, a status, or any other relevant attribute of the entities.

Paging is a common filtering technique for managing data retrieval. It divides the results into “pages” of a specified size. This means that a subset of records is fetched instead of retrieving the entire dataset in one go. The size of each “page” or batch can be configured based on the application’s performance considerations and data processing needs.

As mentioned, Wizzdi Cloud provides built-in filtering capabilities that can be applied to any entity. These built-in filters are predefined and can be easily applied to retrieval.

For more complex filtering needs that cannot be satisfied by the built-in options, the Custom Query Request Object is utilized, and the required activity is Call Custom Query. This object provides flexible, user-defined filtering criteria, including multiple fields from the entity, complex conditional logic, and the ability to join data across different entity types.

When processing all entities of a certain type is necessary, the paging mechanism loops through the entities in manageable batches. This approach allows the system to process large datasets without overwhelming the memory or processing power by only handling a small subset of records at any given time.

In practice, the user specifies the desired filters once the object type is selected for retrieval.

Selecting from available built-in filters.

[F29]
Adding Filters Details

Select the pageSize filtering field and click the pencil icon to set the value.

The expression editor opens, and we set the page size to a constant 10 records.

Current page setting from a variable.

A variable was created for the current page value (see variables below), and the expression references this variable. The image was taken while typing the word current. The expression editor IntelliSense feature suggests the existing variable with its Object Type.

Call Custom Query

When retrieving entities, if the requirement is straightforward, such as fetching a list of all products in a catalog, the resulting list will contain entities of a single type, all sharing the same structure or schema. In this case, the Retrieve Object is a good fit for the job.

However, there are occasions when the needed information is not contained within a single entity type, or filtering must be finer than what the built-in one provides. In such cases, the “Call Custom Query” activity (below) can fetch data from multiple entities that must be combined. A Custom Query is a powerful tool that specifies complex data retrieval operations, such as joining data from multiple entity types. Custom Queries enable you to define a custom structure for the output list, including fields from various related entities. For example, you might need a list that combines customer information with their respective order histories and payment statuses. Custom Queries would allow you to define and retrieve a complex list tailored to your requirements.

 

[F30] Empty Call Custom Query Activity dialog.

 

Once the Custom Query is set from the available custom queries, its request object is presented to be set with data from available object instances in the flow. See Figure 31.

[F31] The Call Custom Query activity after a query is selected

The custom query request defines the object type fields; see the screenshot below [Figure 32] for the matching definition in the Custom Query editor.

Set the Activity name in [1] and the activity description in [figure 32-2]. The query is set in [figure 31-3], and the response object variable name is set in [figure 31-4]. The response object type is defined in the Query and will be stored at run-time in the variable defined in [figure 31-4].

In the example dialog[figure 32] above, the request Object Type consists of several basic type fields, such as String, integer, OffsetDatetime, and a nested Object Type, The MyBookFilter object type. The call custom query dialog [F31] includes these fields for setting their values.

[F32] The Request Object Type definition in the Custom Query editor
Set the request object fields with values from variables or objects defined elsewhere in the flow.

Note: The Call Custom Query activity may truncate long field names like publishingDateStart; put the pointer over the field name to see the full name of the field.

When setting the values in the custom query request object, the following options are available:

  • Setting the value for the field explicitly.
  • Setting the value from a variable defined upstream in the flow, such as a currentPage variable, iterates pages in a loop.
  • Setting the value from a SpEL expression is the most flexible option, but it requires at least basic knowledge of SpEL.

Note: The above options for setting a field’s value at runtime are not intrinsic to the Call Custom Query activity but are used in most of the available flow activities.

 

Lists

[F33] The list activities’ icons
Manage lists: Here, you can create a list of any object type, modify the list by adding or removing objects, perform various operations on lists such as finding, union, and more, and carry out aggregations on lists such as counting and summing.

Create A List

Drag a Create List Activity on an execution line to connect to activities on both sides.

[F34] Create a List activity

In Figure F34, the list element type has not yet been selected.

 

Select the activity name in F34-1 and its description in F34-2. The Create List Activity creates an empty list object and assigns it a name specified in F34-3. The output name is used to access the flow downstream activities.

The output name should never be confused with the activity name. The activity name and description help identify the activity while editing the flow. At run time, it has no significance. What matters is the output name that acts as a handle to the list and the element Object Type used. This handle is also called a variable.

 

[F 35] Create a list, Object type selected (Author)
In F 35-4, the Object Type for the list is selected. Consequently, the List Type becomes List<Author>, a list of Author Object Type elements.

Change a List

 Drop the change list activity on an execution line and let it connect to the activities on both sides.

[F36] Change list activity before selecting change type.
In Figure F36, you set the activity name in F36-1 and its description in F36-2. Then, we need to select the change type required.
It can be ‘add’, ‘clear’ , or ‘remove’. 
Filled Change List Activity.

The change list activity has three options for the change: add, clear, remove

The Add and Remove command requires two parameters: the instance to add or remove and the list. The Clear change type requires only one.

List Operations

  1. Intersect: Creates a new list containing only the elements that are present in both of the original lists.
  2. Subtract: Removes all elements in the second list from the first list. The resulting list contains only those elements in the first list but not in the second.
  3. Contains: Checks if the first list contains all elements of the second list and returns a boolean value (true or false).
  4. Equals: Compares two lists to determine if they are the same in content and order of elements, returning a boolean value.
  5. Sort: Orders the elements of a list according to the specified criteria, which can be in ascending or descending order based on one or more attributes.
  6. Map: Transforms each element in a list based on a provided function or expression and can be used to extract specific attributes from a list of objects.
  7. Find/Filter: Searches for elements in a list that match a specified condition and returns a new list with the matching elements. It can also return a single element if the ‘findFirst’ operation is used.
  8. Head: Retrieves the first element of a list if it exists.
  9. Tail: Retrieves the last element of a list if it exists.
  10. Union: Combines two lists into one, including all elements from both, even if duplicates exist.

To use these operations in Wizzdi Cloud, you would typically select the operation type from a dropdown menu, specify the input list(s), and, if necessary, provide additional expressions to dictate how the list should be manipulated. You would use the output name to reference the resulting list in subsequent activities within your workflow.

Explanation

Suppose we have an entity called Book.

The book entity

The following description is a collection of list operations depicting their purpose and usage.

Retrieve books from the database.

Create a list of books (Book type) by retrieving the first ten or fewer books.

Create a list of the book entities called current books from the first ten books.

Create an adHocBook

Book Object Created

This is created to populate another list of books

Create a new, empty list of books.

Create an empty list of books.

Add the adHocBook to the moreBooks list.

Add the ‘adHocBook’ to
the ‘moreBooks’ list.

Add the two lists into a third one

Add more books to currentBooks.

The union operation creates a new list out of two existing lists.

Subtract one list from another.

Subtract operation.

The resulting list is identical to currentBooks minus all books in the current books that are found in more books.

Sort a list. The result forms a new list
Sort operation
Setting a sort field

In many data processing contexts, particularly in databases, data analysis, or programming, there’s often a need to sort datasets based on multiple criteria. This is where sorting by a list of fields becomes relevant. Here’s a detailed explanation:

  1. Multiple Fields Sorting: Instead of sorting by a single attribute (like age or name), sorting by a list of fields means sorting data based on multiple attributes. For example, you might first sort by age and then by name.
  2. Ascending and Descending Order: Each field in the list can be sorted in ascending order (e.g., from smallest to largest, from A to Z) or descending order (e.g., from largest to smallest, from Z to A). This order is specified for each field individually.
  3. Significance of Order in the List: The position of the field in the sorting list determines its priority in the sorting process. The first field in the list is the primary sorting criterion. Only when there are ties in this first criterion does the second field come into play, and so on.
    • For example, consider a dataset sorted based on the list [Age (ascending), Name (descending)]. Here, the primary sorting criterion is age in ascending order. If two records have the same age, their order is determined based on their names, in descending order.
Intersect two lists
Create a list of books that appear in both lists, currentBooks, and moreBooks.

The intersect operation creates a list of objects appearing in two lists.

Create a list by filtering anther list using the find operation.

Filter a list

Are all objects of moreBooks included in currentBooks list

The Equal operation

Compares two lists and returns either true or false as a result.

Set the two lists
Contains 

return true if all objects in the second list are found in the first list.

Aggregate List

The aggregate list activity provides the following aggregations over a list of objects.

Count 

Counts the number of items in a list.

Count the items in a list.
Sum
Sum s specified field in each item in a list.
Minimum
Find the minimum value of a specified field across all list items.
Maximum

Find the maximum value of a specific field across all list items.

Average

Find the average value of a specific field across list items.

Variables

Variables are used throughout the lifetime of a flow to store intermediate data, control loops, and more.

A Variable is always of certain Object Type, it can a simple type like String or Integer or a more complex Object type.

Create or update a variable (A temporary object holding data).

Create a Variable

Drop the created variable activity on an execution line; the empty activity should look like this.

The Empty Create Variable activity

Apart from the standard name and description, this activity requires you to fill in the following fields:

Variable type: Search for the required type of variable. It can be any type, including entities and other objects.

Variable name: The name of the created variable; this is how it will be identified by activities downstream of the flow.

Init expression: The value given to this variable once it is created.

Create a Variable of a String type with init value.
Create a variable of an object type OffsetDateTime

Gateways.

Gateways are for changing the processing path in a flow based on data. The Condition deals with true/false paths. The Enum gateway deals with multiple possible values and corresponding paths for each. The Merge gateway continues processing from multiple paths back into a single path. The Type Gateway allows processing to take different paths based on a descendant type of some parent type.

Condition Gateway

The Condition Gateway evaluates an expression and changes the execution path according to the result.

Eventually, all execution paths must merge before the flow endEvent is reached.

Consider the following flow:

Simple flow for depicting conditions.

The condition in this flow check is two variables are equal and take a different execution path based on the result.

The condition gateway activity

In the flow, we set variableA to 5 and variableB to 6 (both are int type), so the expression result will be false.

From the Condition Gateway, we have two execution paths; the first is created for a ‘false’ result when you drop the condition gateway on the existing connection line. The second should be dragged from the outlined ‘ear’ to the next activity on the ‘true’ connection line.

How to connect the second connection line for ‘True’

In the flow above, you can see the Condition Gateway with the two execution paths.

Merge Gateway

When the execution flow splits because of a Gateway, it must be merged before the flow execution is finished at the end event.

Pages
The Merge Gateway

The merge gateway has multiple entry points (unlimited) and a single output point. Its definition includes a name (for the activity) and a description.

The merge gateway on the flow

Note the empty ‘ear’ for connecting a new connection line (execution path); a new one will be created once it is used.

Java code

This is for developers who wish to enhance diagram-based programming with Java programming. Methods creation is supported. A full Java editor is provided, including auto-completion and awareness of project available types and services.

Loops

Create loops across a list of elements or for a fixed number of times; loops are visual containers hosting other icons (activities), including nested loops.

To create a loop, drag the loop icon on a connection line. Or drag it onto a diagram space and manually connect it to upstream and downstream activities.

Inside the loop

The activities inside the loop represent what one iteration should do; the structure should be similar to any flow structure. The loop has one entry point and one exit point.

The break and continue events are provided to allow exiting the loop or starting a new iteration without finishing the current one.

Loop types

There are two types of loops: a “for loop” and a “loop over collection.”,

  1. For Loop:
    • This is typically used for executing a set of actions a fixed number of times. The for loop might represent a process that needs to repeat certain steps a predetermined number of times. For example, if a task needs to be performed daily for a week, the for loop could iterate seven times.
  2. Loop Over Collection:
    • This loop iterates over a collection of items, such as a list. This could represent a process where each item in a collection must undergo the same actions. For instance, if you have a list of teacher records that each need to be processed similarly, a loop over collection would be used to iterate through these records.

Example

Loops Example

The example above depicts some points:

  • It retrieves an unknown number of Teacher items from the database in a preferred paged manner.
  • It demonstrates how loops can be nested.
  • It uses the two types of loops.

Step 1

Drag the loop icon on a connection line.

Drag the bottom right corner of the loop to adjust its size. The yellow flag indicates that the Loop is not yet defined.

‘For loop’ type defined.

The loop above is defined as follows:

  • The variable name for the loop is currentPage. We need this loop to control teacher records (entities) fetching.
  • The Init value is 0; we start with page 0.
  • The condition value is set to true. This is because we do not know how many pages will be present. We will exit the loop when the current batch of teacher records is empty. See below.
  • The increment value is 100, which is our choice for a batch size. Too large a batch size will strain our resources, and too small is inefficient.

Step 2

The next step is to drag a Retrieve Object activity inside and to the left side of the loop. It will auto-connect to the loop entry point.

Click on the activity to edit it.

The Object Retrieve activity to get a batch of teachers.

Setting the retrieve Object correctly is critical as we do not want to fetch all Teacher records in one batch.

  • Set the object type to Teacher.
  • Set the output name to teachers. This will be a List of Teacher types per batch.
  • Set the Retrieve Type to all; we will get all teachers available filtered by the Property Mappings.
  • Set the Property Mappings as follows:
    • Click on Add Field and select the currentPage field. The system created this field for the Teacher entity to allow paged access to the Teacher entity.
    • Set the field value to the currentPage variable set on the main loop. Save changes.
    • Click on the Add Field again. Now select the pageSize field and set it to 100.

Note: The currentPage field in the Retrieve Object activity gets its value every loop from the currentPage ‘For Loop’ control variable; we have set the ‘For Loop’ currentPage variable to increment by 100 every loop, hence the setting of 100 for the pageSize field of the Retrieve Object activity.

Step 3 

Connect the Retrieve Object activity’s exit ‘ear’ to the loop’s exit point.

Connection Line inside the loop

Step 4

Drop a Condition Gateway on the line connecting the Retrieve object Activity and the loop exit.

The gateway checks if the last Retrieve Object execution has returned an empty list; this is the condition for exiting the main loop.

Click on the gateway and set it to check if the teachers’ list is empty.

Gateway Setting

Step 5

When the teachers’ list is not empty, we want to process the items individually and increase each teacher’s salary by 20 percent.

We need to drag and drop a new loop inside the main loop; this loop processes each batch if it is not empty.

Drop inner loop

Inner loop dropped

The inner loop is now ‘yellow flagged,’ indicating that we must define it properly.

The inner loop (over collection) defined.
  • The inner loop type is Loop Over Collection, and the collection is the currently fetched batch from the database.
  • When such a loop iterates, every item is fetched from the collection into a variable. We need to define this variable’s name to reference it inside the loop. The name selected here is ‘teacher’.
  • The type of ‘teacher’ needs no definition as the type of each item is known; it is the type of the collection. So, the system implicitly infers the type.
  • Lastly, we must type the collection’s name to iterate over, which is the name given to the collection in the retrieve Object activity. That is, ‘teachers’.

Step 6

Drag  a Change Object activity and place it inside the inner loop as follows:

Change Object in the inner loop, yet to be defined.

Set the activity parameters as follows.

Change variable details

Although the type of teacher is known in runtime, we need the Object Type to be set to Teacher so the property mappings correctly reflect a teacher’s fields.

We now must select the field we want to change in the teacher variable.

Click on the ‘+Add Field‘ and select the salary field.

Select the salary field.

Set the salary to a new value. This will be the current value*1.2.

Change Salary to the current value * 1.2.

Step 7

Connect the right ‘ear’ of the Change Object Activity to the inner loop exit.

The inner loop connection line while dragging.

Connection line connected to inner loop exit.

It is important to note that when an object is modified in a Change Object activity, the changes will not be reflected in the database until they are committed. A Commit Object Activity should be added inside the inner loop to ensure that the changes are saved.

                             Empty Committed Object activity.

The commit object is filled with the Object Type Teacher and the variable ‘teacher’.

The Commit Object activity is straightforward and requires both the variable and the object type.

Step 8

We need to define the actions taken when there are no additional Teacher items and the Gateway Condition evaluates to true.

In such a case, we need the main loop to exit, this is achieved by the Break Event.

The break event.

The two paths from the Condition Gateway must merge before exiting the outer loop. We’ll use a Merge Gateway on the connection line from the inner loop to the outer loop exit.

Merge Gateway added on the end of the ‘false’ path exiting from the Condition Gateway.

Step 9

The ‘true’ path should also end in the same Merge Gateway, so we connect the right ‘ear’ of the Break Event’  to an empty ‘ear’ on the Merge Gateway.

The final example looks like this.

The Break Event is connected to the Merge Event.

Predefined Consumed APIs

You can access external service providers from here; these include built-in services (like Google’s) or consumed APIs defined in the Consumed Apis section.

Fire Events

Fire an event from one flow, potentially notifying another flow. Events are processed synchronously and pass an Object to the receiving Flow.

The same event can trigger multiple flows.

Integrations Activities

See below a discussion about Integrations. These are software components available on the Wizzdi cloud. Once added to an App, integrations may add additional activities to the left side menu of any App flow. For Example, the WebSocket integration adds these activities:

 

Appendixes

Spel FAQ

Basic Operations

Q: How do I concatenate two strings?
A: Use the .concat() method

"Hello".concat("World")

Q: How do I check if two strings are equal?
A: Use the .equals() method:

"apple".equals("banana")

Q: How do I convert a string to uppercase?
A: Use the .toUpperCase() method:

"hello".toUpperCase()

Working with Variables

Q: How do I assign a value to a variable?
A: If supported, typically, variables are set outside the expression using activities and used inside the expression:

#variable = 20

(Note: Check if direct assignment is possible in your Wizzdi environment or if variables need to be pre-defined externally.)

Q: How do I use a variable in an expression?
A: Reference the variable directly:

#myVariable + 10

Type Instantiation and Methods

Q: How do I create an instance of a class?
A: Use the new operator:

new java.util.Date()

Q: How do I call a static method?
A: Use the T() operator:

T(java.lang.Math).max(5, 10)

Collections

Q: How do I access an element in a list?
A: Use index access:

myList[0]

Q: How do I modify an element in a list?
A: If modification is supported:

myList[0] = 'newValue'

Q: How do I filter elements in a list?
A: Use the selection (?) operator:

 

myList.?[#this > 10]

Logical Operations

Q: How do I perform a logical ‘AND’ operation?
A: Use the and keyword:

#isActive and #hasAccess

Q: How do I use the ternary operator for conditional checks?
A: Use the ?: syntax:y code

#age >= 18 ? 'Adult' : 'Minor'

Advanced String Operations

Q: How do I check if a string contains a substring?
A: Use the .contains() method:

"Hello World".contains("World")

Q: How do I replace part of a string?
A: Use the .replace() method:

"Hello World".replace("World", "Everyone")

Date Handling

Q: How do I get the current date and time?
A: Use the new operator with java.util.Date:

new java.util.Date()

Q: How do I format a date?
A: Instantiate SimpleDateFormat and use it:

 

new java.text.SimpleDateFormat('yyyy-MM-dd').format(new java.util.Date())

Numerical Operations

Q: How do I perform arithmetic operations?
A: Directly use arithmetic operators:

10 + 5 * 3 / 2 - 1

 

Was This Helpful?
Updated on June 5, 2024

Looking For Somthing Else?

Contact Our support 24/7

Sign Up for Waitlist