Chapter 14. Deploying and using the Red Hat build of OptaPlanner vehicle route planning starter application

As a developer, you can use the OptaWeb Vehicle Routing starter application to optimize your vehicle fleet deliveries.

Prerequisites

  • OpenJDK (JDK) 11 is installed. Red Hat build of Open JDK is available from the Software Downloads page in the Red Hat Customer Portal (login required).
  • Apache Maven 3.6 or higher is installed. Maven is available from the Apache Maven Project website.

14.1. What is OptaWeb Vehicle Routing?

The main purpose of many businesses is to transport various types of cargo. The goal of these businesses is to deliver a piece of cargo from the loading point to a destination and use its vehicle fleet in the most efficient way. One of the main objectives is to minimize travel costs which are measured in either time or distance.

This type of optimization problem is referred to as the vehicle routing problem (VRP) and has many variations.

Red Hat build of OptaPlanner can solve many of these vehicle routing variations and provides solution examples. OptaPlanner enables developers to focus on modeling business rules and requirements instead of learning constraint programming theory. OptaWeb Vehicle Routing expands the vehicle routing capabilities of OptaPlanner by providing a starter application that answers questions such as these:

  • Where do I get the distances and travel times?
  • How do I visualize the solution on a map?
  • How do I build an application that runs in the cloud?

OptaWeb Vehicle Routing uses OpenStreetMap (OSM) data files. For information about OpenStreetMap, see the OpenStreetMap web site.

Use the following definitions when working with OptaWeb Vehicle Routing:

Region: An arbitrary area on the map of Earth, represented by an OSM file. A region can be a country, a city, a continent, or a group of countries that are frequently used together. For example, the DACH region includes Germany (DE), Austria (AT), and Switzerland (CH).

Country code: A two-letter code assigned to a country by the ISO-3166 standard. You can use a country code to filter geosearch results. Because you can work with a region that spans multiple countries (for example, the DACH region), OptaWeb Vehicle Routing accepts a list of country codes so that geosearch filtering can be used with such regions. For a list of country codes, see ISO 3166 Country Codes

Geosearch: A type of query where you provide an address or a place name of a region as the search keyword and receive a number of GPS locations as a result. The number of locations returned depends on how unique the search keyword is. Because most place names are not unique, filter out nonrelevant results by including only places in the country or countries that are in your working region.

14.2. Download and build the OptaWeb Vehicle Routing deployment files

You must download and prepare the deployment files before building and deploying OptaWeb Vehicle Routing.

Procedure

  1. Navigate to the Software Downloads page in the Red Hat Customer Portal (login required), and select the product and version from the drop-down options:

    • Product: Decision Manager
    • Version: 7.11.0
  2. Download Red Hat Decision Manager 7.11.0 Kogito and OptaPlanner 8 Decision Services Quickstarts (rhdm-7.11.0-decision-services-quickstarts.zip).
  3. Extract the rhdm-7.11.0-decision-services-quickstarts.zip file.
  4. Download the Red Hat Decision Manager 7.11 Maven Repository Kogito and OptaPlanner 8 Maven Repository (rhdm-7.11.0-kogito-maven-repository.zip) file.
  5. Extract the rhdm-7.11.0-kogito-maven-repository.zip file.
  6. Copy the contents of the rhdm-7.11.0-kogito-maven-repository/maven-repository subdirectory into the ~/.m2/repository directory.
  7. Navigate to the optaweb-8.5.0.Final-redhat-00004/optaweb-vehicle-routing directory.
  8. Enter the following command to build OptaWeb Vehicle Routing:

    mvn clean package -DskipTests

14.3. Run OptaWeb Vehicle Routing locally using the runLocally.sh script

Linux users can use the runLocally.sh Bash script to run OptaWeb Vehicle Routing.

Note

The runLocally.sh script does not run on macOS. If you cannot use the runLocally.sh script, see Section 14.4, “Configure and run OptaWeb Vehicle Routing manually”.

The runLocally.sh script automates the following setup steps that otherwise must be carried out manually:

  • Create the data directory.
  • Download selected OpenStreetMap (OSM) files from Geofabrik.
  • Try to associate a country code with each downloaded OSM file automatically.
  • Build the project if the standalone JAR file does not exist.
  • Launch OptaWeb Vehicle Routing by taking a single region argument or by selecting the region interactively.

