Code

The application must implement the NotificationDelivery callback interface to determine how notifications are handled in the application.

The workflow engine will call the deliverNotification method in the curam.util.workflow.impl.NotificationDelivery implementation class in order to process the notification. The engine will pass both the list of allocation targets determined by the allocation strategy and the details of the required notification to this application method.

The application property curam.custom.notifications.notificationdelivery defines what implementation of the NotificationDelivery interface will be used by the workflow engine to process the notification.

The deliverNotification method in this default implementation class is overloaded. This is because the various allocation strategy types return the allocation targets in different formats. However this is an implementation detail that developers of custom notification delivery classes should not have to deal with especially since the business processing for all versions of the method should be the same.

package curam.util.workflow.impl;

      ...

      public interface NotificationDelivery {

        boolean deliverNotification(
          final NotificationDetails notificationDetails,
          final Object allocationTargets);

        boolean deliverNotification(
            final NotificationDetails notificationDetails,
            final Map allocationTargets);


        boolean deliverNotification(
            final NotificationDetails notificationDetails,
            final String allocationTargetID);

            ...
      }

To mitigate against this issue the curam.core.sl.impl.DefaultNotificationDeliveryAdapter provides a more convenient mechanism for implementing a work resolver. This class implements the different methods and converts their input parameters into allocation target lists allowing developers of custom notification delivery logic to extend this class and implement one method that is called regardless of the source of the allocation targets.

package curam.core.sl.impl;

      ...

      public abstract class DefaultNotificationDeliveryAdapter
        implements curam.util.workflow.impl.NotificationDelivery {

        public abstract boolean deliverNotification(
          final NotificationDetails notificationDetails,
          final AllocationTargetList allocationTargets);

            ...
      }

In addition to this adapter class the application ships with a notification delivery implementation that is used out-of-the-box. This class is called curam.core.sl.impl.DefaultNotificationDelivery and it also serves as an example of how to extend the adapter.

The notification delivery strategies are listed in the DELIVERYMECHANISM code table. Adding a new strategy is simply a matter of extending this code table with a new strategy (for example SMS) and implementing a delivery strategy that recognizes this code and performs the appropriate logic. However since the notification delivery class is set using a single application property, replacing the curam.core.sl.impl.DefaultNotificationDelivery class would disable out-of-the-box delivery mechanisms. If the goal is to extend rather replacing the out-of-the-box delivery mechanisms, custom classes should extend the curam.core.sl.impl.DefaultNotificationDelivery in a way that preserves the original functionality. The curam.core.sl.impl.DefaultNotificationDelivery class has been implemented with this in mind.

package curam.core.sl.impl;

 public class DefaultNotificationDelivery
     extends DefaultNotificationDeliveryAdapter {

   public boolean deliverNotification(
       NotificationDetails notificationDetails,
       AllocationTargetList allocationTargetList) {
     return selectDeliveryMechanism(
       notificationDetails, allocationTargetList);
   }

   protected boolean selectDeliveryMechanism(
     NotificationDetails notificationDetails,
      AllocationTargetList allocationTargetList) {

     boolean notificationDelivered = false;
     if (notificationDetails.deliveryMechanism.equals(
         curam.codetable.DELIVERYMECHANISM.STANDARD)) {
       notificationDelivered = standardDeliverNotification(
         notificationDetails, allocationTargetList);
     } else if (
     ...
     return notificationDelivered;
   }

   ...

 }

The curam.core.sl.impl.DefaultNotificationDelivery class implements the deliverNotification method from the abstract adapter but immediately delegates the identification of the mechanism to use to a protected method. The protected selectDeliveryMechanism method can be overridden by subclasses to identify any custom delivery mechanisms and perform the appropriate operations as shown in the example below:

public class CustomNotificationDeliveryStrategy
     extends DefaultNotificationDelivery {

   protected boolean selectDeliveryMechanism(
     NotificationDetails notificationDetails,
      AllocationTargetList allocationTargetList) {

     boolean notificationDelivered = false;
     boolean superNotificationDelivered = false;
     superNotificationDelivered = super.selectDeliveryMechanism(
       notificationDetails, allocationTargetList);
     if (notificationDetails.deliveryMechanism.equals(
       curam.codetable.DELIVERYMECHANISM.CUSTOM)) {
       notificationDelivered = customDeliverNotification(
         notificationDetails, allocationTargetList);
     }
     return (superNotificationDelivered || notificationDelivered);
   }
 }

Notice that the selectDeliveryMechanism method in the custom class first delegates to its super class before executing any of its own logic. Extending the functionality in this was allows custom classes to invoke the out-of-the-box delivery mechanism without having to know the specific codes the parent class recognizes. This approach is also upgrade friendly as if a future version of Cúram supports more delivery mechanisms out-of-the-box a custom class implemented as shown here will not need to change to avail of the new functionality.

The boolean flag returned from the notification delivery function above is used to indicate to the Workflow Engine if the notification was delivered to at least one user on the system. If it was not, then the engine writes a workflow audit record detailing this fact.