OptaPlanner logo
  • Download
  • Learn
    • Documentation
    • Videos
    • Slides
    • Training

    • Use cases
    • Compatibility
    • Testimonials and case studies
  • Get help
  • Blog
  • Source
  • Team
  • Services
  • KIE
    • Drools
    • OptaPlanner
    • jBPM
    • Kogito
  • Star
  • T
  • L
  • F
  • YT
Fork me on GitHub

KIE Server OptaPlanner Task Assignment

Wed 13 March 2019
Avatar Musa Talluzi
Musa Talluzi

Twitter GitHub

OptaPlanner developer

KIE Server is a standalone server component that can be used to instantiate and execute rules and processes. In this blog, you will learn how to build an OptaPlanner service that implements continuous and real-time planning to solve the Task Assignment problem and deploy it to the KIE Server.

Task Assignment KJAR

KJAR or “Knowledge JAR” is a standard JAR file that has some extra files included (at least a META-INF/kmodule.xml file). You will build Task Assignment Service as a KJAR.

Note
In order to build the KJAR, the project’s pom.xml needs to have a <packaging>kjar</packaging> entry and contains kie-maven-plugin.

Problem Description

Assign each task to a spot in an employee’s queue. Each task has a duration which is affected by the employee’s affinity level with the task’s customer.

Constraints:

  • [Hard] Skill: Each task requires one or more skill. The employee must possess all these skills.

  • [Soft 0] Critical tasks: Complete critical tasks first, sooner than major and minor tasks.

  • [Soft 1] Minimize makespan: Reduce the time to complete all tasks.

  • [Soft 2] Major tasks: Complete major tasks as soon as possible, sooner than minor tasks.

  • [Soft 3] Minor tasks: Complete minor tasks as soon as possible.

Domain Model

taskAssigningClassDiagram

Read more on how to model a planning problem.

Real-time Planning

As new tasks come in and others start being implemented, the optimal solution might change. OptaPlanner handles such scenarios using ProblemFactChange.

For example, if an employee starts working on a task, tell OptaPlanner to pin this task by sending a PinTaskProblemFactChange. Each ProblemFactChange type is implemented as a class that implements the interface ProblemFactChange<Solution_>. In the Task Assignment example, this class can be something like:

public class PinTaskProblemFactChange implements ProblemFactChange<TaskAssigningSolution> {
    ...

    @Override
    public void doChange(ScoreDirector<TaskAssigningSolution> scoreDirector) {
        ...
        scoreDirector.beforeProblemPropertyChanged(toBePinnedTask);
        toBePinnedTask.setPinned(true);
        scoreDirector.afterProblemPropertyChanged(toBePinnedTask);
        ...

        scoreDirector.triggerVariableListeners();
    }
}

The full class can be found on GitHub.

Solver Configuration

The solver configuration file determines how the solving process works. For a KJAR deployed to a KIE Server and since we are using Drools for score calculation, use a ksessionName. This tells the KieContainer where to find the DRL file. Add an optataskKsession to META-INF/kmodule.xml file:

<kbase name="optataskKBase" packages="PATH_TO_SOLVER_RESOURCES">
    <ksession name="optataskKsession"/>
</kbase>

And to solver config file:

<scoreDirectorFactory>
    <ksessionName>optataskKsession</ksessionName>
</scoreDirectorFactory>

Notice that both solver configuration and DRL files need to be in the resources folder under the path PATH_TO_SOLVER_RESOURCES.

For real-time planning, set the solver in daemon mode in order to resume solving once a problem fact change is added. This is accomplished by adding the following to the solver config file:

<daemon>true</daemon>

Persistence

Since you will be sending and receiving data to/from KIE Server through REST API, you need to tell it how to marshall/unmarshall this data. Read how OptaPlanner marshals a score using Xstream.

OptaPlanner stores all planning entities as objects and references to these objects, which might result in a lot of redundant data received from the server. In our example, we are using @JsonIdentityInfo to avoid such redundancies.

Dependencies

The minimum required dependencies to build the OptaPlanner service are: optaplanner-core, optaplanner-persistence-xstream.

Note
Because you will be using several OptaPlanner modules, it’s recommended to import the optaplanner-bom in Maven’s dependencyManagement so that OptaPlanner version is specified only once.

Build and Deployment

Now that you have the KJAR ready, you can deploy it to the KIE Server and perform all planning operations. You can send HTTP requests to the server using REST API.

Deployment

POST /config

Through the above endpoint, you can execute various commands on the KIE Server.

For example, to create a container running your OptaPlanner service, the request’s body should be:

{
  commands: [
    {
      'create-container': {
        'container': {
          'container-id': CONTAINER_ID,
          'release-id': {
            'group-id': GROUP_ID,
            'artifact-id': ARTIFACT_ID,
            'version': VERSION,
          },
        },
      },
    },
  ],
}

