This section describes JDL samples of a Capacity Planning application, using either a standard single JDL file or a composite data model with multiple JDL files.
In this JDL sample for a simple Data Model application, all entities and relationships are indicated in one single file, entities.jdl
.
application { // DOM [java.collectorClass] : [CapacityPlanning] } entity Country { // DOM [primary.keys] : [id] id String required, name String } entity Plant { // DOM [primary.keys] : [plantId] plantId String required, lat Double, lng Double, @Formula("(SELECT SUM(a.duration_in_hours) FROM activity a WHERE a.plant_id = db_gene_internal_id AND a.db_gene_internal_scenario_id = db_gene_internal_scenario_id)") durationInHours Double } entity Parameter { // DOM [single.row] : [true] // DOM [java.collectionName] : [Parameter] currentTime Instant } entity Resource { // DOM [primary.keys] : [id] id String required, name String } entity ResourceCapacity { quantity Integer min(1) } entity Activity { // DOM [primary.keys] : [id] id String required, name String, durationInHours Duration, dueDate Instant } entity Precedence { } entity Requirement { @DefaultValue("1") quantity Integer min(1) } entity Schedule { start Instant, end Instant } entity SolutionSummary { // DOM [single.row] : [true] start Instant, end Instant, timespan Integer } entity ResourceUsagePerDay { // DOM [primary.keys] : [day] day Integer, numberOfHours Integer } relationship ManyToOne { // DOM [affects.primary.key] : [true] Requirement{activity} to Activity{requirements}, // DOM [affects.primary.key] : [true] Requirement{resource} to Resource{requirements}, // DOM [affects.primary.key] : [true] Precedence{first} to Activity{successors}, // DOM [affects.primary.key] : [true] Precedence{second} to Activity{predecessors}, // DOM [affects.primary.key] : [true] Schedule{resource} to Resource{schedules} // DOM [affects.primary.key] : [true] Schedule{activity} to Activity{schedules} // DOM [affects.primary.key] : [true] ResourceUsagePerDay{resource} to Resource{usagePerDay} // DOM [affects.primary.key] : [true] Plant{country} to Country{plants} // DOM [affects.primary.key] : [true] Activity{plant} to Plant{activities} } relationship OneToOne { // DOM [affects.primary.key] : [true] ResourceCapacity{resource} to Resource{capacity} }
In these JDL samples for a Composite Data Model application, capacity_planning.jdl
is the main JDL file. It includes all the JDL files of the model, where each one represents a scenario type. For more details, refer to Section Defining a Composite Data Model (CDM).
application { // DOM [java.collectorClass] : [CapacityPlanning] include "master_data.jdl" include "delivery_data.jdl" include "transactional_data.jdl" include "plan_data.jdl" }
@Description("Master data other scenario types") scenarioType MasterData { } @Description("Define a country by an ID and a name") entity Country { // DOM [primary.keys] : [id] @Description("ISO 3166-1 alpha-3 codes") id String required length(3), @Description("Country full name") name String } entity Plant { // DOM [primary.keys] : [plantId] plantId String required, latitude Double, longitude Double @DefaultValue("true") online Boolean } relationship ManyToOne { // DOM [affects.primary.key] : [true] Plant{country} to Country{plants} }
@Description("This is a scenario type used to store data associated to the delivery") scenarioType DeliveryData { } // Trucks handle the deliveries; they start and end their routes at the depot entity Truck { // DOM [primary.keys] : [id] id String, depotLongitude Double, depotLatitude Double } entity TruckRoute { // DOM [primary.keys] : [id] id String, start LocalDateTime, end LocalDateTime } relationship ManyToOne { // DOM [affects.primary.key] : [true] TruckRoute{truck} to Truck{routes} }
@Description("Scenario type used to store data for a plan") scenarioType TransactionalData { import MasterData } entity Activity { // DOM [primary.keys] : [id] id String required, name String, durationInHours Double min(0) max(4096) } entity Precedence { } entity Resource { // DOM [primary.keys] : [id] id String required, name String, active Boolean } entity ResourceCapacity { quantity Integer min(0) max(512) } entity Requirement { quantity Integer min(1) } relationship OneToOne { // DOM [affects.primary.key] : [true] ResourceCapacity{resource} to Resource{capacity} } relationship ManyToOne { // DOM [affects.primary.key] : [true] Requirement{activity} to Activity{requirements}, // DOM [affects.primary.key] : [true] Requirement{resource} to Resource{requirements}, // DOM [affects.primary.key] : [true] Precedence{first} to Activity{successors}, // DOM [affects.primary.key] : [true] Precedence{second} to Activity{predecessors}, // DOM [affects.primary.key] : [true] Activity{plant} to Plant{activities} }
@Description("Scenario type used to store data for a plan") scenarioType PlanData { import TransactionalData import MasterData import DeliveryData } entity Schedule { // DOM [primary.keys] : [start, end] start Instant required, end Instant required } entity ResourceUsagePerDay { // DOM [primary.keys] : [day] day Integer, numberOfHours Integer, } entity SolutionSummary { // DOM [single.row] : [true] start Instant, end Instant, timespan Integer } // Plant are sending resources to other plants entity ResourceDelivery { start LocalDateTime, end LocalDateTime } @Description("Calendar with cycle") entity Calendar { // DOM [java.collectionName] : [Calendars] // DOM [primary.keys] : [id] id String required } relationship ManyToOne { // DOM [affects.primary.key] : [true] ResourceDelivery{resource} to Resource{deliveries} // DOM [affects.primary.key] : [true] ResourceDelivery{from} to Plant{shippings} // DOM [affects.primary.key] : [true] ResourceDelivery{to} to Plant{deliveries} // DOM [affects.primary.key] : [true] ResourceDelivery{route} to TruckRoute{deliveries} // DOM [affects.primary.key] : [true] Schedule{resource} to Resource{schedules} // DOM [affects.primary.key] : [true] Schedule{activity} to Activity{schedules} // DOM [affects.primary.key] : [true] ResourceUsagePerDay{resource} to Resource{usagePerDay} Calendar{parentCalendar} to Calendar{subCalendars}, // DOM [affects.primary.key] : [true] Calendar{schedule} to Schedule{schedules} }
This section provides user with details on the entities and relationships generated using the above JDL files of the Capacity Planning sample.
It can be used to fill in the scenario template that corresponds to the application data model, which is available for download from Topbar menu Settings > Application Configuration > Excel Template.
In the Capacity Planning Application JDL Samples using a Composite Data Model, this entity relies on the following entities:
|
The Calendar
entity has the following attributes, which detail the hierarchical structure and scheduling of calendar activities:
id
- String
, required
: The unique identifier for the calendar.
parentCalendar.id
- String
: The identifier of the parent calendar.
parentCalendar.schedule.end
- DateTime
: The end date and time of the schedule in the parent calendar.
parentCalendar.schedule.start
- DateTime
: The start date and time of the schedule in the parent calendar.
parentCalendar.schedule.activity.id
- String
: The identifier of the activity in the parent calendar schedule.
parentCalendar.schedule.activity.plant.plantId
- String
: The plant identifier associated with the activity in the parent calendar schedule.
parentCalendar.schedule.activity.plant.country.id
- String
: The country identifier of the plant associated with the activity in the parent calendar schedule.
parentCalendar.schedule.resource.id
- String
: The resource identifier associated with the parent calendar schedule.
schedule.end
- DateTime
: The end date and time of the schedule.
schedule.start
- DateTime
: The start date and time of the schedule.
schedule.activity.id
- String
: The identifier of the activity in the schedule.
schedule.activity.plant.plantId
- String
: The plant identifier associated with the activity in the schedule.
schedule.activity.plant.country.id
- String
: The country identifier of the plant associated with the activity in the schedule.
schedule.resource.id
- String
: The resource identifier associated with the schedule.
Here are some sample values it can contain:
id | parentCalendar.id | parentCalendar.schedule.end | parentCalendar.schedule.start | parentCalendar.schedule.activity.id | parentCalendar.schedule.activity.plant.plantId | parentCalendar.schedule.activity.plant.country.id | parentCalendar.schedule.resource.id | schedule.end | schedule.start | schedule.activity.id | schedule.activity.plant.plantId | schedule.activity.plant.country.id | schedule.resource.id |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
CAL001 | PCAL001 | 2024-11-15T17:00:00 | 2024-11-15T09:00:00 | ACT001 | Paris | FR | RES001 | 2024-11-15T18:00:00 | 2024-11-15T10:00:00 | ACT002 | PLANT002 | UK | RES002 |
CAL002 | PCAL002 | 2024-12-01T12:00:00 | 2024-12-01T08:00:00 | ACT003 | London | UK | RES003 | 2024-12-01T16:00:00 | 2024-12-01T09:00:00 | ACT004 | PLANT004 | UK | RES004 |
In the Capacity Planning Application JDL Samples using a Composite Data Model, this entity relies on the following entities:
|
The ResourceDelivery
entity has the following attributes, detailing the delivery schedule and route information for resources:
end
- LocalDateTime
: The end date and time of the delivery.
start
- LocalDateTime
: The start date and time of the delivery.
from.plantId
- String
: The plant identifier for the origin of the delivery.
from.country.id
- String
: The country identifier for the origin of the delivery.
resource.id
- String
, required
: The unique identifier of the resource being delivered.
route.id
- String
: The identifier of the delivery route.
route.truck.id
- String
: The identifier of the truck used for the delivery route.
to.plantId
- String
: The plant identifier for the destination of the delivery.
to.country.id
- String
: The country identifier for the destination of the delivery.
Here are some sample values it can contain:
end | start | from.plantId | from.country.id | resource.id | route.id | route.truck.id | to.plantId | to.country.id |
---|---|---|---|---|---|---|---|---|
2024-11-15T18:00:00 | 2024-11-15T10:00:00 | Nice | FRA | RES001 | ROUTE001 | TRUCK001 | Paris | FRA |
2024-12-01T16:00:00 | 2024-12-01T08:00:00 | London | UK | RES002 | ROUTE002 | TRUCK002 | Paris | FRA |
In the Capacity Planning Application JDL Samples using a Composite Data Model, this entity relies on the following entities:
|
The ResourceUsagePerDay
entity has the following attributes, detailing the daily usage of resources in terms of hours:
day
- Integer
: The specific day for which the resource usage is recorded.
numberOfHours
- Integer
: The number of hours the resource is used on the specified day.
resource.id
- String
: The unique identifier of the resource being used.
Here are some sample values it can contain:
day | numberOfHours | resource.id |
---|---|---|
2024-11-13 | 8.0 | RES001 |
2024-11-14 | 6.5 | RES002 |
2024-11-15 | 7.0 | RES003 |
2024-11-16 | 5.5 | RES001 |
In the Capacity Planning Application JDL Samples using a Composite Data Model, this entity relies on the following entities:
|
The Schedule
entity has the following attributes, detailing the scheduling of activities and associated resources:
end
- Instant
: The end date and time of the scheduled activity.
start
- Instant
: The start date and time of the scheduled activity.
activity.id
- String
: The unique identifier for the activity.
activity.plant.plantId
- String
: The plant identifier associated with the activity.
activity.plant.country.id
- String
: The country identifier of the plant associated with the activity.
resource.id
- String
: The unique identifier of the resource used for the activity.
Here are some sample values it can contain:
end | start | activity.id | activity.plant.plantId | activity.plant.country.id | resource.id |
---|---|---|---|---|---|
2024-11-15T18:00:00 | 2024-11-15T10:00:00 | ACT001 | Paris | FR | RES001 |
2024-12-01T16:00:00 | 2024-12-01T08:00:00 | ACT002 | PLANT002 | USA | RES002 |
2024-12-15T15:00:00 | 2024-12-15T09:00:00 | ACT003 | London | UK | RES003 |
The SolutionSummary
entity has the following attributes, which summarize the solution time span:
end
- Instant
: The end date and time of the solution time span.
start
- Instant
: The start date and time of the solution time span.
timespan
- Integer
: The total duration of the solution time span.
Here are some sample values it can contain:
end | start | timespan |
---|---|---|
2024-11-15T18:00:00 | 2024-11-15T08:00:00 | 30 |
The Truck
entity has the following attributes, detailing the depot location and identifier for each truck:
depotLatitude
- Double
: The latitude coordinate of the truck's depot.
depotLongitude
- Double
: The longitude coordinate of the truck's depot.
id
- String
: The unique identifier of the truck.
Here are some sample values it can contain:
depotLatitude | depotLongitude | id |
---|---|---|
48.8566 | 2.3522 | TRUCK001 |
51.5074 | -0.1278 | TRUCK002 |
40.7128 | -74.0060 | TRUCK003 |
In the Capacity Planning Application JDL Samples using a Composite Data Model, this entity relies on the following entities:
|
The TruckRoute
entity has the following attributes, detailing the route information for each truck:
end
- LocalDateTime
: The end date and time of the truck route.
id
- String
: The unique identifier of the truck route.
start
- LocalDateTime
: The start date and time of the truck route.
truck.id
- String
: The unique identifier of the truck assigned to this route.
Here are some sample values it can contain:
end | id | start | truck.id |
---|---|---|---|
2024-11-15T18:00:00 | ROUTE001 | 2024-11-15T10:00:00 | TRUCK001 |
2024-12-01T17:00:00 | ROUTE002 | 2024-12-01T09:00:00 | TRUCK002 |
2024-12-15T20:00:00 | ROUTE003 | 2024-12-15T11:00:00 | TRUCK003 |
In the Capacity Planning Application JDL Samples using a Composite Data Model, this entity relies on the following entities:
|
The Activity
entity has the following attributes:
creationDate
- LocalDate
: The date the activity was created.
creationDateTime
- LocalDateTime
: The date and time the activity was created.
durationInHours
- Double
: The duration of the activity in hours.
id
- String
, required
: The unique identifier of the activity.
name
- String
: The name of the activity.
plant.plantId
- String
: The identifier of the plant associated with the activity.
plant.country.id
- String
: The country identifier of the plant associated with the activity.
Here are some sample values it can contain:
creationDate | creationDateTime | durationInHours | id | name | plant.plantId | plant.country.id |
---|---|---|---|---|---|---|
2024-11-13 | 2024-11-13T09:00:00 | 3.5 | ACT001 | Activity Alpha | Paris | FR |
2024-12-01 | 2024-12-01T14:30:00 | 2.0 | ACT002 | Activity Beta | NYC | USA |
2024-12-15 | 2024-12-15T11:15:00 | 5.0 | ACT003 | Activity Gamma | London | UK |
In the Capacity Planning Application JDL Samples using a Composite Data Model, this entity relies on the following entities:
|
The Precedence
entity has the following attributes, detailing the precedence relationships between activities, including associated plants and countries:
first.id
- String
, required
: The unique identifier of the first activity in the precedence relationship.
first.plant.plantId
- String
: The plant identifier associated with the first activity.
first.plant.country.id
- String
: The country identifier of the plant associated with the first activity.
second.id
- String
, required
: The unique identifier of the second activity in the precedence relationship.
second.plant.plantId
- String
: The plant identifier associated with the second activity.
second.plant.country.id
- String
: The country identifier of the plant associated with the second activity.
Here are some sample values it can contain:
first.id | first.plant.plantId | first.plant.country.id | second.id | second.plant.plantId | second.plant.country.id |
---|---|---|---|---|---|
ACT001 | Paris | FRA | ACT002 | NYC | USA |
ACT002 | NYC | USA | ACT003 | London | UK |
In the Capacity Planning Application JDL Samples using a Composite Data Model, this entity relies on the following entities:
|
The Requirement
entity has the following attributes, detailing the resource requirements for specific activities, including associated plants and countries:
quantity
- Integer
, required
: The quantity of the resource required for the activity.
activity.id
- String
: The unique identifier of the activity associated with the requirement.
activity.plant.plantId
- String
: The plant identifier associated with the activity.
activity.plant.country.id
- String
: The country identifier of the plant associated with the activity.
resource.id
- String
, required
: The unique identifier of the resource needed for the activity.
Here are some sample values it can contain:
quantity | activity.id | activity.plant.plantId | activity.plant.country.id | resource.id |
---|---|---|---|---|
50 | ACT001 | Paris | FRA | RES001 |
30 | ACT002 | NYC | USA | RES002 |
75 | ACT003 | London | UK | RES003 |
The Resource
entity has the following attributes:
active
- Boolean
: Indicates whether the resource is active.
id
- String
, required
: The unique identifier of the resource.
name
- String
: The name of the resource.
Here are some sample values it can contain:
active | id | name |
---|---|---|
true | RES001 | Resource Alpha |
false | RES002 | Resource Beta |
true | RES003 | Resource Gamma |
false | RES004 | Resource Delta |
In the Capacity Planning Application JDL Samples using a Composite Data Model, this entity relies on the following entities:
|
The Resource Capacity
entity has the following attributes:
quantity
- Integer
: The quantity available for the resource.
resource.id
- String
, required
: The unique identifier of the resource.
Here are some sample values it can contain:
quantity | resource.id |
---|---|
100 | RES123 |
250 | RES456 |
50 | RES789 |
75 | RES012 |
The Country
entity has the following attributes:
id
- String
, required
: The country code identifier.
name
- String
: The full name of the country.
Here are some values it can contain:
id | name |
---|---|
FRA | France |
UK | United Kingdom |
USA | United States of America |
SNG | Singapore |
In the Capacity Planning Application JDL Samples using a Composite Data Model, this entity relies on the following entities:
|
The Plant
entity has the following attributes:
geojson
- String
: The GeoJSON area of the plant location.
latitude
- Double
: The latitude of the plant location.
longitude
- Double
: The longitude of the plant location.
online
- Boolean
: The online status of the plant.
plantId
- String
, required
: The identifier of the plant.
country.id
- String
: The id of the country where the plant is located.
Here are some values it can contain:
geojson | latitude | longitude | online | plantId | country.id |
---|---|---|---|---|---|
{ "type": "FeatureCollection", "features": [ { "type": "Feature", "properties": { "name": "Paris", "country": "France", "population": 2148000 }, "geometry": { "type": "Polygon", "coordinates": [ [ [2.2241, 48.8156], [2.4699, 48.8156], [2.4699, 48.9021], [2.2241, 48.9021], [2.2241, 48.8156] ] ] } } ] } | 48.8566 | 2.3522 | true | Paris | FRA |
{ "type": "FeatureCollection", "features": [ { "type": "Feature", "properties": { "name": "New York City", "state": "New York", "country": "United States", "population": 8419600 }, "geometry": { "type": "Polygon", "coordinates": [ [ [-74.2591, 40.4774], [-73.7004, 40.4774], [-73.7004, 40.9176], [-74.2591, 40.9176], [-74.2591, 40.4774] ] ] } } ] } | 40.7128 | -74.0060 | true | NYC | USA |
{ "type": "FeatureCollection", "features": [ { "type": "Feature", "properties": { "name": "London", "country": "United Kingdom", "population": 8982000 }, "geometry": { "type": "Polygon", "coordinates": [ [ [-0.5103, 51.2868], [0.3340, 51.2868], [0.3340, 51.6919], [-0.5103, 51.6919], [-0.5103, 51.2868] ] ] } } ] } | 51.5074 | -0.1278 | true | London | UK |
{ "type": "FeatureCollection", "features": [ { "type": "Feature", "properties": { "name": "Singapore", "country": "Singapore", "population": 5639000 }, "geometry": { "type": "Polygon", "coordinates": [ [ [103.6050, 1.2098], [104.0327, 1.2098], [104.0327, 1.4713], [103.6050, 1.4713], [103.6050, 1.2098] ] ] } } ] } | 1.3521 | 103.8198 | true | Singapore | SNG |
{ "type": "FeatureCollection", "features": [ { "type": "Feature", "properties": { "name": "Nice", "region": "Provence-Alpes-Côte d'Azur", "country": "France", "population": 340000 }, "geometry": { "type": "Polygon", "coordinates": [ [ [7.2174, 43.6650], [7.3050, 43.6650], [7.3050, 43.7450], [7.2174, 43.7450], [7.2174, 43.6650] ] ] } } ] } | 43.7102 | 7.2620 | true | Nice | FRA |
Here we provide some sample scripted tasks and screenshots of the web client.
Basic tasks are tasks that do not require running a routine on the Backend Service, nor on an optimization server. User-defined routine tasks are described in Section Understanding User-Defined Routine Statements.
This task launches a routine on the Backend Service to log a 'Hello' message..
@Bean public ScriptedTaskDescription helloWorldTask() { ScriptedTaskDescription task = new ScriptedTaskDescription("HelloWorldTask", "*Greetings (a sample)"); task.setDescription("Launch a backend routine to log a 'Hello' message."); task.getScript() .addStatement(AskInputStatement.of("name", true, ParameterTypes.TEXT, "The name of the person to greet.")) .addStatement(ExecuteRoutineStatement.of(StringExpression.of("HelloWorld")) .withInput(VariableAccessExpression.of("name"))); return task; }
This task runs a checker on the selected scenario schema by calling CheckSchemaStatement.forScenario
. Note that this statement returns exit code 1 when the check ends with errors. For that, we check in the following statement the return code of the check statement IfStatement.of(BooleanExpression.LAST_STATEMENT_EXIT_CODE_NOT_OK...
. If the return code is not OK (not 0), we interrupt the task with ExitTaskStatement.failing
. The following statement is an example of how to check the data status of a scenario directly ScenarioStatusExpression.dataStatusIs
(or ScenarioStatusExpression.dataStatusIs
). In this sample task, we interrupt the execution with ExitTaskStatement.alerting
if the data status is ScenarioStatusExpression.WARNING
.
We could have replaced the condition, following which we do ExitTaskStatement.failing(StringExpression.of("Scenario Schema Check ended with ERRORS"))
, with:
IfStatement.of(ScenarioStatusExpression.dataStatusIs(VariableAccessExpression.of("scenario"), ScenarioStatusExpression.ERROR), ExitTaskStatement.failing(StringExpression.of("Scenario Schema Check ended with ERRORS")))
Note that the possible values for schema or data statuses are: UNCHECKED
, CHECKING
, VALID
, WARNING
, and ERROR
public class Tasks { @Bean public ScriptedTaskDescription checkScenarioSchemaTask() { ScriptedTaskDescription task = new ScriptedTaskDescription("checkScenarioSchema", "Test - Check Scenario Schema using CheckSchemaStatement"); task.setDescription("Check Scenario Schema, using CheckSchemaStatement"); task.getScript() .addStatement(AskInputStatement.of("scenario", true, JobInputType.scenarioId(WRITABLE))) .addStatement(CheckSchemaStatement.forScenario(VariableAccessExpression.of("scenario"))) .addStatement(IfStatement.of(BooleanExpression.LAST_STATEMENT_EXIT_CODE_NOT_OK, ExitTaskStatement.failing(StringExpression.of("Scenario Schema Check ended with ERRORS")) )) .addStatement(ExitTaskStatement.alerting(StringExpression.of("Scenario Schema Check ended with WARNINGS")) .when(ScenarioStatusExpression.dataStatusIs(VariableAccessExpression.of("scenario"), ScenarioStatusExpression.WARNING)) ); return task; } }
This task creates an empty Scenario with no data.
@Bean public ScriptedTaskDescription createEmptyScenarioTask() { ScriptedTaskDescription task = new ScriptedTaskDescription("CreateEmptyScenarioTask", "Create an empty Scenario"); task.setDescription("Creates an empty Scenario with no data"); setI18nKeys(task, "CREATE_EMPTY_SCENARIO"); var scenarioId = VariableAccessExpression.of("scenarioId"); var folder = VariableAccessExpression.ofFolder(); var scenarioCreationParameters = VariableAccessExpression.ofScenarioCreationExpression(); var createdScenarios = VariableAccessExpression.of("createdScenarios"); Supplier<Statement> deleteAllCreatedScenariosAndFail = () -> Block.of( ForeachStatement.of(scenarioId.getVariableName(), createdScenarios, DeleteScenarioStatement.of(scenarioId).moveToTrash(BooleanExpression.FALSE)), ExitTaskStatement.alerting(StringExpression.of("Scenario could not be imported due to errors.")) );
This task imports a file content into a new scenario, supporting several formats.
@Bean public ScriptedTaskDescription scenarioImportTask() { ScriptedTaskDescription task = new ScriptedTaskDescription("ScenarioImportTask", "Create scenario from file"); task.setDescription("Import a file content into a new scenario, supporting several formats"); setI18nKeys(task, "SCENARIO_IMPORT"); var folder = VariableAccessExpression.ofFolder(); var scenarioFile = VariableAccessExpression.ofFile(); var scenarioCreationParameters = VariableAccessExpression.ofScenarioCreationExpression(); var createdScenarios = VariableAccessExpression.of("createdScenarios"); var issues = VariableAccessExpression.of("issues"); task.getScript() .addStatement(AskInputStatement.ofVariable(folder, true, JobInputType.FOLDER_IN_WORKSPACE, "The Folder in a Workspace where to import the new Scenario ")) .addStatement(AskInputStatement.ofVariable(scenarioFile, true, ParameterTypes.file("xlsx", "xcsv", "dbrf", "gz", "zip"), "The Scenario file containing the data (.xlsx, .xcsv, .dbrf, .gz, .zip)")) .addStatement(AskInputStatement.ofVariable(scenarioCreationParameters, true, JobInputType.SCENARIO_CREATION_PARAMETERS, "Parameters to create the Scenario")) // Create the new scenario using metadata if exists. .addStatement(SetVariableStatement.of( createdScenarios.getVariableName(), ScenarioCreationExpression.of( scenarioCreationParameters, folder ) .withFileForProperties(scenarioFile) )) // Import the scenarios or delete them if an error occurs .addStatement(DoStatementOnLockedScenariosOrDeleteThem.of( createdScenarios, Block.of( // Save the file content in the data service ImportScenarioStatement.of(createdScenarios, scenarioFile).storingIssuesInto(issues.getVariableName()), // Save the issues to output SetTaskOutputStatement.of("issues", issues) ) )); return task; }
This task imports a list of files into new scenarios, supporting several formats.
@Bean public ScriptedTaskDescription scenariosImportTask() { ScriptedTaskDescription task = new ScriptedTaskDescription("ScenariosImportTask", "Create scenarios from files"); task.setDescription("Import a list of files into new scenarios, supporting several formats"); setI18nKeys(task, "SCENARIOS_IMPORT"); var folder = VariableAccessExpression.ofFolder(); var scenarioFiles = VariableAccessExpression.ofFile(); var scenarioCreationParameters = VariableAccessExpression.ofScenarioCreationExpression(); // Variables for ForeachStatement var scenarioFile = VariableAccessExpression.of("scenarioFile"); var createdScenarios = VariableAccessExpression.of("createdScenarios"); task.getScript() .addStatement(AskInputStatement.ofVariable(folder, true, JobInputType.FOLDER_IN_WORKSPACE, "The Folder in a Workspace where to import the new Scenarios")) .addStatement(AskInputStatement.ofVariable(scenarioFiles, true, JobInputType.files(1, null, "xlsx", "dbrf", "gz", "zip"), "The Scenario files containing the data (.xlsx, .dbrf, .gz, .zip)")) .addStatement(AskInputStatement.ofVariable(scenarioCreationParameters, true, JobInputType.SCENARIO_CREATION_PARAMETERS, "Parameters to create the Scenario")) .addStatement(ForeachStatement.of( scenarioFile.getVariableName(), scenarioFiles, // Create the new scenario using metadata if exists. SetVariableStatement.of( createdScenarios.getVariableName(), ScenarioCreationExpression.of( scenarioCreationParameters, folder ) .withFileForProperties(scenarioFile) .withScenarioNamePrefix( StringExpression.concat( StringExpression.ofFileName(scenarioFile), StringExpression.of(" - ") )) ), // Import the scenarios or delete them if an error occurs DoStatementOnLockedScenariosOrDeleteThem.of( createdScenarios, // Save the file content in the data service ImportScenarioStatement.of(createdScenarios, scenarioFile) ) )); return task; }
This task duplicates the selected scenario.
@Bean public ScriptedTaskDescription duplicateScenarioTask() { ScriptedTaskDescription task = new ScriptedTaskDescription("DuplicateScenarioTask", "Duplicate Scenario"); task.setDescription("Duplicate the selected scenario"); setI18nKeys(task, "DUPLICATE_SCENARIO"); var scenario = VariableAccessExpression.ofScenario(); var newScenarioName = VariableAccessExpression.of("New scenario name"); var duplicateVisibleScenarios = VariableAccessExpression.of("Duplicate visible scenarios"); var newScenarioIds = VariableAccessExpression.of("Created scenario IDs"); task.getScript() .addStatement(AskInputStatement.ofVariable(scenario, true, JobInputType.SCENARIO_ID)) .addStatement(AskInputStatement.ofVariable(newScenarioName,false, ParameterTypes.TEXT)) .addStatement(AskInputStatement.ofVariable(duplicateVisibleScenarios,false, ParameterTypes.BOOLEAN)) .addStatement(ExecuteRoutineStatement .of(StringExpression.of("com.decisionbrain.gene.DuplicateScenarioRoutine")) .withInput(scenario) .withInput(newScenarioName) .withInput(duplicateVisibleScenarios) .withOutput("new-scenario-ids", newScenarioIds.getVariableName()) ) .addStatement(SetTaskOutputStatement.of("New Scenario IDs", newScenarioIds)); return task; }
This task duplicates a custom view or dashboard under the same parent as the original.
@Bean public ScriptedTaskDescription duplicateViewDashboard() { ScriptedTaskDescription task = new ScriptedTaskDescription("DuplicateViewDashboard", "Duplicate View or Dashboard"); task.setDescription("Copies Custom View or Custom Dashboard under the same parent as the original."); setI18nKeys(task, "DUPLICATE_VIEW_DASHBOARD"); var pathUuid = VariableAccessExpression.of("pathUuid"); task.getScript() .addStatement(AskInputStatement.ofVariable(pathUuid, true, ParameterTypes.TEXT, "Id of the Custom View/Dashboard to copy")) .addStatement(ExecuteRoutineStatement .of(StringExpression.of("com.decisionbrain.gene.DuplicateViewDashboard")) .withInput(pathUuid)); return task; }
This task executes a ruleset on a scenario.
@Bean public ScriptedTaskDescription executeRulesTask() { ScriptedTaskDescription task = new ScriptedTaskDescription( "ExecuteRulesetOnScenarioTask", "Execute Ruleset On Scenario Task"); task.setDescription("Execute the given ruleset on the given scenario"); setI18nKeys(task, "EXECUTE_RULES"); var scenario = VariableAccessExpression.ofScenario(); var scriptParameterName = VariableAccessExpression.of("scriptParameterName"); var executionLogs = VariableAccessExpression.of("executionLogs"); var exitCode = VariableAccessExpression.of("exitCode"); task.getScript() .addStatement(AskInputStatement.ofVariable(scenario, true, JobInputType.SCENARIO_ID)) .addStatement(AskInputStatement.ofVariable(scriptParameterName, true, JobInputType.TEXT)) .addStatement(ExecuteRoutineStatement // For the given routine .of(EXECUTE_RULESET_ROUTINE_NAME) // Pass the input parameters .withInput(ScenarioDataExpression.of(scenario)) .withInput(scriptParameterName) // And retrieve the logs of the routine execution in a variable .withOutput(executionLogs.getVariableName(), executionLogs.getVariableName())) // Keep the exit code of the routine in a variable .addStatement(SetVariableStatement.of(exitCode.getVariableName(), NumericExpression.LAST_STATEMENT_EXIT_CODE)) // Set the output of the task to the routine execution logs .addStatement(SetTaskOutputStatement.of(executionLogs.getVariableName(), executionLogs)) // Process routine errors exit codes .addStatement(alertingTheTaskWithMessageWhen(exitCode, "An error occurred during the processing the routine input parameters", ROUTINE_PARAMETER_ERROR_EXIT_CODE)) .addStatement(alertingTheTaskWithMessageWhen(exitCode, "An error occurred during the compilation of the ruleset", RULESET_COMPILATION_ERROR_EXIT_CODE)) .addStatement(alertingTheTaskWithMessageWhen(exitCode, "An error occurred during the execution of the ruleset", RULESET_EXECUTION_ERROR_EXIT_CODE)) .addStatement(alertingTheTaskWithMessageWhen(exitCode, "An unexpected error occurred during the routine execution", UNKNOWN_ERROR_EXIT_CODE)); return task; }
This task exports the contents of the selected scenario to a GZIP archive, in DBRF format.
@Bean public ScriptedTaskDescription dbrfExportTask() { ScriptedTaskDescription task = new ScriptedTaskDescription("DbrfExportTask", "Export scenario to DBRF"); task.setDescription("Export the contents of the selected scenario to a GZIP archive, in DBRF format"); setI18nKeys(task, "DBPF_EXPORT"); var scenario = VariableAccessExpression.ofScenario(); var baseFileName = VariableAccessExpression.of("base file name"); var filter = VariableAccessExpression.ofFilter(); task.getScript() .addStatement(AskInputStatement.ofVariable(scenario, true, JobInputType.SCENARIO_ID)) .addStatement(AskInputStatement.ofVariable(baseFileName, true, ParameterTypes.TEXT, "Name of the file to export to. Warning: a '.gz' extension will be appended.")) .addStatement(AskInputStatement.ofVariable(filter, false, JobInputType.ENTITIES, "Select the tables to export")) .addStatement(SetTaskOutputStatement.of("DBRF file", FileExpression.of( StringExpression.concat(baseFileName, StringExpression.of(".gz")), BlobExpression.of( ScenarioDataExpression.of(scenario) .withFormat(ScenarioDataFormat.DBRF) .onlyTables(filter)), StringExpression.of("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet") ))); return task; }
This task exports the selected scenario to an Excel file.
@Bean public ScriptedTaskDescription excelExportTask() { ScriptedTaskDescription task = new ScriptedTaskDescription("ExcelExportTask", "Export scenario to Excel"); task.setDescription("Exports the selected scenario to an Excel file"); setI18nKeys(task, "EXCEL_EXPORT"); var scenario = VariableAccessExpression.ofScenario(); var baseFileName = VariableAccessExpression.of("base file name"); var filter = VariableAccessExpression.ofFilter(); VariableAccessExpression scenarioData = VariableAccessExpression.of("scenario-data"); task.getScript() .addStatement(AskInputStatement.ofVariable(scenario, true, JobInputType.SCENARIO_ID)) .addStatement(AskInputStatement.ofVariable(baseFileName, true, ParameterTypes.TEXT, "Name of the file to export to. Warning: a '.xlsx' extension will be appended.")) .addStatement(AskInputStatement.ofVariable(filter, false, JobInputType.ENTITIES, "Select the tables to export")) // Load the scenario data into a variable .addStatement(SetVariableStatement.of( scenarioData.getVariableName(), ScenarioDataExpression.of(scenario).withFormat(ScenarioDataFormat.EXCEL).onlyTables(filter) )) // Set the Excel file as task output .addStatement(SetTaskOutputStatement.of("Excel file", FileExpression.of( StringExpression.concat(baseFileName, StringExpression.of(".xlsx")), BlobExpression.of(scenarioData), StringExpression.of("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet") ))) // If there are errors or warnings, we exit the task with an alert. // The only known case is when the scenario content does not fit into an Excel file. .addStatement(ExitTaskStatement.alerting(StringExpression.of("Exporting the scenario data was not completed successfully")) .when(ScenarioDataExpression.hasErrorsOrWarnings(scenarioData)) ); return task; }
This task exports the contents of the selected scenario to an XCSV archive file (ZIP with CSV).
@Bean public ScriptedTaskDescription xcsvExportTask() { ScriptedTaskDescription task = new ScriptedTaskDescription("XCSVExportTask", "Export scenario to XCSV"); task.setDescription("Export the contents of the selected scenario to a XCSV archive file (ZIP with CSV)"); setI18nKeys(task, "XCSV_EXPORT"); task.getScript() .addStatement(AskInputStatement.of("scenario", true, JobInputType.SCENARIO_ID)) .addStatement(AskInputStatement.of("base file name", true, ParameterTypes.TEXT, "Name of the file to export to. Warning: a '.xcsv' extension will be appended.")) .addStatement(AskInputStatement.of("filter", false, JobInputType.ENTITIES, "Select the tables to export")) .addStatement(SetTaskOutputStatement.of("XCSV file", FileExpression.of( StringExpression.concat(VariableAccessExpression.of("base file name"), StringExpression.of(".xcsv")), BlobExpression.of(ScenarioDataExpression .of(VariableAccessExpression.of("scenario")) .withFormat(ScenarioDataFormat.XCSV) .onlyTables(VariableAccessExpression.of("filter"))), StringExpression.of("application/octet-stream") ))); return task; }
This task exports the contents of the selected scenario to a ZIP archive, in CSV format.
@Bean public ScriptedTaskDescription zipExportTask() { ScriptedTaskDescription task = new ScriptedTaskDescription("ZipExportTask", "Export scenario to ZIP"); task.setDescription("Export the contents of the selected scenario to a ZIP archive, in CSV format"); setI18nKeys(task, "ZIP_EXPORT"); var scenario = VariableAccessExpression.ofScenario(); var baseFileName = VariableAccessExpression.of("base file name"); var filter = VariableAccessExpression.ofFilter(); task.getScript() .addStatement(AskInputStatement.ofVariable(scenario, true, JobInputType.SCENARIO_ID)) .addStatement(AskInputStatement.ofVariable(baseFileName, true, ParameterTypes.TEXT, "Name of the file to export to. Warning: a '.zip' extension will be appended.")) .addStatement(AskInputStatement.ofVariable(filter, false, JobInputType.ENTITIES, "Select the tables to export")) .addStatement(SetTaskOutputStatement.of("ZIP file", FileExpression.of( StringExpression.concat(baseFileName, StringExpression.of(".zip")), BlobExpression.of(ScenarioDataExpression.of(scenario).onlyTables(filter).withFormat(CSV)), StringExpression.of("application/octet-stream") ))); return task; }
This task sets a scenario property (key and value pair) for the specified scenario. It takes as input:
a scenario Id
a property key
a property value
@Configuration public class Tasks { @Bean public ScriptedTaskDescription setScenarioPropertyTask() { ScriptedTaskDescription task = new ScriptedTaskDescription("SetScenarioProperty", "Set Scenario Property"); task.setDescription("Set a property for the selected scenario"); task.getScript() .addStatement(AskInputStatement.of("scenario", true, JobInputType.scenarioId(WRITABLE))) .addStatement(AskInputStatement.of("property name", true, JobInputType.TEXT)) .addStatement(AskInputStatement.of("property value", true, JobInputType.TEXT)) //set property (key and value) from input variables .addStatement(SetScenarioPropertyStatement.of(VariableAccessExpression.of("scenario"), VariableAccessExpression.of("property name"), VariableAccessExpression.of("property value"))) //Make the task return a result, which is a string representing the new property, having as key the value entered in "property name" and as value what is entered in "property value" //using the formatting "Scenario property[{property name}] new value is: {property value}" .addStatement(SetTaskOutputStatement.of("result", StringExpression.concat( StringExpression.of("Scenario property["), VariableAccessExpression.of("property name"), StringExpression.of("] new value is: "), ScenarioPropertyExpression.of(VariableAccessExpression.of("scenario"), VariableAccessExpression.of("property name"))) )); return task; } }
The generated web client component for this task is the following:
![]() |
Note that it is possible to create a scripted task to fetch the value of a scenario property by using ScenarioPropertyExpression. In this case, we are getting the property that was just created, so we use the key that was entered in "property name" by using VariableAccessExpression.of("property name")
. We can get the value of a property that we know is already defined in the scenario. For instance, to get the value of the scenario property "property1", we can use the following expression: ScenarioPropertyExpression.of(VariableAccessExpression.of("scenario"), StringExpression.of("property1"))
This task shares the selected scenario with a different workspace.
@Bean public ScriptedTaskDescription shareScenarioTask() { ScriptedTaskDescription task = new ScriptedTaskDescription("ShareScenarioTask", "Share Scenario"); task.setDescription("Share the selected scenario to a different workspace"); setI18nKeys(task, "SHARE_SCENARIO"); var scenario = VariableAccessExpression.ofScenario(); var workspace = VariableAccessExpression.of("Share to"); var newScenarioId = VariableAccessExpression.of("newScenarioId"); task.getScript() .addStatement(AskInputStatement.ofVariable(scenario, true, JobInputType.SCENARIO_ID)) .addStatement(AskInputStatement.ofVariable(workspace, true, JobInputType.workspaceId(JobInputType.WorkspaceOrScenarioFilter.UNIQUE), "The Uuid of the new workspace to share the scenario to")) .addStatement(ExecuteRoutineStatement .of(StringExpression.of("com.decisionbrain.gene.ShareScenarioRoutine")) .withInput(scenario) .withInput(workspace) .withOutput("new-scenario-id", newScenarioId.getVariableName())) .addStatement(SetTaskOutputStatement.of("New Scenario ID", newScenarioId)); return task; }
DOC
allows launching worker tasks using the Optimization Server. For more details, refer to Sections Understanding Optimization Server Statements and Implementing Worker Tasks.
This task takes scenarioId and a text message as input, adds the message to the scenario issues collection, then returns an output collector of the modified scenario as a result.
@Configuration public class Tasks { @Bean public ScriptedTaskDescription addIssueWithOptimizationServerTask() { ScriptedTaskDescription task = new ScriptedTaskDescription("addIssueWithOptimizationServer", "Add Issue with OptimizationServer"); task.setDescription("Add an issue to the selected scenario, using an OptimizationServer task"); task.getScript() .addStatement(AskInputStatement.of("scenario", true, JobInputType.scenarioId(WRITABLE))) .addStatement(AskInputStatement.of("Issue Message", true, JobInputType.TEXT, "The text of the issue to add")) .addStatement(ExecuteOptimizationServerTaskStatement .forTaskId(StringExpression.of("Add Issue with OptimizationServer")) .withInput("Issue Message", VariableAccessExpression.of("Issue Message")) .withInput("inputCollector", ScenarioDataExpression.of(VariableAccessExpression.of("scenario"))) .withOutputScenario("outputCollector", VariableAccessExpression.of("scenario"), StringExpression.of("GeneIssue"), StringExpression.of("Activity"))); return task; } }
Note that the table names mentioned in the arguments of withOutputScenario
can include list expressions. That is, the corresponding line in the example above could have been written as follows:
.withOutputScenario("outputCollector", VariableAccessExpression.of("scenario"), ListExpression.of(StringExpression.of("GeneIssue"), StringExpression.of("Activity")))
A slightly different version of this task is a task that creates a new scenario (with a name given as input) and adds an issue message to the newly created scenario. To create a new scenario, we use StringExpression.idOfNewScenario()
as in the following task:
@Configuration public class Tasks { @Bean public ScriptedTaskDescription addIssueToNewScenarioWithOptimizationServerTask() { ScriptedTaskDescription task = new ScriptedTaskDescription("createScenarioAndAddIssueWithOptimizationServer", "Add Issue to new scenario"); task.setDescription("Add an issue to a new scenario, using an OptimizationServer task"); task.getScript() .addStatement(AskInputStatement.of("Issue Message", true, JobInputType.TEXT, "The text of the issue to add")) .addStatement(AskInputStatement.of("Scenario Name", true, JobInputType.TEXT, "The name of the scenario to create")) .addStatement(AskInputStatement.of("workspace", true, JobInputType.WORKSPACE_ID, "The Workspace where to create the new Scenario")) .addStatement(SetVariableStatement.of("scenarioId", StringExpression.idOfNewScenario(VariableAccessExpression.of("Scenario Name"), VariableAccessExpression.of("workspace")))) .addStatement(ExecuteOptimizationServerTaskStatement .forTaskId(StringExpression.of("Add Issue with OptimizationServer")) .withInput("Issue Message", VariableAccessExpression.of("Issue Message")) .withInput("inputCollector", ScenarioDataExpression.of(VariableAccessExpression.of("scenarioId"))) .withOutputScenario("outputCollector", VariableAccessExpression.of("scenarioId"), StringExpression.of("GeneIssue"))); return task; } }
The OptimizationServer task with id "Add Issue with OptimizationServer" (for both versions above) is defined in OptimizationServer tasks configuration in worker.yml
as follows:
tasks: - id: Add Issue with OptimizationServer implementationClassName: com.decisionbrain.gene.execution.worker.AddIssueTask description: This task adds an issue to the provided scenario inputs: - name: Issue Message type: TEXT description: The text of the issue to add required: true - name: inputCollector type: BINARY description: Collector with initial data required: true outputs: - name: outputCollector type: BINARY description: Collector with initial data plus added issue required: true
With the following implementation class:
import com.decisionbrain.optimserver.common.parameter.Parameter; import com.decisionbrain.optimserver.worker.api.ExecutionContext; import com.decisionbrain.optimserver.worker.api.Task; import com.decisionbrain.sample.model.Activity; import com.decisionbrain.sample.model.CapacityPlanning; import com.decisionbrain.sample.model.GeneIssue; import com.decisionbrain.sample.model.impl.CapacityPlanningFactoryImpl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.IOException; import java.util.Arrays; public class AddIssueTask implements Task { private static final Logger LOGGER = LoggerFactory.getLogger("AddIssueTask"); @Override public void execute(Parameter input, Parameter output, ExecutionContext context) { CapacityPlanning collector = getInputCollector(input); LOGGER.info("Seeing {} existing issues", collector.getIssues().size()); GeneIssue issue = collector.createGeneIssue(); issue.setSeverity("INFO"); issue.setMessage(new String(input.get("Issue Message"))); emitOutputCollector(output, collector); } private CapacityPlanning getInputCollector(Parameter input) { try { CapacityPlanning collector = new CapacityPlanningFactoryImpl().createCollector(); byte[] inputData = input.get("inputCollector"); collector.loadSnapshot(inputData); return collector; } catch (Exception e) { throw new RuntimeException("Error while preparing data", e); } } private void emitOutputCollector(Parameter output, CapacityPlanning collector) { try { output.emit("outputCollector", collector.saveSnapshot(Arrays.asList(Activity.class, GeneIssue.class))); } catch (IOException e) { throw new RuntimeException("Error while saving data", e); } } }
The generated web client component for this task is the following:
![]() |
When using ScenarioDataExpression
, you can choose the URI
format. This brings some special features:
Only an URI
to fetch the scenario data is sent to the worker. The input scenario data are not loaded and transferred as bytes through the OptimizationServer, but they are directly streamed between the Data Service and the worker upon worker demand. This leads to better performance and reduced memory usage.
The input scenario data modifications can be persisted directly by the worker (the data are streamed directly to the Data Service), which means that you will not need to declare an output scenario in your task.
The task does the same logic as the previous task example except it uses a Scenario URI to read and update the scenario:
@Configuration public class Tasks { @Bean public ScriptedTaskDescription addIssueWithOptimizationServerWithUriTask() { ScriptedTaskDescription task = new ScriptedTaskDescription("addIssueWithOptimizationServerWithUri", "Add Issue with OptimizationServer using URI"); task.setDescription("Add an issue to the selected scenario, using an OptimizationServer task using URI"); task.getScript() .addStatement(AskInputStatement.of("scenario", true, JobInputType.scenarioId(WRITABLE))) .addStatement(AskInputStatement.of("Issue Message", true, JobInputType.TEXT, "The text of the issue to add")) .addStatement(ExecuteOptimizationServerTaskStatement .forTaskId(StringExpression.of("Add Issue with OptimizationServer using URI")) .withInput("Issue Message", VariableAccessExpression.of("Issue Message")) .withInput("inputCollector", ScenarioDataExpression.of(VariableAccessExpression.of("scenario")).withFormat(ScenarioDataFormat.URI))); return task; } }
Compared to the previous task example, note that the call to withFormat(ScenarioDataFormat.URI)
has been added and the call to withOutputScenario(...)
has been removed.
The OptimizationServer task with id "Add Issue with OptimizationServer using URI" is defined in OptimizationServer tasks configuration in worker.yml
as follows:
tasks: - id: Add Issue with OptimizationServer using URI implementationClassName: com.decisionbrain.gene.execution.worker.AddIssueUsingUriTask description: This task adds an issue to the provided scenario inputs: - name: Issue Message type: TEXT description: The text of the issue to add required: true - name: inputCollector type: BINARY description: Collector with initial data required: true
Compared to the previous task example, note that the outputCollector
output has been removed.
With the following implementation class:
import com.decisionbrain.gene.worker.component.DbDomCollectorDAO; import com.decisionbrain.gene.worker.task.GeneTask; import com.decisionbrain.optimserver.common.parameter.Parameter; import com.decisionbrain.optimserver.worker.api.ExecutionContext; import com.example.caplan.model.CapacityPlanning; import com.example.caplan.model.GeneIssue; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.List; public class AddIssueUsingUriTask extends GeneTask<CapacityPlanning> { private static final Logger LOGGER = LoggerFactory.getLogger("AddIssueTask"); @Override public void execute(Parameter input, Parameter output, ExecutionContext context) { DbDomCollectorDAO<CapacityPlanning> collectorDAO = createDbDomCollectorDAO(context, "inputCollector"); // Load only issues CapacityPlanning collector = collectorDAO.loadScenario(List.of(GeneIssue.class)); LOGGER.info("Seeing {} existing issues", collector.getGeneIssues().size()); GeneIssue issue = collector.createGeneIssue(); issue.setSeverity("INFO"); issue.setMessage(context.getInputData("Issue Message").loadAsString()); // Save only issues collectorDAO.saveScenario(collector, List.of(GeneIssue.class)); } }
This task runs the checker task in the Optimization server.
@Bean public ScriptedTaskDescription checker() { ScriptedTaskDescription task = new ScriptedTaskDescription("CheckerTask", "Optimization server - Run Checker task"); task.setDescription("Run the checker task in the Optimization server"); VariableAccessExpression scenario = VariableAccessExpression.of(SCENARIO); task.getScript() .addStatement(AskInputStatement.of(scenario.getVariableName(), true, JobInputType.scenarioId(WRITABLE))) .addStatement(ExecuteOptimizationServerTaskStatement .forTaskId(StringExpression.of("CheckerTask")) .usingOnDemandContext(StringExpression.of("small")) .withInput(INPUT_COLLECTOR, ScenarioDataExpression.of(scenario)) .withOutputScenario(OUTPUT_COLLECTOR, scenario, StringExpression.of("GeneIssue")) ); return task; }
This task runs the engine task in the Optimization server.
@Bean public ScriptedTaskDescription engineTask() { ScriptedTaskDescription task = new ScriptedTaskDescription("EngineTask", "Optimization server - Run Engine task"); task.setDescription("Run the engine task in the Optimization server"); VariableAccessExpression scenario = VariableAccessExpression.of(SCENARIO); task.getScript() .addStatement(AskInputStatement.of(scenario.getVariableName(), true, JobInputType.scenarioId(WRITABLE))) .addStatement(ExecuteOptimizationServerTaskStatement .forTaskId(StringExpression.of("EngineTask")) .withInput(INPUT_COLLECTOR, ScenarioDataExpression.of(scenario)) .withOutputScenario(OUTPUT_COLLECTOR, scenario) ); return task; }
This task runs the Python engine task using a DOM collector in the Optimization server.
@Bean public ScriptedTaskDescription pythonEngineCollectorTask() { ScriptedTaskDescription task = new ScriptedTaskDescription("PythonEngineCollectorTask", "Optimization server - Run Python Engine task using collector"); task.setDescription("Run the Python engine task using collector in the Optimization server"); VariableAccessExpression scenario = VariableAccessExpression.of(SCENARIO); task.getScript() .addStatement(AskInputStatement.of(scenario.getVariableName(), true, JobInputType.scenarioId(WRITABLE))) .addStatement(ExecuteOptimizationServerTaskStatement .forTaskId(StringExpression.of("PythonEngineCollectorTask")) .withInput(INPUT_COLLECTOR, ScenarioDataExpression.of(scenario)) .withOutputScenario(OUTPUT_COLLECTOR, scenario) ); return task; }
This task runs the Python engine task using a dataframe in the Optimization server.
@Bean public ScriptedTaskDescription pythonEngineDataframeTask() { ScriptedTaskDescription task = new ScriptedTaskDescription("PythonEngineDataframeTask", "Optimization server - Run Python Engine task using dataframe"); task.setDescription("Run the Python engine task using dataframes in the Optimization server"); VariableAccessExpression scenario = VariableAccessExpression.of(SCENARIO); task.getScript() .addStatement(AskInputStatement.of(scenario.getVariableName(), true, JobInputType.scenarioId(WRITABLE))) .addStatement(ExecuteOptimizationServerTaskStatement .forTaskId(StringExpression.of("PythonEngineDataframeTask")) .withInput(INPUT_COLLECTOR, ScenarioDataExpression.of(scenario)) .withOutputScenario(OUTPUT_COLLECTOR, scenario, StringExpression.of("GeneIssue")) ); return task; }