See the following sections for instructions about executing the runLocally.sh script:

14.3.1. Run the OptaWeb Vehicle Routing runLocally.sh script in quick start mode

The easiest way to get started with OptaWeb Vehicle Routing is to run the runLocally.sh script without any arguments.

Prerequisites

Procedure

  1. Enter the following command in the rhdm-7.11.0-decision-services-quickstarts/optaweb-8.5.0.Final-redhat-00004/optaweb-vehicle-routing directory.

     ./runLocally.sh
  2. If prompted to create the .optaweb-vehicle-routing directory, enter y. You are prompted to create this directory the first time you run the script.
  3. If prompted to download an OSM file, enter y. The first time that you run the script, OptaWeb Vehicle Routing downloads the Belgium OSM file.

    The application starts after the OSM file is downloaded.

  4. To open the OptaWeb Vehicle Routing user interface, enter the following URL in a web browser:

    http://localhost:8080
Note

The first time that you run the script, it will take a few minutes to start because the OSM file must be imported by GraphHopper and stored as a road network graph. The next time you run the runlocally.sh script, load times will be significantly faster.

14.3.2. Run the OptaWeb Vehicle Routing runLocally.sh script in interactive mode

Use interactive mode to see the list of downloaded OSM files and country codes assigned to each region. You can use the interactive mode to download additional OSM files from Geofabrik without visiting the website and choosing a destination for the download.

Prerequisites

Procedure

  1. Change directory to rhdm-7.11.0-decision-services-quickstarts/optaweb-8.5.0.Final-redhat-00004/optaweb-vehicle-routing.
  2. Enter the following command to run the script in interactive mode:

    ./runLocally.sh -i
  3. At the Your choice prompt, enter d to display the download menu. A list of previously downloaded regions appears followed by a list of regions that you can download.
  4. Optional: Select a region from the list of previously downloaded regions:

    1. Enter the number associated with a region in the list of downloaded regions.
    2. Press the Enter key.
  5. Optional: Download a region:

    1. Enter the number associated with the region that you want to download. For example, to select the map of Europe, enter 5.
    2. To download the map, enter d then press the Enter key.
    3. To download a specific region within the map, enter e then enter the number associated with the region that you want to download, and press the Enter key.

      Using large OSM files

      For the best user experience, use smaller regions such as individual European or US states. Using OSM files larger than 1 GB will require significant RAM size and take a lot of time (up to several hours) for the initial processing.

      The application starts after the OSM file is downloaded.

  6. To open the OptaWeb Vehicle Routing user interface, enter the following URL in a web browser:

    http://localhost:8080

14.3.3. Run the OptaWeb Vehicle Routing runLocally.sh script in non-interactive mode

Use OptaWeb Vehicle Routing in non-interactive mode to start OptaWeb Vehicle Routing with a single command that includes an OSM file that you downloaded previously. This is useful when you want to switch between regions quickly or when doing a demo.

Prerequisites

Procedure

  1. Change directory to rhdm-7.11.0-decision-services-quickstarts/optaweb-8.5.0.Final-redhat-00004/optaweb-vehicle-routing.
  2. Execute the following command where <OSM_FILE_NAME> is an OSM file that you downloaded previously:

    ./runLocally.sh <OSM_FILE_NAME>

14.3.4. Update the data directory

You can update the data directory that OptaWeb Vehicle Routing uses if you want to use a different data directory. The default data directory is $HOME/.optaweb-vehicle-routing.

Prerequisites

Procedure

  • To use a different data directory, add the directory’s absolute path to the .DATA_DIR_LAST file in the current data directory.
  • To change country codes associated with a region, edit the corresponding file in the country_codes directory, in the current data directory.

    For example, if you downloaded an OSM file for Scotland and the script fails to guess the country code, set the content of country_codes/scotland-latest to GB.

  • To remove a region, delete the corresponding OSM file from openstreetmap directory in the data directory and delete the region’s directory in the graphhopper directory.

14.4. Configure and run OptaWeb Vehicle Routing manually

The easiest way to run OptaWeb Vehicle Routing is to use the runlocally.sh script. However, if Bash is not available on your system you can manually complete the steps that the runlocally.sh script performs.

Prerequisites

