Bulk Aggregate

The purpose of the Bulker Aggregate is to create single or recurring bulks, validating and aggregating components that will be used by the Bulk Producer to create the bulk file.

Single Bulk Aggregate

The Single Bulk aggregate is a component whose purpose is to create a new bulk, aggregate bulk components and make sure those components are valid. After all bulk components are collected by the aggregate, bulking can be started.

Interface

The BulkAggregate interface is defined as follows.

public interface BulkAggregate {

    CompletionStage<BulkIdResponse> createBulk(CreateBulkCommand command); (1)

    CompletionStage<BulkComponentIdResponse> addComponent(AddComponentCommand command); (2)

    CompletionStage<BulkComponentIdResponse> addComponent(AddComponentWithAutoCreateCommand command); (3)

    CompletionStage<Response> updateComponent(UpdateComponentCommand command); (4)

    CompletionStage<Response> removeComponent(RemoveComponentCommand command); (5)

    CompletionStage<Response> closeBulk(CloseBulkCommand command); (6)

    CompletionStage<Response> openBulk(OpenBulkCommand command); (7)

    CompletionStage<Response> finaliseBulk(FinaliseBulkCommand command); (8)

    CompletionStage<BulkReportResponse> getBulkReport(GetBulkReportCommand command); (9)

    CompletionStage<Response> terminateBulk(TerminateBulkCommand command); (10)

    CompletionStage<Response> rejectBulk(RejectBulkCommand command); (11)

    CompletionStage<Response> archiveBulk(ArchiveBulkCommand command); (12)

    CompletionStage<Response> completeBulk(CompleteBulkCommand command); (13)
}
1 createBulk Creates a new bulk.
  • Returns BulkIdResponse with BulkId when bulk creation was successful.

2 addComponent Adds a new component to the bulk aggregate. The first component needs to be a root component.
  • Returns BulkComponentIdResponse with SUCCESS result and BulkComponentId when adding component is successful

3 addComponent Adds a new component to the bulk aggregate with bulk auto-creation functionality. That means if the bulk with the passed bulkId doesn’t exist, it will be created and a root component will be generated by ComponentGenerator before the new component is added to it.
  • Returns BulkComponentIdResponse with SUCCESS result and BulkComponentId when adding component is successful

4 updateComponent Updates the component that which is present in the aggregate with the new content.
  • Returns Response with SUCCESS result if the component update is successful

5 removeComponent Deletes the component which is present in the aggregate.
  • Returns Response with SUCCESS result if the component removal is successful

6 closeBulk Closes the aggregate, preventing the client from removing and adding new components to the aggregate, but allows updating components which are already in the aggregate.
  • Returns Response with SUCCESS result if the bulk is closed

7 openBulk Re-opens the aggregate which is closed.
  • Returns Response with SUCCESS result if the bulk is opened

8 finaliseBulk The point of no return, this is the signal to start processing data in the aggregate and perform bulking.
  • Returns Response with SUCCESS result if the bulk is finalised

9 getBulkReport Returns a BulkReportResponse which contain information about current bulk.
10 terminateBulk Removes a whole bulk which is present in the aggregate.
  • Returns Response with SUCCESS result if the bulk removal is successful

11 rejectBulk Deletes the bulk file produced after finalisation has occurred. The command will only be successfully processed if the Bulk is in the finalised state, and if the produced file is present. It is recommended that this process is triggered after the BulkFinalisedNotification event has been received.
  • Returns Response with SUCCESS result if the deletion of the produced bulk file is successful

12 archiveBulk Archives the bulk file produced after finalisation has occurred. The command will only be successfully processed if the Bulk is in the finalised state, and if the produced file is present. It is recommended that this process is triggered after the BulkFinalisedNotification event has been received.
  • Returns Response with SUCCESS result if the archiving of the produced bulk file is successful. Note: a BulkArchivedNotification will always be generated after the successful processing of an archiveBulk command, even when archiving has not been performed due to the required file-reader and file-writer configuration not being provided.

13 completeBulk Completes finalised bulk, after bulk is complete, only getBulkReport method can be called.

Recurring Bulk Aggregate

Recurring Bulk Aggregate is a component for creating a recurring bulk. It is responsible for adding components to a currently open Bulk Aggregate, and when that Bulk Aggregate gets finalised for any reason, it will create new Bulk Aggregate with a root component and forward components to it.

Interface

