D365FFO – AX – FTP Adapter for AIF

The Application Integration Framework in Dynamics AX is an extensible framework for data transportation and reception. It support the separation of transport technology (e.g. MSMQ, XML/SOAP Webservices, Filesystem Share) security aspects (services, permissions, transported data) and data manipulation. Creating new adapters to support other transport technologies is simple. Here is an example to support FTP.

Develop AIF FTP Adapter

  • First, create a new parameter table AifFTPParameters to store FTP server name, user, password and directory (4 strings). Next create a setup form for the AifFTPParameters table and a display menu item. Add an OK command button. Add this code to the buttons clicked event:

    void clicked()
    {;
        super();
        // use the server name as selected value 
        element.closeSelect(Setup_ServerName.text());
    }
FTP Parameters setup
  • Create a new AifFTPSendAdapter class that implementes the AifSendAdapter interface. You may create empty implementations for begin(), commit(), initialize(), rollback() and terminate(). But you really need to implement the sendMessage() method. I’m using the System.Net Classes to implement the FTP transfer.
     

    public void sendMessage(AifGatewayMessage gatewayMessage)
    {
        System.Text.Encoding encoding;
        System.Byte[] bytes;
        str requestStr = “”;
        object ftpo;
        System.Net.FtpWebRequest ftpRequest;
        System.Net.NetworkCredential credential;
        str ftpUser;
        str ftpPass;
        System.IO.Stream requestStream;
        InteropPermission clrPermission =
         new InteropPermission(InteropKind::ClrInterop);
        ;    clrPermission.assert();    switch(gatewayMessage.parmEncoding())
        {
            case ‘UTF-8’:
                encoding = System.Text.Encoding::get_UTF8();
                break;
            default:
                throw error(“Unsupported Encoding”);
        }
        bytes = encoding.GetBytes(gatewayMessage.parmMessageXml());    requestStr = strfmt(‘ftp://%1′,AifFTPParameters::find().ServerName);
        if(AifFTPParameters::find().Directory)
        {
            requestStr = strfmt(‘%1/%2’,
                                 requestStr,
                                 AifFTPParameters::find().Directory);
        }
        requestStr = strfmt(‘%1/%2%3’,
                              requestStr,
                              gatewayMessage.parmMessageId(),
                              ’.xml’);    ftpo =  System.Net.WebRequest::Create(requestStr);
        ftpRequest = ftpo;    ftpUser = AifFTPParameters::find().UserName;
        ftpPass = AifFTPParameters::find().Password;
        //BP deviation documented
        credential = new System.Net.NetworkCredential(ftpUser,ftpPass);
        ftpRequest.set_Credentials(credential);
        ftpRequest.set_ContentLength(bytes.get_Length());
        ftpRequest.set_Method(‘STOR’);    requestStream = ftpRequest.GetRequestStream();
        requestStream.Write(bytes,0,bytes.get_Length());
        requestStream.Close();    CodeAccessPermission::revertAssert();
    }
  • Create a new AifFTPAdapter class that implements AifIntegrationAdapter. This class is used by the AIF configuration interface in Dynamics AX to identify an outbound adapter and its configuration form.
    public AifIntegrationAdapterType getAdapterType()
    {;
        return AifIntegrationAdapterType::SendOnly;
    }
    public MenuItemNameDisplay getAddressDisplayMenuItem()
    {;
        // the AifFTPParameter forms display menu items name
        return ‘AifFTPParameters’;
    }
    public AifTransportAddress getCanonicalTransportAddress(AifTransportAddress transportAddress)
    {;
        return transportAddress;
    }
    public MenuItemNameDisplay getConfigurationDisplayMenuItem()
    {;
        return ”;
    }
    public LabelString getLabel()
    {;
        return “AIF FTP Adapter”;
    }
    public AifReceiveAdapter getReceiveAdapter()
    {;
        return null;
    }
    public AifSendAdapter getSendAdapter()
    {;
        return new AifFTPSendAdapter();
    }
    public boolean isHosted()
    {;
        return true;
    }
    public void validateConfiguration(AifTransportAddress transportAddress,
                                      AifChannelDirection channelDirection)
    {;
        //TODO:Check or throw error
    }
  • Go to Basics > Setup > Application Integration Framework.
  • In Local Endpoints make sure you have an endpoint configured
  • In Transport Adapters create a new record, select AifFTPAdapter and mark it as active.
  • In Channels, create a new outbound FTP Channel, provide server name and credentials.
    Mark the channel as active.
Configure AIF FTP Adapter

Activate SalesSalesInvoiceService

In Endpoints create a new endpoint. Set the outbound channel to your FTP channel and set the local endpoint. Go to the Constraints tab and set “No Constraints” flag. Mark the endpoint as active.

Create an endpoint with outbound FTP

Click the Action Policies button and add the SalesSalesInvoiceService.read method

Activate SalesSalesInvoiceService.read

Click the Data Policies button and use the set button to enable all data fields for transportation.

Set data policies for invoice

Set data policies for invoice

Go to Basic > Inquiries > Batch jobs. Make sure to run a batch job that processes the AIF message send and receive tasks: AIFInboundProcessingService, AIFOutboundProcessingService, AIFGatewaySendService and AIFGatewayReceiveService.

Setup AIF processing batch jobs

Go to Accounts Receivable > Inquiries > Journals > Invoice. Select an invoice and use the Send Electronically button to put it in the transportation queue.

Send invoice electronically using AIF

Wait a few miniutes and take a look at your FTP space. There you should see the transmitted invoices as xml file.

Invoice successfully uploaded

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s