Notice that the GAV in the release-id object are your KJAR’s GAV.

Solver registration

PUT /containers/{CONTAINER_ID}/solvers/{SOLVER_ID}

With body:

{
  'solver-config-file': 'PATH_TO_SOLVER_CONFIG_FILE.xml'
}

This will build a new solver from the xml resource included in the KJAR.

Submit a problem

POST /containers/{CONTAINER_ID}/solvers/{SOLVER_ID}/state/solving

Once a solver is built it will be waiting for a problem to start solving. The body of this request contains the object annotated as @PlanningSolution, in the Task Assignment example it will be TaskAssigningSolution.

Query bestSolution

GET /containers/{CONTAINER_ID}/solvers/{SOLVER_ID}/bestsolution

This response body will contain best-solution object in addition to extra information about the solver status and score.

Submit a ProblemFactChange

POST /containers/{CONTAINER_ID}/solvers/{SOLVER_ID}/problemfactchanges

Submits a ProblemFactChange to update the problem the solver is solving. For example if you want to delete a task the body should be:

<problem-fact-change class="TaDeleteTaskProblemFactChange">
    <taskId>TO_BE_DELETED_TASK_ID</taskId>
</problem-fact-change>

Notice the use of class attribute, this is how you tell OptaPlanner service what type of ProblemFactChange you are submitting. Here TaDeleteTaskProblemFactChange is an @XStreamAlias for the DeleteTaskProblemFactChange.

Note
All the requests above have a base URL http://SERVER:PORT/CONTEXT/services/rest/server and require basic HTTP Authentication for the role kie-server.

Check all the available endpoints in the docs.

Conclusion

To integrate an OptaPlanner service with your application on KIE Server:

  1. Build the service as a KJAR.

  2. Send an HTTP request to the KIE Server to start a container that runs this service.

  3. Communicate with the service through the REST API the KIE Server exposes.

Related material

KIE Server OptaPlanner Task Assignment demo

KIE Server and KIE container commands in OptaPlanner

OptaPlanner REST API


Permalink
 tagged as use case task assignment execution server

Comments

Visit our forum to comment

Giscus Comments

AtomNews feed
Don’t want to miss a single blog post?
Follow us on
  • T
  • L
  • F
Blog archive
Latest release
  • 8.14.0.Final released
    Wed 8 December 2021
Upcoming events
  • DevConf.CZ
    Brno, Czech Republic (virtual) - Fri 28 January 2022
    • Artificial Intelligence on Quarkus: I love it when an OptaPlan comes together by Geoffrey De Smet
  • JFokus
    Stockholm, Sweden - Mon 7 February 2022
    • AI maintenance scheduling with OptaPlanner on Quarkus by Geoffrey De Smet
  • Add event / Archive
Latest blog posts
  • OptaPlanner documentation turns over a new leaf
    Tue 26 October 2021
    Radovan Synek
  • Order picking optimization in warehouses and supermarkets with OptaPlanner
    Thu 14 October 2021
    Walter Medvedeo
  • Monitor OptaPlanner solvers through Micrometer
    Tue 12 October 2021
    Christopher Chianelli
  • A new AI constraint solver for Python: OptaPy
    Tue 5 October 2021
    Christopher Chianelli
  • How much faster is Java 17?
    Wed 15 September 2021
    Geoffrey De Smet
  • Constraint Streams get some more love
    Thu 19 August 2021
    Lukáš Petrovický
  • Let’s OptaPlan your jBPM tasks (part 2) - BPM Task assigning in the cloud
    Mon 26 July 2021
    Walter Medvedeo
  • Blog archive
Latest videos
  • AI lesson scheduling on Quarkus with OptaPlanner
    Thu 18 November 2021
    Geoffrey De Smet
  • Maintenance scheduling
    Fri 12 November 2021
    Geoffrey De Smet
  • Optimized order picking in warehouses and supermarkets
    Tue 26 October 2021
    Walter Medvedeo
  • A modern OO/FP constraint solver
    Tue 14 September 2021
    Geoffrey De Smet
  • Business processes task optimization in Kogito
    Tue 7 September 2021
    Walter Medvedeo
  • School timetable optimization
    Mon 6 September 2021
    Geoffrey De Smet
  • Schedule incoming calls real-time
    Mon 23 August 2021
    Radovan Synek
  • Video archive

OptaPlanner is open. All dependencies of this project are available under the Apache Software License 2.0 or a compatible license. OptaPlanner is trademarked.

This website was built with JBake and is open source.

Community

  • Blog
  • Get Help
  • Team
  • Governance
  • Academic research

Code

  • Build from source
  • Issue tracker
  • Release notes
  • Upgrade recipes
  • Logo and branding

KIE projects

  • Drools rule engine
  • OptaPlanner constraint solver
  • jBPM workflow engine
  • Kogito Business Automation platform
CC by 3.0 | Privacy Policy
Sponsored by Red Hat