The RecurringBulkAggregate interface is defined as follows.

public interface RecurringBulkAggregate {

    CompletionStage<Response> configureBulk(ConfigureBulkCommand command); (1)

    CompletionStage<RecurringBulkComponentIdResponse> addComponent(AddComponentCommand command); (2)

    CompletionStage<CurrentOpenBulkResponse> getCurrentOpenBulk(GetCurrentOpenBulkCommand command); (3)
}
1 createBulk is used to create a new recurring bulk.
  • Returns a CurrentOpenBulkResponse with the BulkId of the current single bulk and the root component id to which components will be sent via addComponent method

2 addComponent is used to add new component to the current open bulk.
  • Returns a RecurringBulkComponentIdResponse with a SUCCESS result, the BulkId of the single bulk aggregate to which component was added, and the BulkComponentId of the added component

3 getCurrentOpenBulk is used to retrieve the current recurring bulk
  • Returns a CurrentOpenBulkResponse with the BulkId of the current single bulk and root component id to which components will be sent via addComponent method

What you need to implement

Since the recurring bulk aggregate is responsible for creating a new single bulk, it is also responsible for generating the root component for the created single bulk, and the client can send only components which will be added as child components of that root component. Clients will need to create an implementation of ComponentGenerator which will be responsible for the generation of a single bulk root component created by the recurring bulk aggregate.

public interface ComponentGenerator {
    String generateComponent(String specificationName); (1)
}
1 generateComponent is used to create a root component for the single bulk created by the recurring bulk.
  • It should return the generated component based on the passed specificationName.

Error Codes

When a client sends invalid commands a response with FAILURE result will be returned along with the Error.

List of error codes:

Error Message Description For Command Aggregate type

AC01

Parent id present for root component

Root component can’t have a parent

AddComponentCommand

Single

AC02

Parent doesn’t exist

Returned if the parent is not present in the bulk aggregate (doesn’t apply to root component)

AddComponentCommand

Single

AC03

Path not valid or not present in the BulkSpecification

Returned if component path is not defined in the BulkSpecification

AddComponentCommand

Single

AC04

Content not present

Returned if content is null or empty

AddComponentCommand

Single

AC05

Bulk auto closed

Returned if bulk is auto closed

AddComponentCommand

Single

AC06

Bulk component with the same id already exists

Returned if component with the same id is already added to bulk aggregate

AddComponentCommand

Single

UC01

Component doesn’t exist

Component with BulkComponentId not present in the Bulk Aggregate

UpdateComponentCommand

Single

UC02

Content not present

Returned if content is null or empty

UpdateComponentCommand

Single

RC01

Component doesn’t exist

Component with BulkComponentId not present in the Bulk Aggregate

RemoveComponentCommand

Single

RC02

Root component can’t be deleted

Returned if component can’t be removed because it is a root component

RemoveComponentCommand

Single

RC03

Component has child components

Returned when component can’t be removed because it has child components

RemoveComponentCommand

Single

CS01

Failed to save to component store

If a save/update fails to the component store

On any command that adds or updates components

Single

CS02

Failed to delete from component store

If a delete fails from the component store

RemoveComponentCommand

Single

SS01

Failed to retrieve bulk state

If it fails to retrieve persisted bulk state

During bulk actor creation

Single

RB01

Recurring bulk id not valid

Returned if recurring bulk id is not valid

CreateBulkCommand

Recurring

RB02

Recurring bulk specification not valid

Returned if BulkSpecification is not valid.

CreateBulkCommand

Recurring

RB03

Bulk marked as closed

The command is not supported in the current state

On any command other than finalise

Recurring

RB04

Recurring bulk not configured

The command is not supported in the current state

GetCurrentOpenBulk

Recurring

RB05

No Current Open Bulk

The command is not supported in the current state

GetCurrentOpenBulk

Recurring

RB06

New bulk creation in progress

The command is not supported in the current state

AddComponentWithAutoCreate, RegisterChildBulkWithAutoCreate

Recurring

NSC01

Command is not supported

The command is not supported in the current state

On any command

Idempotency

In order to enforce idempotency, and prevent adding two same components to bulk aggregate, client should set component id when sending AddComponent commands to bulker.

Since bulk aggregate doesn’t care about the component content, if the client sends two components with the same content but with different component ids, both components would be accepted.

Implementations

As with other IPF libraries, the default implementations for the most common use cases are already provided.