Uploaded image for project: 'OptaPlanner'
  1. OptaPlanner
  2. PLANNER-1440

Review JSON requests and responses from Employee Rostering solution

    XMLWordPrintable

Details

    • Task
    • Resolution: Won't Do
    • Minor
    • None
    • None
    • optaplanner-wb
    • None
    • 5
    • NEW
    • NEW

    Description

      Current example request to POST /server/containers/{containerId}/solvers/{solverId}/state/solving:

      {
        "employeerostering.employeerostering.EmployeeRoster": {
          "employeeList": [
            {
              "name": "John",
              "skills": {
                "employeerostering.employeerostering.Skill": {
                  "name": "reading"
                }
              }
            },
            {
              "name": "Mary",
              "skills": {
                "employeerostering.employeerostering.Skill": {
                  "name": "writing"
                }
              }
            },
            {
              "name": "Petr",
              "skills": {
                "employeerostering.employeerostering.Skill": {
                  "name": "speaking"
                }
              }
            }
          ],
          "shiftList": [
            {
              "timeslot": {
                "startTime": "2017-01-01T00:00:00",
                "endTime": "2017-01-01T01:00:00"
              },
              "requiredSkill": {
                "-reference": "../../../employeeList/employeerostering.employeerostering.Employee/skills/employeerostering.employeerostering.Skill"
              }
            },
            {
              "timeslot": {
                "-reference": "../../employeerostering.employeerostering.Shift/timeslot"
              },
              "requiredSkill": {
                "-reference": "../../../employeeList/employeerostering.employeerostering.Employee[3]/skills/employeerostering.employeerostering.Skill"
              }
            },
            {
              "timeslot": {
                "-reference": "../../employeerostering.employeerostering.Shift/timeslot"
              },
              "requiredSkill": {
                "-reference": "../../../employeeList/employeerostering.employeerostering.Employee[2]/skills/employeerostering.employeerostering.Skill"
              }
            }
          ],
          "skillList": [
            {
              "-reference": "../../employeeList/employeerostering.employeerostering.Employee/skills/employeerostering.employeerostering.Skill"
            },
            {
              "-reference": "../../employeeList/employeerostering.employeerostering.Employee[3]/skills/employeerostering.employeerostering.Skill"
            },
            {
              "-reference": "../../employeeList/employeerostering.employeerostering.Employee[2]/skills/employeerostering.employeerostering.Skill"
            }
          ],
          "timeslotList": {
            "employeerostering.employeerostering.Timeslot": {
              "-reference": "../../shiftList/employeerostering.employeerostering.Shift/timeslot"
            }
          },
          "shiftAssignmentList": [],
          "dayOffRequestList": [
            {
              "employee": {
                "-reference": "../../../employeeList/employeerostering.employeerostering.Employee"
              },
              "date": "2017-01-01"
            }
          ]
        }
      }
      

      but when I request best solution, I get:

      {
        "container-id" : "employeerostering_1.0.0-SNAPSHOT",
        "solver-id" : "solver-json",
        "solver-config-file" : "employeerostering/employeerostering/EmployeeRosteringSolverConfig.solver.xml",
        "status" : "NOT_SOLVING",
        "score" : {
          "value" : "0hard/0soft",
          "scoreClass" : "org.optaplanner.core.api.score.buildin.hardsoft.HardSoftScore"
        },
        "best-solution" : {"employeerostering.employeerostering.EmployeeRoster":{
        "employeeList" : [ {
          "name" : "John",
          "skills" : [ {
            "name" : "reading"
          } ]
        }, {
          "name" : "Mary",
          "skills" : [ {
            "name" : "writing"
          } ]
        }, {
          "name" : "Petr",
          "skills" : [ {
            "name" : "speaking"
          } ]
        } ],
        "shiftList" : [ {
          "timeslot" : {
            "startTime" : [ 2017, 1, 1, 0, 0 ],
            "endTime" : [ 2017, 1, 1, 1, 0 ]
          },
          "requiredSkill" : {
            "name" : null
          }
        }, {
          "timeslot" : {
            "startTime" : null,
            "endTime" : null
          },
          "requiredSkill" : {
            "name" : null
          }
        }, {
          "timeslot" : {
            "startTime" : null,
            "endTime" : null
          },
          "requiredSkill" : {
            "name" : null
          }
        } ],
        "skillList" : [ {
          "name" : null
        }, {
          "name" : null
        }, {
          "name" : null
        } ],
        "timeslotList" : [ {
          "startTime" : null,
          "endTime" : null
        } ],
        "dayOffRequestList" : [ {
          "employee" : {
            "name" : null,
            "skills" : null
          },
          "date" : [ 2017, 1, 1 ]
        } ],
        "shiftAssignmentList" : [ ],
        "score" : "0hard/0soft"
      }}
      }
      

      with lot of null, so the references don't work.

      If I submit a solution in XML and retrieve it in JSON there are no references. All objects are serialized fully. That may work for simple objects like skills (just a string) but for example a dayOffRequest needs to reference an existing object from employeeList.

      TODO: Recreate the employee rostering problem that is used in documentation and looks like this:

          <employeerostering.employeerostering.EmployeeRoster>
            <employeeList>
              <employeerostering.employeerostering.Employee>
                <name>John</name>
                <skills>
                  <employeerostering.employeerostering.Skill>
                    <name>reading</name>
                  </employeerostering.employeerostering.Skill>
                </skills>
              </employeerostering.employeerostering.Employee>
              <employeerostering.employeerostering.Employee>
                <name>Mary</name>
                <skills>
                  <employeerostering.employeerostering.Skill>
                    <name>writing</name>
                  </employeerostering.employeerostering.Skill>
                </skills>
              </employeerostering.employeerostering.Employee>
              <employeerostering.employeerostering.Employee>
                <name>Petr</name>
                <skills>
                  <employeerostering.employeerostering.Skill>
                    <name>speaking</name>
                  </employeerostering.employeerostering.Skill>
                </skills>
              </employeerostering.employeerostering.Employee>
            </employeeList>
            <shiftList>
              <employeerostering.employeerostering.Shift>
                <timeslot>
                  <startTime>2017-01-01T00:00:00</startTime>
                  <endTime>2017-01-01T01:00:00</endTime>
                </timeslot>
                <requiredSkill reference="../../../employeeList/employeerostering.employeerostering.Employee/skills/employeerostering.employeerostering.Skill"/>
              </employeerostering.employeerostering.Shift>
              <employeerostering.employeerostering.Shift>
                <timeslot reference="../../employeerostering.employeerostering.Shift/timeslot"/>
                <requiredSkill reference="../../../employeeList/employeerostering.employeerostering.Employee[3]/skills/employeerostering.employeerostering.Skill"/>
              </employeerostering.employeerostering.Shift>
              <employeerostering.employeerostering.Shift>
                <timeslot reference="../../employeerostering.employeerostering.Shift/timeslot"/>
                <requiredSkill reference="../../../employeeList/employeerostering.employeerostering.Employee[2]/skills/employeerostering.employeerostering.Skill"/>
              </employeerostering.employeerostering.Shift>
            </shiftList>
            <skillList>
              <employeerostering.employeerostering.Skill reference="../../employeeList/employeerostering.employeerostering.Employee/skills/employeerostering.employeerostering.Skill"/>
              <employeerostering.employeerostering.Skill reference="../../employeeList/employeerostering.employeerostering.Employee[3]/skills/employeerostering.employeerostering.Skill"/>
              <employeerostering.employeerostering.Skill reference="../../employeeList/employeerostering.employeerostering.Employee[2]/skills/employeerostering.employeerostering.Skill"/>
            </skillList>
            <timeslotList>
              <employeerostering.employeerostering.Timeslot reference="../../shiftList/employeerostering.employeerostering.Shift/timeslot"/>
            </timeslotList>
            <dayOffRequestList/>
            <shiftAssignmentList/>
          </employeerostering.employeerostering.EmployeeRoster>
      

      Add a dayOffRequest and serialize the problem into JSON using Jackson. Make sure references work, it can be sent to server and best solution returns expected solution.

      May require the use of @JsonIdentityInfo. See https://www.baeldung.com/jackson-annotations, https://www.baeldung.com/jackson-bidirectional-relationships-and-infinite-recursion.

      Attachments

        Activity

          People

            jlocker Jiří Locker
            jlocker Jiří Locker
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: