AX 2012 Export Data with Outbound ports

I've recently made some tests with AIF (Application Integration Framework), inbound ports and outbound ports.
I had never used AIF before AX 2012 and this is a great tool once you understand how it works.
MSDN explains the subject quite correctly : Services and Application Integration Framweork 2012

At the beginning, I did not understand the concept of outbound port. SoI decided to take an interest in it. I've known web services for a long time now so I could correctly understand the "inbound port" concept; a service is "listening" at a specific "port", ready to execute your method with input parameters.
But what for outbound ports ? There is no socket "port" to pull out data....

Outbound ports are not related with web services or network at all (talking about WCF, bindings and endpoints). You can use it in order to retreive data from Dynamics AX and send the results to either a file or a message queue (MSMQ).


The following post will show a summary of the steps I followed in order to export customers in several XML files into a directory on the AOS server.



  1. I create an outbound port specifying "File system adapter" as adapter.
    You can limit it to a specific company if you want
    In the operations I choose : CustCustomerService.read

    This service operation will be used to read a customer from AX by specifying an account number.
    The output result of the operation will be the customer itself.
  2. I create a new folder on the AOS side (in the example C:\AIFOutputTemp).
    Don't forget to give the correct write access rights for the user executing your AOS Service.
    The AOS will need write access to create the file.
  3. I specify the newly created folder in the URI of the outbound port.
  4. I save the outbound port and I activate it.
  5. I create a new job to post some customer in the AIF Queue :

    static void AIF_SendCustomer(Args _args)
    {

        AxdSendContext axdSendContext = AxdSendContext::construct();
        AifEntityKey aifEntityKey = AifEntityKey::construct();
        Map keyData;
        AifConstraintList aifConstraintList = new AifConstraintList();
        AifConstraint aifConstraint = new AifConstraint();

        CustTable       custTable;
        ;

        custTable = CustTable::find("<CUSTACCOUNT>");
       
        keyData = SysDictTable::getKeyData(custTable);

        aifEntityKey.parmTableId(custTable.TableId);
        aifEntityKey.parmRecId(custTable.RecId);
        aifEntityKey.parmKeyDataMap(keyData);

        axdSendContext.parmXMLDocPurpose(XMLDocPurpose::Original);
        axdSendContext.parmSecurity(false);

        aifConstraint.parmType(AifConstraintType::NoConstraint) ;
        aifConstraintList.addConstraint(aifConstraint) ;

        AifSendService::submitDefault(
            classnum(CustCustomerService),
            aifEntityKey,
            aifConstraintList,
            AifSendMode::Async,
            axdSendContext.pack());

    }
  6. Once this code is executed, a new record will be created in the AIF Queue manager.

    You can reach the queue manager with the following path :
    System Administration > Periodic > Services and Application Integration Framework > Queue manager

    Status will be ready and you will see the document service operation involved.

  7. Now the instructions are created with correct parameters. You can either setup a batch system tha will automatically execute the following method, or you can simply execute it manually.
    There is an explanation of this at msdn : Configuring batch jobs for AIF
    AifOutboundProcessingService = new AifOutboundProcessingService();
    AifOutboundProcessingService.run();
  8. Once this method has been executed, you will be able to see the resulting newly created AIF message (XML result). For this, use the following menu : Document Log and View message




  9. Once the message has been created, we can execute the following method :

    AifGatewaySendService = new AifGatewaySendService();
    AifGatewaySendService.run();
  10. This operation will export the message to a physical XML file on the folder we specified in the outbound port.

 That's it for outbound ports.

    13 comments:

    1. Hi

      I have created some outbound services to export data from Ax to a interface.
      I tested them by passing a specific record in a job.
      But i want to run this outbound service as a RunBase batch class.( I want to create a batch job class and run the outbound serivce)
      So here i want to run the service for all the data in the service (query).
      How can i achieve this ?

      Thanks in advance
      Reply
      Replies
      1. Hi,

        In order to automate the export process you could create as you said a new class that inherit from RunBaseBatch and then running this class within a batch job.
        This will send the records to the queue.
        In order to automatically process the queue you filled with the class, take a look at this link : http://technet.microsoft.com/en-us/library/hh352328.aspx

        It explains how to configure the batch jobs for AIF.
      2. This comment has been removed by the author.
    2. Hello, here is the code you can use in order to export a list of customers with a Query :

      Query queryCustTable;
      AifActionId actionId;
      AifEndpointList endPointList;
      AifConstraintList aifConstraintList = new AifConstraintList();
      AifConstraint aifConstraint = new AifConstraint();
      AifOutboundProcessingService AifOutboundProcessingService;


      queryCustTable = new Query();
      queryCustTable.addDataSource(tableNum(custTable),"CustTable");
      queryCustTable.dataSourceTable(tableNum(custTable)).addRange(fieldNum(custTable,AccountNum)).value("13*");

      aifConstraint.parmType(AifConstraintType::NoConstraint);
      aifConstraintList.addConstraint(aifConstraint);

      actionId = AifSendService::getDefaultSendAction(classnum(CustCustomerService), AifSendActionType::SendByQuery);

      if (actionId)
      {
      endPointList = AifSendService::getEligibleEndpoints(actionId, aifConstraintList);
      if(endpointList.getEndpointCount()>0)
      AifSendService::submitFromQuery(actionId,endPointList,queryCustTable,AifSendMode::Async);
      }


      AifOutboundProcessingService = new AifOutboundProcessingService();
      AifOutboundProcessingService.run();

      Don't forget to change the operation on the outbound service from CustCustomerService.read to CustCustomerService.find
      Reply
      Replies
      1. Thank you very much
      2. How can i do the similar operation for a specific Inbound message
        Like through x++ i want to run a specific Inbound message
      3. Hello,

        Take a look a the AifInboundProcessingService class. It should do the job.
    3. where to write this code
      AifOutboundProcessingService = new AifOutboundProcessingService();
      AifOutboundProcessingService.run();
      and
      AifGatewaySendService = new AifGatewaySendService();
      AifGatewaySendService.run();
      Reply
    4. Hello,

      I would say it depends.

      The AifOutboundProcessingService will process all the requests that were placed in the AifOutboundProcessingQueue by the submitDefault method. It will send them in the AifGatewayQueue table.

      The AifGatewaySendService on the other hand will retrieve records that are
      in the AifGatewayQueue and will process the messages. In this case, as the outbound port is configured to export a file, it will export the message (XML file) in the specified directory.

      So you can use this code in different ways depending on your intentions :)
      Reply
    5. Hi,

      I am trying to export Items data using standard service "InventItemService"
      But when the file is exported i cannot see all the items in the file. Also i cannot see the newly created items in the file.

      If i try to export the specific item (which is not coming in the xml) through job the xml got generated for that item.

      But when the service is running for all the items some items and new items are not coming in the xml. Also the query returns the item data (which is not coming

      Am i missing anything ? what can be the reason for this .
      Reply
    6. Hello, your problem is weird... All the items should be exported.
      Honestly, I don't know what could be the cause. Do you use the same code to export only one item and all items ? I mean do you send "byKey" or "byQuery" ?
      Reply
    7. Hi Renauld,
      I have a question about preparation of entity key lists. The normal way is, to define this like you said: keyData = SysDictTable::getKeyData(custTable);
      In my case, I get the RecId but I need the naturalKey for my outbound update message instead. Do you know some samples to prepare this in the axd class? I've seen, there is a method called useNaturalKey and a possibility to manipulate the KeyMap in getEntityKeyReplaycmentElementMap. Do you have some experiences to do this? I can't find anything in the web.

      Best regards,
      Frank
      Reply
    8. Hi,
      I've created a query with vendtable and dirpartyview, and created a document service through AIFDocumentservicewizard and configured that in outbound port. Can anyone tell me how to access the service and send the details to an XML file
      Reply

    No comments:

    Post a Comment

    Note: Only a member of this blog may post a comment.