Chamando serviços de documentos AIF diretamente do X++ no Dynamics AX 2012
Publicado: 16 de fevereiro de 2025 às 11:23:10 UTC
Neste artigo, explico como chamar serviços de documentos do Application Integration Framework no Dynamics AX 2012 diretamente do código X++, emulando chamadas de entrada e saída, o que pode tornar significativamente mais fácil encontrar e depurar erros no código AIF.
Calling AIF Document Services Directly from X++ in Dynamics AX 2012
As informações neste post são baseadas no Dynamics AX 2012 R3. Podem ou não ser válidas para outras versões.
Recentemente, eu estava ajudando um cliente a implementar uma porta de entrada do Application Integration Framework (AIF) para criar clientes com base em dados que eles estavam recebendo de outro sistema. Como o Dynamics AX já fornece o serviço de documento CustCustomer, que implementa a lógica para isso, decidimos mantê-lo simples e usar a solução padrão.
No entanto, logo descobri que havia muitos problemas para fazer o sistema externo gerar XML que o Dynamics AX aceitaria. O esquema XML gerado pelo Dynamics AX é bem complexo e também parece que há alguns bugs no Dynamics AX que às vezes fazem com que ele rejeite XML que é válido para o esquema de acordo com outras ferramentas, então, no geral, provou ser menos simples do que eu pensava.
Durante o esforço, muitas vezes tive dificuldade para descobrir qual era exatamente o problema com certos arquivos XML porque as mensagens de erro fornecidas pelo AIF são menos do que informativas. Também era tedioso, porque eu tinha que esperar o sistema externo enviar uma nova mensagem pelo MSMQ e depois novamente para o AIF pegar a mensagem e processá-la antes que eu pudesse ver um erro.
Por isso, investiguei se é possível chamar o código de serviço diretamente com um arquivo XML local para testes um pouco mais rápidos e descobri que é possível. E não só isso, é muito simples de fazer e, na verdade, fornece mensagens de erro muito mais significativas.
O trabalho de exemplo abaixo lê um arquivo XML local e tenta usá-lo com a classe AxdCustomer (que é a classe de documento usada pelo serviço CustCustomer) para criar um cliente. Você pode fazer trabalhos semelhantes para todas as outras classes de documento, por exemplo AxdSalesOrder, se precisar.
{
FileNameOpen fileName = @'C:\\TestCustomerCreate.xml';
AxdCustomer customer;
AifEntityKey key;
#File
;
new FileIoPermission(fileName, #IO_Read).assert();
customer = new AxdCustomer();
key = customer.create( XmlDocument::newFile(fileName).xml(),
new AifEndpointActionPolicyInfo(),
new AifConstraintList());
CodeAccessPermission::revertAssert();
info('Done');
}
O objeto AifEntityKey retornado pelo método customer.create() (que corresponde à operação de serviço "create" no AIF) contém informações sobre qual cliente foi criado, entre outras coisas, o RecId do registro CustTable criado.
Se o que você está tentando testar é uma porta de saída ou se você só precisa de um exemplo de como o XML deve ficar na porta de entrada, você também pode usar a classe de documento para exportar um cliente para um arquivo chamando o método read() (correspondente à operação de serviço "read"), assim:
{
FileNameSave fileName = @'C:\\TestCustomerRead.xml';
Map map = new Map( Types::Integer,
Types::Container);
AxdCustomer customer;
AifEntityKey key;
XMLDocument xmlDoc;
XML xml;
AifPropertyBag bag;
#File
;
map.insert(fieldNum(CustTable, AccountNum), ['123456']);
key = new AifEntityKey();
key.parmTableId(tableNum(CustTable));
key.parmKeyDataMap(map);
customer = new AxdCustomer();
xml = customer.read(key,
null,
new AifEndpointActionPolicyInfo(),
new AifConstraintList(),
bag);
new FileIoPermission(fileName, #IO_Write).assert();
xmlDoc = XmlDocument::newXml(xml);
xmlDoc.save(fileName);
CodeAccessPermission::revertAssert();
info('Done');
}
É claro que você deve substituir '123456' pelo número da conta do cliente que deseja ler.