Batch Framework

AX 2012: Mastering Batch Framework

Posted on Updated on

Master the Batch Framework in Dynamics AX 2012 by going through the following topics in sequence. The initial topics discuss the basics followed by advanced and complex concepts of the Batch Framework. All the posts will be based on the SysOperation framework which is recommended over the depreciated RunBase framework to develop customized batch jobs.

Following are the topics which are listed in the order of their complexity:

1. Create a simple batch job.

This post describes how to develop a fully functional customized batch job with the following minimum development artifacts:

  • Service operation class

2. Add fields to batch job dialog.

This post builds on the previous topic and describes how to use data contracts to add custom fields to the batch job dialog to control the service operation. It uses the following development artifacts:

  • Service operation class
  • Data contract class

3. Add lookup to batch job dialog.

This post builds on the previous topic and describes how to develop custom UI builder class extending SysOperationAutomaticUIBuilder base class to add lookups and custom validations to batch job dialog. It uses the following development artifacts:

  • Service operation class
  • Data contract class
  • UI Builder class

4. Customize controller for batch job.

This post builds on the previous topic and describes how to develop custom controller class extending SysOperationServiceController base class to have more control over execution modes of the service operation as well as initializing dialog fields with default values. It uses the following development artifacts:

  • Service operation class
  • Data contract class
  • UI Builder class
  • Controller class

AX 2012: Customize Controller for Batch Job

Posted on Updated on

The purpose of this document is to demonstrate what power we can leverage by customizing the controller for our batch job. For simplicity, we’ll explore how we can set batch dialog fields with default values by extending SysOperationServiceController class.

Prerequisites:

It is highly recommended to go through the following posts to get a better understanding of what we have done so far in the Batch Framework series.

1. Create a simple batch job.
2. Add fields to batch job dialog.
3. Add lookup to batch job dialog.

Business Requirement:

To set batch dialog fields with default values.

Project Overview:

Untitled

Development Steps:

1. Create a new class MAKSalesTableServiceController extending SysOperationServiceController base class.

class MAKSalesTableServiceController extends SysOperationServiceController
{
}

2. Override the new method and give the following definition:

public void new()
{
    super();

    this.parmClassName(classStr(MAKSalesTableService));
    this.parmMethodName(methodStr(MAKSalesTableService, processRecords));
}

3. Create a new method main and give the following definition. This is where the magic happens. The controller is used to get reference to data contract object which is then modified to initialize data members, by calling their parm methods, with default values.

static void main(Args _args)
{
    MAKSalesTableServiceController  controller;
    MAKSalesTableContract           dataContract;

    controller = new MAKSalesTableServiceController();

    // Run operation synchronously, asynchronously or in batch
    // Async execution requires service to be published
    // in the AxClient service group
    controller.parmExecutionMode(SysOperationExecutionMode::ReliableAsynchronous);

    // Get the contract from the controller and initialize it default values
    dataContract = controller.getDataContractObject();
    dataContract.parmFromDate(systemDateGet());
    dataContract.parmToDate(systemDateGet());
    dataContract.parmSalesChannel("Direct");

    // call the operation. The controller will handle execution mode
    controller.startOperation();
}

4. Modify Menu Items > Action > MAKSalesTableService to point to MAKSalesTableServiceController class just created.

Untitled

5. Compile and generate incremental CIL.
6. Click Tools > Caches > Refresh elements to refresh the AOD cache to reflect changes on the batch dialog.
7. Click Menu Items > Action > MAKSalesTableService to run the batch job.
8. You should now be getting batch dialog fields initialized with default values 🙂

Untitled

AX 2012: Add Lookup to Batch Job Dialog

Posted on Updated on

Prerequisites:

1. Create a simple batch job.
2. Add fields to batch job dialog.

Business Requirement:

To have a lookup on the batch job dialog to filter records to be processed based on the user selected value of sales channel field on the dialog.

Project Overview:

Untitled

We’ll be adding a new UI Builder class MAKSalesTableUIBuilder and link it with the MAKSalesTableContract class to add lookup on the batch dialog. It is highly recommended to read the prerequisites first before proceeding any further to have better understanding of the topic.

Development steps:

1. Add salesChannel variable to the class declaration of MAKSalesTableContract class to store sales channel value:

[DataContractAttribute]
class MAKSalesTableContract
{
    TransDate           fromDate;
    TransDate           toDate;
    MAKSalesChannel     salesChannel;
}

2. Add parm method for sales channel variable to designate it as a data member of the contract class:

[
    DataMemberAttribute,
    SysOperationLabelAttribute(literalStr("Sales channel")),
    SysOperationHelpTextAttribute(literalStr("Pick sales channel")),
    SysOperationDisplayOrderAttribute('3')
]
public MAKSalesChannel parmSalesChannel(MAKSalesChannel _salesChannel = salesChannel)
{
    salesChannel = _salesChannel;

    return salesChannel;
}

