Modeling and Class structure

In other for the correct classes to be generated, along with the supporting meta-data for the batch launcher, a class must be defined in the UML model with one method of stereotype <<batch>> for each batch executable. For more information on the <<batch>> stereotype, please consult the Cúram Modeling Reference Guide. When writing a streamed batch program two batch executables are required for the chunker and the stream. For example, consider two classes each with a method called process.

In other to use the batch streaming infrastructure the following is also required:

  1. a chunker implementation which implements the BatchMain interface.
  2. a stream implementation which implements the BatchStream interface

To minimize the volume of classes required, it is recommended to add the methods from the interfaces, which are required for the implementation, to the modeled classes created above. This gives rise to two modeled classes as shown in the figure below.

Figure 1. UML Model for Example Streamed Batch Program

The factory mechanism used for generated Cúram classes prevents other classes seeing the interfaces implemented by the impl classes. To get around this, it is necessary to create a wrapper class to implement the required interfaces. This is shown in the examples below.

Figure 2. Chunker Wrapper implementation
public class DetermineProductDeliveryEligibilityWrapper 
  implements BatchMain {

  private curam.core.intf.DetermineProductDeliveryEligibility 
    determineProdDeliveryEligibilityObj;

  public DetermineProductDeliveryEligibilityWrapper(
    curam.core.intf.DetermineProductDeliveryEligibility 
    determineProductDeliveryEligibility) {

    determineProdDeliveryEligibilityObj = 
      determineProductDeliveryEligibility;

  }

  public void sendBatchReport(
    String instanceID, BatchProcessDtls batchProcessDtls,
    BatchProcessChunkDtlsList processedBatchProcessChunkDtlsList,
    BatchProcessChunkDtlsList unprocessedBatchProcessChunkDtlsList)
    throws AppException, InformationalException {

    determineProdDeliveryEligibilityObj.sendBatchReport(instanceID,
      batchProcessDtls, processedBatchProcessChunkDtlsList,
      unprocessedBatchProcessChunkDtlsList);

  }

  public BatchProcessingResult doExtraProcessing(
    BatchProcessStreamKey batchProcessStreamKey, 
    Blob batchProcessParameters)
    throws AppException, InformationalException {
    
    return null;
    
  }

}

In this particular example the doExtraProcessing operation isn't implemented and so the wrapper just returns and the modeled class doesn't contain this method.

Figure 3. Chunker Wrapper implementation
public class DetermineProductDeliveryEligibilityStreamWrapper 
  implements BatchStream {

  private curam.core.intf.DetermineProductDeliveryEligibilityStream 
    determineProdDeliveryEligibilityStreamObj;

  public DetermineProductDeliveryEligibilityStreamWrapper(
    curam.core.intf.DetermineProductDeliveryEligibilityStream 
    determineProdDeliveryEligibilityStream) {

    determineProdDeliveryEligibilityStreamObj =
      determineProdDeliveryEligibilityStream;

  }

  public String getChunkResult(int skippedCasesCount)
    throws AppException, InformationalException {

    return determineProdDeliveryEligibilityStreamObj.getChunkResult(
      skippedCasesCount);

  }

  public BatchProcessingSkippedRecord processRecord(
    BatchProcessingID batchProcessingID, Object parameters)
    throws AppException, InformationalException {

    return determineProdDeliveryEligibilityStreamObj.processRecord(
      batchProcessingID, 
      (DetermineProductDeliveryEligibilityKey) parameters);

  }

  public void processSkippedCases(
    BatchProcessingSkippedRecordList batchProcessingSkippedRecordList)
    throws AppException, InformationalException {

    determineProdDeliveryEligibilityStreamObj.processSkippedCases(
      batchProcessingSkippedRecordList);

  }

}