Procedure

  1. Download routing data.

    The routing engine requires geographical data to calculate the time it takes vehicles to travel between locations. You must download and store OpenStreetMap (OSM) data files on the local file system before you run OptaWeb Vehicle Routing.

    Note

    The OSM data files are typically between 100 MB to 1 GB and take time to download so it is a good idea to download the files before building or starting the OptaWeb Vehicle Routing application.

    1. Open http://download.geofabrik.de/ in a web browser.
    2. Click a region in the Sub Region list, for example Europe. The subregion page opens.
    3. In the Sub Regions table, download the OSM file (.osm.pbf) for a country, for example Belgium.
  2. Create the data directory structure.

    OptaWeb Vehicle Routing reads and writes several types of data on the file system. It reads OSM (OpenStreetMap) files from the openstreetmap directory, writes a road network graph to the graphhopper directory, and persists user data in a directory called db. Create a new directory dedicated to storing all of these data to make it easier to upgrade to a newer version of OptaWeb Vehicle Routing in the future and continue working with the data you created previously.

    1. Create the $HOME/.optaweb-vehicle-routing directory.
    2. Create the openstreetmap directory in the $HOME/.optaweb-vehicle-routing directory:

      $HOME/.optaweb-vehicle-routing
      └── openstreetmap
    3. Move all of your downloaded OSM files (files with the extension .osm.pbf) to the openstreetmap directory.

      The rest of the directory structure is created by the OptaWeb Vehicle Routing application when it runs for the first time. After that, your directory structure is similar to the following example:

      $HOME/.optaweb-vehicle-routing
      
      ├── db
      │   └── vrp.mv.db
      ├── graphhopper
      │   └── belgium-latest
      └── openstreetmap
          └── belgium-latest.osm.pbf
  3. Change directory to rhdm-7.11.0-decision-services-quickstarts/optaweb-8.5.0.Final-redhat-00004/optaweb-vehicle-routing/optaweb-vehicle-routing-standalone/target.
  4. To run OptaWeb Vehicle Routing, enter the following command:

    java \
    -Dapp.demo.data-set-dir=$HOME/.optaweb-vehicle-routing/dataset \
    -Dapp.persistence.h2-dir=$HOME/.optaweb-vehicle-routing/db \
    -Dapp.routing.gh-dir=$HOME/.optaweb-vehicle-routing/graphhopper \
    -Dapp.routing.osm-dir=$HOME/.optaweb-vehicle-routing/openstreetmap \
    -Dapp.routing.osm-file=<OSM_FILE_NAME> \
    -Dapp.region.country-codes=<COUNTRY_CODE_LIST> \
    -jar quarkus-app/quarkus-run.jar

    In this command, replace the following variables:

    • <OSM_FILE_NAME>: The OSM file for the region that you want to use and that you downloaded previously
    • <COUNTRY_CODE_LIST>: A comma-separated list of country codes used to filter geosearch queries. For a list of country codes, see ISO 3166 Country Codes.

      The application starts after the OSM file is downloaded.

      In the following example, OptaWeb Vehicle Routing downloads the OSM map of Central America (central-america-latest.osm.pbf) and searches in the countries Belize (BZ) and Guatemala (GT).

      java \
      -Dapp.demo.data-set-dir=$HOME/.optaweb-vehicle-routing/dataset \
      -Dapp.persistence.h2-dir=$HOME/.optaweb-vehicle-routing/db \
      -Dapp.routing.gh-dir=$HOME/.optaweb-vehicle-routing/graphhopper \
      -Dapp.routing.osm-dir=$HOME/.optaweb-vehicle-routing/openstreetmap \
      -Dapp.routing.osm-file=entral-america-latest.osm.pbf \
      -Dapp.region.country-codes=BZ,GT \
      -jar quarkus-app/quarkus-run.jar
  5. To open the OptaWeb Vehicle Routing user interface, enter the following URL in a web browser:

    http://localhost:8080

14.5. Run OptaWeb Vehicle Routing on Red Hat OpenShift Container Platform

Linux users can use the runOnOpenShift.sh Bash script to install OptaWeb Vehicle Routing on Red Hat OpenShift Container Platform.

Note

The runOnOpenShift.sh script does not run on macOS.

Prerequisites

Procedure

  1. Log in to or start a Red Hat OpenShift Container Platform cluster.
  1. Enter the following command where <PROJECT_NAME> is the name of your new project:

    oc new-project <PROJECT_NAME>
  2. If necessary, change directory to rhdm-7.11.0-decision-services-quickstarts/optaweb-8.5.0.Final-redhat-00004/optaweb-vehicle-routing.
  3. Enter the following command to execute the runOnOpenShift.sh script and download an OpenStreetMap (OSM) file:

    ./runOnOpenShift.sh <OSM_FILE_NAME> <COUNTRY_CODE_LIST> <OSM_FILE_DOWNLOAD_URL>

    In this command, replace the following variables:

    • <OSM_FILE_NAME>: The name of a file downloaded from <OSM_FILE_DOWNLOAD_URL>.
    • <COUNTRY_CODE_LIST>: A comma-separated list of country codes used to filter geosearch queries. For a list of country codes, see ISO 3166 Country Codes.
    • <OSM_FILE_DOWNLOAD_URL>: The URL of an OSM data file in PBF format accessible from OpenShift. The file will be downloaded during backend startup and saved as /deployments/local/<OSM_FILE_NAME>.

      In the following example, OptaWeb Vehicle Routing downloads the OSM map of Central America (central-america-latest.osm.pbf) and searches in the countries Belize (BZ) and Guatemala (GT).

      ./runOnOpenShift.sh central-america-latest.osm.pbf BZ,GT http://download.geofabrik.de/europe/central-america-latest.osm.pbf
Note

For help with the runOnOpenShift.sh script, enter ./runOnOpenShift.sh --help.

14.5.1. Updating the deployed OptaWeb Vehicle Routing application with local changes

After you deploy your OptaWeb Vehicle Routing application on Red Hat OpenShift Container Platform, you can update the back end and front end.

Prerequisites

  • OptaWeb Vehicle Routing has been successfully built with Maven and deployed on OpenShift.

Procedure

  • To update the back end, perform the following steps:

    1. Change the source code and build the back-end module with Maven.
    2. Change directory to rhdm-7.11.0-decision-services-quickstarts/optaweb-8.5.0.Final-redhat-00004/optaweb-vehicle-routing.
    3. Enter the following command to start the OpenShift build:

      oc start-build backend --from-dir=. --follow
  • To update the front end, perform the following steps:

    1. Change the source code and build the front-end module with the npm utility.
    2. Change directory to sources/optaweb-vehicle-routing-frontend.
    3. Enter the following command to start the OpenShift build:

      oc start-build frontend --from-dir=docker --follow

14.6. Using OptaWeb Vehicle Routing

In the OptaWeb Vehicle Routing application, you can mark a number of locations on the map. The first location is assumed to be the depot. Vehicles must deliver goods from this depot to every other location that you marked.

You can set the number of vehicles and the carrying capacity of every vehicle. However, the route is not guaranteed to use all vehicles. The application uses as many vehicles as required for an optimal route.

The current version has certain limitations:

  • Every delivery to a location is supposed to take one point of vehicle capacity. For example, a vehicle with a capacity of 10 can visit up to 10 locations before returning to the depot.
  • Setting custom names of vehicles and locations is not supported.

14.6.1. Creating a route

To create an optimal route, use the Demo tab of the OptaWeb Vehicle Routing user interface.

Prerequisites

  • OptaWeb Vehicle Routing is running and you have access to the user interface.

Procedure

  1. In OptaWeb Vehicle Routing, click Demo to open the Demo tab.
  2. Use the blue minus and plus buttons above the map to set the number of vehicles. Each vehicle has a default capacity of 10.
  3. Use the plus button in a square on the map to zoom in as required.

    Note

    Do not double-click to zoom in. A double click also creates a location.

  4. Click a location for the depot.
  5. Click other locations on the map for delivery points.
  6. If you want to delete a location:

    1. Hover the mouse cursor over the location to see the location name.
    2. Find the location name in the list in the left part of the screen.
    3. Click the X icon next to the name.

Every time you add or remove a location or change the number of vehicles, the application creates and displays a new optimal route. If the solution uses several vehicles, the application shows the route for every vehicle in a different color.

14.6.2. Viewing and setting other details

You can use other tabs in the OptaWeb Vehicle Routing user interface to view and set additional details.

Prerequisites

  • OptaWeb Vehicle Routing is running and you have access to the user interface.

