This documentation supports the 21.3 version of BMC Helix Innovation Studio.To view an earlier version, select the version from the Product version menu.

Creating a Java program to use auto assignment


Developers can implement the auto-assignment capability in applications that use the BMC Helix Cognitive Automation.

To implement auto-assignment capability that uses the BMC Helix Cognitive Automation in your application, you must create a Java program that acts as an interface to work with the Suggest Assignee element in your application process. The Java program implements an assignment calculator class and methods to provide information to the assignment process. You can implement methods that provide the information, such as the assignee availability, workload, effort, and last assign time. The assignment process requires this information to assign the appropriate assignee for a task.

The assignment process returns an assignee login ID that belongs to the Agent in the Foundation library. BMC Helix Innovation Studio provides a default assignment calculator implementation (AgentAssignmentCalculator) to check the availability of agents. You can extend the AgentAssignmentCalculator code to add custom logic. For example, you can extend the code to include logic to check an agent's PTO requests. 

Auto-assignment steps

The following image describes the runtime assignment steps when the Suggest Assignee element in a process is triggered:

Auto assignment flow.png 

Important

You must implement methods to sort the agents by the assignment type, such as Round Robin, Load Balanced By Number, Load Balanced By Capacity, and By Skill Level.

To create a Java program to use auto-assignment

  1. In your application bundle project pom.xml file, add the dependencies of the Assignment library and the Foundation library.

    For example:

      <dependency>
               <groupId>${rx-sdk.groupId}</groupId>
               <artifactId>com.bmc.arsys.rx.assignment</artifactId>
               <version>${rx-sdk.version}</version>
               <scope>provided</scope>
           </dependency>

           <dependency>
               <groupId>${rx-sdk.groupId}</groupId>
               <artifactId>com.bmc.arsys.rx.foundation</artifactId>
               <version>${rx-sdk.version}</version>
               <scope>provided</scope>
           </dependency>

     

  2. Create a Java class that extends the AgentAssignmentCalculator class.
    For example:

    package com.example.bundle;

    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.Calendar;
    import java.util.Collections;
    import java.util.Date;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    import java.util.Random;
    import java.util.concurrent.ThreadLocalRandom;
    import com.bmc.arsys.rx.assignment.business.domain.AgentAssignmentCalculator;
    import com.bmc.arsys.rx.foundation.domain.Agent;

    /**
    * This class implements the Agent Assignment Interface provided by
    * Cognitive Services.
    * Developer is supposed to provide following methods to help the assignment
    * engine to pick the right assignee.
    *
    */
    public class AssignementCalc extends AgentAssignmentCalculator {
     public List<Agent> applicationAgents = new ArrayList<Agent>();
  3. Register the assignment calculator by passing the following parameters:

    • Record definition name (fully qualified) which is the same record definition that you provide in the Suggest Assignee action of your process or rule.

    • The calculator object just created in step 2.

    For example:

    package com.example.bundle;

    /**
    * Used for registering with Assignment Calculator for Cognitive Services.
    */
    import com.bmc.arsys.rx.application.common.ServiceLocator;
    import com.bmc.arsys.rx.assignment.business.AssignmentService;
    import com.bmc.arsys.rx.services.bundle.BundleService;
    import com.bmc.arsys.rx.services.common.RxBundle;

    /**
    * Rx Web Activator class.
    */
    public class MyApplication extends RxBundle {

       /* (non-Javadoc)
        * @see com.bmc.arsys.rx.business.common.RxBundle#register()
        */
       @Override
        protected void register() {
           //
           // TODO: Register static web resources and framework extensions.
           //
           // registerService(new MyService());
           //

            registerStaticWebResource(String.format("/%s", getId()), "/webapp");

           /**
            * Registering with Assignment Calculator for Cognitive Services.
            */
            BundleService bundleService = ServiceLocator.getBundleService();
            AssignmentService assignmentService = (AssignmentService) bundleService.getService(
                    AssignmentService.class.getName());
            AssignementCalc AssignementCal = new AssignementCalc();
            assignmentService.registerAgentAssignmentCalculator("com.example.testassginment:test",
                    AssignementCal);
        }
    }
  4. Extend the AgentAssignmentCalculator class to add the methods that provide information to the assignment process.

Sample code

The following code snippet illustrates a sample implementation of the assignment calculator. In the sample code, the loginIds arrayList is a list of login IDs that belong to Agents in the Foundation library.

package com.example.bundle;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.ThreadLocalRandom;

import com.bmc.arsys.rx.assignment.business.domain.AgentAssignmentCalculator;
import com.bmc.arsys.rx.foundation.domain.Agent;

/**
* This class implements the Agent Assignment Interface provided by
* Cognitive Services.
* Developer is supposed to provide following methods to help the assignment
* engine to pick the right assignee.
*
*/
public class AssignementCalc  extends AgentAssignmentCalculator {
    public List<Agent> applicationAgents = new ArrayList<Agent>();

   /** List of agents login Ids that should exist in Agent foundation record definition */
    public List<String> loginIds = Arrays.asList("Jason Wen", "Ashish Ghumnar", "calvin", "hobbes");

   /** The priorities. Smaller number represents higher priority. */
    public List<Integer> priorities = Arrays.asList(0, 1, 2, 3);

   /**
    * Creating an agent list (used for demo purposes). Those agents should exist in Agent
    * foundation record definition.
    */
    public AssignementCalc() {
       for (String loginId : loginIds) {
            Agent agent = new Agent();
            agent.setLoginId(loginId);
            applicationAgents.add(agent);
        }
    }

   /**
    * This method overrides the method from the Cognitive Assignment interface. It is supposed to
    * send back a list of Agents, sorted by their skill level.
    *
    * This implementation is for the assignment type "by skill level".
    *
    * @param agents
    *            List of agents provided by the assignment engine. It merely contains their login
    *            ID.
    *
    * @return List of Agents, sorted by their skill level as List<Agent>
    */
   @Override
    public List<Agent> rankAgentsBySkillLevel(List<Agent> agents) {
       // As an example we just shuffle the list.
        Collections.shuffle(agents);
       return agents;
    }

   /**
    * This method overrides the method from the Cognitive Assignment interface. It is supposed to
    * send back a list of Agents loginIds and their typical effort (in hours) by Priority. This
    * will be used to assess which developer should be assigned to a task but weighting with the
    * task priority.
    *
    * @param agents
    *            List of agents provided by the assignment engine. It merely contains their login
    *            ID.
    *
    * @return List of Agents loginIds, with a List of their typical efforts per priority as
    *         Map<String, Map<Priority, Float>>
    */
   @Override
    public Map<String, Map<Integer, Float>> getEffortsByPriorityAndByAgents(List<Agent> agents) {
       // As an example we just build a list with random values.
        Map<String, Map<Integer, Float>> effortsByPriorityAndByAgents = new HashMap<String, Map<Integer, Float>>();

       for (Agent agent : agents) {
            Map<Integer, Float> effortPriority = new HashMap<Integer, Float>();

           for (Integer currentPriority : priorities) {
                effortPriority.put(currentPriority, (float) getRandomValue(0, 50));
            }

            effortsByPriorityAndByAgents.put(agent.getLoginId(), effortPriority);
        }

       return effortsByPriorityAndByAgents;
    }

   /**
    * This method overrides the method from the Cognitive Assignment interface. It is supposed to
    * send back a list of Agents loginIds with their last assignment date.
    *
    * This implementation is for the assignment type "round robin".
    *
    * @param agents
    *            List of agents provided by the assignment engine. It merely contains their login
    *            ID.
    *
    * @return List of Agents loginIds with their last assignment date as Map<String, Date>.
    */
   @Override
    public Map<String, Date> getAgentsLastAssignTime(List<Agent> agents) {
       // As an example we just build a list with random date values.
        Map<String, Date> agentsLastAssignTime = new HashMap<String, Date>();

       for (Agent agent : agents) {
            agentsLastAssignTime.put(agent.getLoginId(), getRandomDate());
        }

       return agentsLastAssignTime;
    }

   /**
    * This method overrides the method from the Cognitive Assignment interface. It is supposed to
    * send back a list of Agents loginIds with their current number of assigned tasks.
    *
    * This implementation is for the assignment type "by number".
    *
    * @param agents
    *            List of agents provided by the assignment engine. It merely contains their login
    *            ID.
    *
    * @return List of Agents loginIds with their with their current number of assigned tasks as
    *         Map<String, Integer>.
    */
   @Override
    public Map<String, Integer> getAgentNumberOfAssignedTasks(List<Agent> agents) {
       // As an example we just build a list with random values.
        Map<String, Integer> agentNumberOfAssignedTasks = new HashMap<String, Integer>();

       for (Agent agent : agents) {
            agentNumberOfAssignedTasks.put(agent.getLoginId(), getRandomValue(0, 10));
        }

       return agentNumberOfAssignedTasks;
    }

   /**
    * This method overrides the method from the Cognitive Assignment interface. It
    * sends back a list of Agents loginIds with their actual capacity.
    *
    * This implementation is for the assignment type "by capacity".
    *
    * @param agents
    *            List of agents provided by the assignment engine. It merely contains their login
    *            ID.
    *
    * @return List of Agents loginIds with their with their actual capacity as Map<String, Float>.
    */
   @Override
    public Map<String, Float> getAgentCapacity(List<Agent> agents) {
       // As an example we just build a list with random values.
        Map<String, Float> agentCapacity = new HashMap<String, Float>();

       for (Agent agent : agents) {
            agentCapacity.put(agent.getLoginId(), (float) getRandomValue(0, 100));
        }

       return agentCapacity;
    }

   /**
    * This method overrides the method from the Cognitive Assignment interface. It is supposed to
    * send back a list of Agents loginIds with the amount of their available time between the
    * current Date and a date provided by the assignment engine. This amount, in hours, could be
    * determined by their usual schedule, PTO and current assignments.
    *
    * @param agents
    *            List of agents provided by the assignment engine. It merely contains their login
    *            ID.
    *
    * @return List of Agents loginIds with their with their amount of available time (hours) as
    *         Map<String, Float>.
    */
   @Override
    public Map<String, Float> getAvailableWorkHours(List<Agent> agents, Date date) {
       // As an example we just build a list with random values.

        Calendar cal = Calendar.getInstance();
        cal.add(Calendar.DATE, -8);

       int hoursDifference = getDateDifference(date, cal.getTime());

        Map<String, Float> availableWorkHours = new HashMap<String, Float>();

       for (Agent agent : applicationAgents) {
            availableWorkHours.put(agent.getLoginId(), (float) getRandomValue(0, hoursDifference));
        }

       return availableWorkHours;
    }

   /**
    * Generate a random Date.
    * https://stackoverflow.com/questions/11016336/how-to-generate-a-random-timestamp-in-java
    *
    * @return a random Date in Date format.
    */
    private Date getRandomDate() {
        Random r = new Random();
       long unixtime = (long) (1293861599 + r.nextDouble() * 60 * 60 * 24 * 365);

       return new Date(unixtime);
    }

   /**
    * generate a random number in the provided range
    * https://stackoverflow.com/questions/363681/how-do-i-generate-random-integers-within-a-
    * specific-range-in-java
    *
    * @param min
    *            Minimum value for the random number.
    * @param max
    *            Maximum value for the random number.
    *
    * @return random number as an int.
    */
    private int getRandomValue(int min, int max) {
       return ThreadLocalRandom.current().nextInt(min, max + 1);
    }

   /**
    * Get difference between two dates, in hours.
    * https://stackoverflow.com/questions/2003521/find-total-hours-between-two-dates
    *
    * @param date1
    *            Begin date
    * @param date2
    *            End date
    * @return difference between both dates in hours.
    */
    private static int getDateDifference(Date date1, Date date2) {

        final int MILLI_TO_HOUR = 1000 * 60 * 60;
       return (int) (date1.getTime() - date2.getTime()) / MILLI_TO_HOUR;
    }
}

Where to go from here

Automating-categorization-and-assignment-of-application-requests