3. Compile and generate incremental CIL.
4. Click Tools > Caches > Refresh elements to refresh the AOD cache to reflect changes on the batch dialog.
5. You should be able to see newly added Sales channel field on the batch dialog but without a lookup.

Untitled

6. Create a new class MAKSalesTableUIBuilder which extends SysOperationAutomaticUIBuilder base class:

class MAKSalesTableUIBuilder extends SysOperationAutomaticUIBuilder
{
    #define.lookupAlways(2)

    DialogField     fromDateField;
    DialogField     toDateField;
    DialogField     salesChannelField;
}

7. Override the postBuild method of the base class to get the references to dialog field controls after creation:

public void postBuild()
{
    super();

    //Get references to dialog controls after creation
    fromDateField = this.bindInfo().getDialogField(
        this.dataContractObject(), methodStr(MAKSalesTableContract, parmFromDate));
    
    toDateField = this.bindInfo().getDialogField(
        this.dataContractObject(), methodStr(MAKSalesTableContract, parmToDate));
    
    salesChannelField = this.bindInfo().getDialogField(
        this.dataContractObject(), methodStr(MAKSalesTableContract, parmSalesChannel));

    //Change text field metadata to add lookup
    salesChannelField.lookupButton(#lookupAlways);
}

8. Override the postRun method of the base class to register the custom lookup method salesChannelFieldLookup with the form control event lookup:

public void postRun()
{
    super();

    //Register overrides for form control events
    salesChannelField.registerOverrideMethod(
        methodstr(FormStringControl, lookup),
        methodstr(MAKSalesTableUIBuilder, salesChannelFieldLookup),
        this);
}

9. Give the following implementation for the custom lookup method salesChannelFieldLookup:

public void salesChannelFieldLookup(FormStringControl _control)
{
    Query                   query;
    QueryBuildDataSource    qbdsMAKSalesTable;
    SysTableLookup          sysTableLookup;

    query = new Query();
    qbdsMAKSalesTable = query.addDataSource(tableNum(MAKSalesTable));
    qbdsMAKSalesTable.fields().clearFieldList();
    qbdsMAKSalesTable.fields().addField(fieldNum(MAKSalesTable, SalesChannel));
    qbdsMAKSalesTable.addGroupByField(fieldNum(MAKSalesTable, SalesChannel));

    sysTableLookup = SysTableLookup::newParameters(tableNum(MAKSalesTable), _control);
    sysTableLookup.addLookupfield(fieldNum(MAKSalesTable, SalesChannel));
    sysTableLookup.parmQuery(query);
    sysTableLookup.performFormLookup();
}

10. Lastly, modify the class declaration of MAKSalesTableContract class to link it with the MAKSalesTableUIBuilder class we just created by decorating it with the SysOperationContractProcessingAttribute:

[
    DataContractAttribute,
    SysOperationContractProcessingAttribute(classStr(MAKSalesTableUIBuilder))
]
class MAKSalesTableContract
{
    TransDate           fromDate;
    TransDate           toDate;
    MAKSalesChannel     salesChannel;
}

11. Compile and generate incremental CIL.
12. Click Tools > Caches > Refresh elements to refresh the AOD cache to reflect changes on the batch dialog.
13. Click on the menu item MAKSalesTableService to run the batch job dialog.
14. You should now be getting a lookup generated for the Sales channel field on the batch dialog 🙂

Untitled

Next:

Next in the series: Customize controller for batch job.

AX 2012: Add Fields to Batch Job Dialog

Posted on Updated on

Prerequisites:

1. Create a simple batch job.

Requirement:

To add custom fields to batch job dialog to choose a date range to process only those records falling in that date range.

Project overview:

Untitled

As you can see in the picture, a data contract class MAKSalesTableContract has been added to the project to achieve the goal. We’ll be adding from date and to date fields on the batch dialog to capture the date range.

Development steps:

1. Create a new data contract class MAKSalesTableContract with the following class declaration:

[DataContractAttribute]
class MAKSalesTableContract
{
    TransDate   fromDate;
    TransDate   toDate;
}

2. Create a new method parmFromDate with the following definition:

[
    DataMemberAttribute,
    SysOperationLabelAttribute(literalStr("From Date")),
    SysOperationHelpTextAttribute(literalStr("Pick a valid begin date")),
    SysOperationDisplayOrderAttribute('1')
]
public TransDate parmFromDate(TransDate _fromDate = fromDate)
{
    fromDate = _fromDate;

    return fromDate;
}

3. Create a new method parmToDate with the following definition:

[
    DataMemberAttribute,
    SysOperationLabelAttribute(literalStr("To Date")),
    SysOperationHelpTextAttribute(literalStr("Pick a valid end date")),
    SysOperationDisplayOrderAttribute('2')
]
public TransDate parmToDate(TransDate _toDate = toDate)
{
    toDate = _toDate;

    return toDate;
}

4. Update the MAKSalesTableService.processRecords method to the following definition:

[SysEntryPointAttribute(false)]
public void processRecords(MAKSalesTableContract _contract)
{
    MAKSalesTable   makSalesTable;
    int             counter = 0;

    //Determines the runtime
    if (xSession::isCLRSession())
    {
        info('Running in a CLR session.');
    }
    else
    {
        info('Running in an interpreter session.');

        //Determines the tier
        if (isRunningOnServer())
        {
            info('Running on the AOS.');
        }
        else
        {
            info('Running on the Client.');
        }
    }

    //Actual operation performed
    while select forUpdate makSalesTable
        where makSalesTable.TransDate >= _contract.parmFromDate()
            && makSalesTable.TransDate <= _contract.parmToDate()
    {
        ttsBegin;
        makSalesTable.Processed = NoYes::Yes;
        makSalesTable.update();
        ttsCommit;

        counter++;
    }

    info(strFmt("Successfully processed %1 records.", counter));
}

This is where the magic happens. Note that method now takes an input parameter of type MAKSalesTableContract class. Then it filters the records to be processed in the while loop by adding ranges to the MAKSalesTable.TransDate field, using the values given by user on the batch dialog for From Date and To Date.

5. Compile and generate incremental IL.
6. Click on Menu Items > Action > MAKSalesTableService to run the batch job.
7. You should now be having 2 fields added to the batch dialog:

Untitled

Next:

Next in the series: Add lookup to batch job dialog.

AX 2012: Create a Simple Batch Job

Posted on Updated on

In this post we’ll learn how to create a very basic custom Batch job using SysOperation framework. We’ll use the base controller class SysOperationServiceController and develop a custom service operation class to achieve the goal.

Requirement:

To create a Batch job to mark all the records as processed in a custom table MAKSalesTable.

Project overview:

Untitled

The project shows how simple yet powerful the SysOperation framework is for developing custom batch jobs as opposed to RunBase framework since the minimum development needed to create a fully functional batch job is to create a custom service operation class defining a single method giving the implementation for the batch operation to be performed.

Development steps:

1. Create a service operation class MAKSalesTableService having the following class declaration:

class MAKSalesTableService
{
}

2. Create a new method in the class giving a suitable name like processRecords having the following definition:

[SysEntryPointAttribute(false)]
public void processRecords()
{
    MAKSalesTable   makSalesTable;
    int             counter = 0;

    //Determines the runtime
    if (xSession::isCLRSession())
    {
        info('Running in a CLR session.');
    }
    else
    {
        info('Running in an interpreter session.');

        //Determines the tier
        if (isRunningOnServer())
        {
            info('Running on the AOS.');
        }
        else
        {
            info('Running on the Client.');
        }
    }

    //Actual operation performed
    while select forUpdate makSalesTable
    {
        ttsBegin;
        makSalesTable.Processed = NoYes::Yes;
        makSalesTable.update();
        ttsCommit;

        counter++;
    }

    info(strFmt("Successfully processed %1 records.", counter));
}

3. Create an action menu item MAKSalesTableService pointing to SysOperationServiceController.

4. Set the parameters of the action menu item to the service operation just created, MAKSalesTableService.processRecords.

Untitled

5. Compile the service operation class and generate incremental IL.

6. Click on the action menu item to run the batch job. Check the Batch processing checkbox to run the job in CLR runtime which is the batch server execution environment.

Untitled

Untitled

7. Click System administration > Inquiries > Batch jobs to view the status of the job. You may also click on the Log button to view the messages written to infolog during the job execution.

Untitled

Untitled

Preconditions:

Before running the batch job, all the records were unprocessed:

Untitled

Post conditions:

After running the batch job, the list page shows that all the records are now marked as processed:

Untitled

Next:

Next in the series: Add fields to batch job dialog.

AX 2012: All about Batch processing

Posted on Updated on

In this post, you can learn about the following:

1. Batch Server Configuration

Learn about how to set maximum no. of threads and their scheduling. Indicating which AOS instances are batch servers and which are load balancers.

2. Batch Group Configuration

Learn how to configure batch groups. Select AOS instances available for your batch job.

2. How to view Batch jobs running

Learn how to see the status of the batch job just executed. Learn how to change the statuses of batch jobs in the queue. Also learn how to find the log entries against a job.

3. How to debug batch jobs and service operations

Learn how to debug batch jobs and service operations in Visual Studio.

4. Linking Code Permission to service class method

Learn how to grant permissions to invoke a server method via a menu item which is necessary to trigger a batch job in an environment where security measures have been taken.

AX 2012: Batch Groups

Posted on Updated on

To configure a batch group, navigate to:

System Administration → Setup → Batch Group

1. On the batch group form, click on the New button to create a new batch group.
2. Give it a suitable name and description.
3. Switch to Batch Servers tab to view available servers for batch processing.
4. Shift the desired servers from Remaining Servers pane to Selected Servers pane for the particular batch group just created
5. You’re done with batch group configuration!

Untitled

Make sure you choose the appropriate batch group while running a batch job. You can choose your newly created batch group from the Batch Group lookup as shown below:

Untitled