Procedure

  • Click the Vehicles tab to view, add, and remove vehicles, and also set the capacity for every vehicle.
  • Click the Visits tab to view and remove locations.
  • Click the Route tab to select each vehicle and view the route for the selected vehicle.

14.6.3. Creating custom data sets with OptaWeb Vehicle Routing

There is a built-in demo data set consisting of a several large Belgian cities. If you want to have more demos available in the Load demo menu, you can prepare your own data sets.

Procedure

  1. In OptaWeb Vehicle Routing, add a depot and one or more of visits by clicking on the map or using geosearch.
  2. Click Export and save the file in the data set directory.

    Note

    The data set directory is the directory specified in the app.demo.data-set-dir property.

    If the application is running through the runLocally.sh script, the data set directory is set to $HOME/.optaweb-vehicle-routing/dataset.

    Otherwise, the property is taken from the application.properties file and defaults to rhdm-7.11.0-decision-services-quickstarts/optaweb-8.5.0.Final-redhat-00004/optaweb-vehicle-routing/optaweb-vehicle-routing-standalone/target/local/dataset.

    You can edit the app.demo.data-set-dir property to specify a diffent data directory.

  3. Edit the YAML file and choose a unique name for the data set.
  4. Restart the back end.

After you restart the back end, files in the data set directory appear in the Load demo menu.

14.6.4. Troubleshooting OptaWeb Vehicle Routing

If the OptaWeb Vehicle Routing behaves unexpectedly, follow this procedure to trouble-shoot.

Prerequisites

  • OptaWeb Vehicle Routing is running and behaving unexpectedly.

Procedure

  1. To identify issues, review the back-end terminal output log.
  2. To resolve issues, remove the back-end database:

    1. Stop the back end by pressing Ctrl+C in the back-end terminal window.
    2. Remove the optaweb-vehicle-routing/optaweb-vehicle-routing-backend/local/db directory.
    3. Restart OptaWeb Vehicle Routing.

14.7. OptaWeb Vehicle Routing development guide

This section describes how to configure and run the back-end and front-end modules in development mode.

14.7.1. OptaWeb Vehicle Routing project structure

The OptaWeb Vehicle Routing project is a multi-module Maven project.

Figure 14.1. Module dependency tree diagram

The back-end and front-end modules are at the bottom of the module tree. These modules contain the application source code.

The standalone module is an assembly module that combines the back end and front end into a single executable JAR file.

The distribution module represents the final assembly step. It takes the standalone application and the documentation and wraps them in an archive that is easy to distribute.

The back end and front end are separate projects that you can build and deploy separately. In fact, they are written in completely different languages and built with different tools. Both projects have tools that provide a modern developer experience with fast turn-around between code changes and the running application.

The next sections describe how to run both back-end and front-end projects in development mode.

14.7.2. The OptaWeb Vehicle Routing back-end module

The back-end module contains a server-side application that uses Red Hat build of OptaPlanner to optimize vehicle routes. Optimization is a CPU-intensive computation that must avoid any I/O operations in order to perform to its full potential. Because one of the chief objectives is to minimize travel cost, either time or distance, OptaWeb Vehicle Routing keeps the travel cost information in RAM memory. While solving, OptaPlanner needs to know the travel cost between every pair of locations entered by the user. This information is stored in a structure called the distance matrix.

When you enter a new location, OptaWeb Vehicle Routing calculates the travel cost between the new location and every other location that has been entered so far, and stores the travel cost in the distance matrix. The travel cost calculation is performed by the GraphHopper routing engine.

The back-end module implements the following additional functionality:

  • Persistence
  • WebSocket connection for the front end
  • Data set loading, export, and import

To learn more about the back-end code architecture, see Section 14.8, “OptaWeb Vehicle Routing back-end architecture”.

The next sections describe how to configure and run the back end in development mode.

14.7.2.1. Running the OptaWeb Vehicle Routing back-end module

You can run the back-end module in Quarkus development mode.

Prerequisites

Procedure

  1. Change directory to rhdm-7.11.0-decision-services-quickstarts/optaweb-8.5.0.Final-redhat-00004/optaweb-vehicle-routing/optaweb-vehicle-routing-backend.
  2. To run the back end in development mode, enter the following command:

    mvn compile quarkus:dev

14.7.2.2. Running the OptaWeb Vehicle Routing back-end module from IntelliJ IDEA Ultimate

You can use IntelliJ IDEA Ulitmate to run the OptaWeb Vehicle Routing back-end module to make it easier to develop your project. IntelliJ IDEA Ultimate includes a Quarkus plug-in that automatically creates run configurations for modules that use the Quarkus framework.

Procedure

Use the optaweb-vehicle-routing-backend run configuration to run the back end.

Additional resources

For more information, see Run the Quarkus application.

14.7.2.3. Quarkus development mode

In development mode, if there are changes to the back-end source code or configuration and you refresh the browser tab where the front end runs, the back-end automatically restarts.

Learn more about Quarkus development mode.

14.7.2.4. Changing OptaWeb Vehicle Routing back-end module system property values

You can temporarily or permanently override the default system property values of the OptaWeb Vehicle Routing back-end module.

The OptaWeb Vehicle Routing back-end module system properties are stored in the /src/main/resources/application.properties file. This file is under version control. Use it to permanently store default configuration property values and to define Quarkus profiles.

Prerequisites

Procedure

  • To temporarily override a default system property value, include the -D<PROPERTY>=<VALUE> argument when you run the mvn or java command, where <PROPERTY> is the name of the property that you want to change and <VALUE> is the value that you want to temporarily assign to that property. The following example shows how to temporarily change the value of the quarkus.http.port system property to 8181 when you use Maven to compile a Quarkus project in dev mode:

    mvn compile quarkus:dev -Dquarkus.http.port=8181

    This temporarily changes the value of the property stored in the /src/main/resources/application.properties file.

  • To change a configuration value permanently, for example to store a configuration that is specific to your development environment, copy the contents of the env-example file to the optaweb-vehicle-routing-backend/.env file.

    This file is excluded from version control and therefore it does not exist when you clone the repository. You can make changes in the .env file without affecting the Git working tree.

Additional resources

For a complete list of OptaWeb Vehicle Routing configuration properties, see Section 14.9, “OptaWeb Vehicle Routing back-end configuration properties”.

14.7.2.5. OptaWeb Vehicle Routing backend logging

OptaWeb Vehicle Routing uses the SLF4J API and Logback as the logging framework. For more information, see Quarkus - Configuring Logging.

14.7.3. Working with the OptaWeb Vehicle Routing front-end module

The front-end project was bootstrapped with Create React App. Create React App provides a number of scripts and dependencies that help with development and with building the application for production.

Prerequisites

Procedure

  1. On Fedora, enter the following command to set up the development environment:

    sudo dnf install npm

    See Downloading and installing Node.js and npm for more information about installing npm.

  2. Change directory to rhdm-7.11.0-decision-services-quickstarts/optaweb-8.5.0.Final-redhat-00004/optaweb-vehicle-routing/optaweb-vehicle-routing-frontend.
  3. Install npm dependencies:

    npm install

    Unlike Maven, the npm package manager installs dependencies in node_modules under the project directory and does that only when you execute npm install. Whenever the dependencies listed in package.json change, for example when you pull changes to the master branch, you must execute npm install before you run the development server.

  4. Enter the following command to run the development server:

    npm start
  5. If it does not open automatically, open http://localhost:3000/ in a web browser.

    By default, the npm start command attempts to open this URL in your default browser.

    Note

    If you do not want the npm start command to open a new browser tab each time you run it, export the BROWSER=none environment variable. You can use .env.local file to make this preference permanent. To do that, enter the following command:

    echo BROWSER=none >> .env.local

    The browser refreshes the page whenever you make changes in the front-end source code. The development server process running in the terminal picks up the changes as well and prints compilation and lint errors to the console.

  6. Enter the following command to run tests:

    npm test
  7. Change the value of the REACT_APP_BACKEND_URL environment variable to specify the location of the back-end project to be used by npm when you execute npm start or npm run build, for example:

    REACT_APP_BACKEND_URL=http://10.0.0.123:8081
    Note

    Environment variables are hard coded inside the JavaScript bundle during the npm build process, so you must specify the back-end location before you build and deploy the front end.

    To learn more about the React environment variables, see Adding Custom Environment Variables.

  8. To build the front end, enter one of the following commands:

    ./mvnw install
    mvn install

14.8. OptaWeb Vehicle Routing back-end architecture

Domain model and use cases are essential for the application. The OptaWeb Vehicle Routing domain model is at the center of the architecture and is surround by the application layer that embeds use cases. Functions such as route optimization, distance calculation, persistence, and network communication are considered implementation details and are placed at the outermost layer of the architecture.

Figure 14.2. Diagram of application layers

14.8.1. Code organization

The back-end code is organized in three layers, illustrated in the preceding graphic.

org.optaweb.vehiclerouting
├── domain
├── plugin          # Infrastructure layer
│   ├── persistence
│   ├── planner
│   ├── routing
│   └── rest
└── service         # Application layer
    ├── demo
    ├── distance
    ├── error
    ├── location
    ├── region
    ├── reload
    ├── route
    └── vehicle

The service package contains the application layer that implements use cases. The plugin package contains the infrastructure layer.

Code in each layer is further organized by function. This means that each service or plug-in has its own package.

14.8.2. Dependency rules

Compile-time dependencies are only allowed to point from outer layers towards the center. Following this rule helps to keep the domain model independent of underlying frameworks and other implementation details and models the behavior of business entities more precisely. With presentation and persistence being pushed out to the periphery, it is easier to test the behavior of business entities and use cases.

The domain has no dependencies.

Services only depend on the domain. If a service needs to send a result (for example to the database or to the client), it uses an output boundary interface. Its implementation is injected by the contexts and dependency injection (CDI) container.

Plug-ins depend on services in two ways. First, they invoke services based on events such as a user input or a route update coming from the optimization engine. Services are injected into plug-ins which moves the burden of their construction and dependency resolution to the IoC container. Second, plug-ins implement service output boundary interfaces to handle use case results, for example persisting changes to the database or sending a response to the web UI.

14.8.3. The domain package

The domain package contains business objects that model the domain of this project, for example Location, Vehicle, Route. These objects are strictly business-oriented and must not be influenced by any tools and frameworks, for example object-relational mapping tools and web service frameworks.

14.8.4. The service package

The service package contains classes that implement use cases. A use case describes something that you want to do, for example adding a new location, changing vehicle capacity, or finding coordinates for an address. The business rules that govern use cases are expressed using the domain objects.

Services often need to interact with plug-ins in the outer layer, such as persistence, web, and optimization. To satisfy the dependency rules between layers, the interaction between services and plug-ins is expressed in terms of interfaces that define the dependencies of a service. A plug-in can satisfy a dependency of a service by providing a bean that implements the boundary interface of the service. The CDI container creates an instance of the plug-in bean and injects it to the service at runtime. This is an example of the inversion of control principle.

14.8.5. The plugin package

The plugin package contains infrastructure functions such as optimization, persistence, routing, and network.

14.9. OptaWeb Vehicle Routing back-end configuration properties

You can set the OptaWeb Vehicle Routing application properties listed in the following table.

PropertyTypeExampleDescription

app.demo.data-set-dir

Relative or absolute path

/home/user/.optaweb-vehicle-routing/dataset

Custom data sets are loaded from this directory. Defaults to local/dataset.

app.persistence.h2-dir

Relative or absolute path

/home/user/.optaweb-vehicle-routing/db

The directory used by H2 to store the database file. Defaults to local/db.

app.region.country-codes

List of ISO 3166-1 alpha-2 country codes

US, GB,IE, DE,AT,CH, may be empty

Restricts geosearch results.

app.routing.engine

Enumeration

air, graphhopper

Routing engine implementation. Defaults to graphhopper.

app.routing.gh-dir

Relative or absolute path

/home/user/.optaweb-vehicle-routing/graphhopper

The directory used by GraphHopper to store road network graphs. Defaults to local/graphhopper.

app.routing.osm-dir

Relative or absolute path

/home/user/.optaweb-vehicle-routing/openstreetmap

The directory that contains OSM files. Defaults to local/openstreetmap.

app.routing.osm-file

File name

belgium-latest.osm.pbf

Name of the OSM file to be loaded by GraphHopper. The file must be placed under app.routing.osm-dir.

optaplanner.solver.termination.spent-limit

java.time.Duration

  • 1m
  • 150s
  • P2dT21h (PnDTnHnMn.nS)

How long the solver should run after a location change occurs.

server.address

IP address or hostname

10.0.0.123, my-vrp.geo-1.openshiftapps.com

Network address to which to bind the server.

server.port

Port number

4000, 8081

Server HTTP port.