Adapter Specific Message Attributes (ASMA) – dynamiczna konfiguracja parametrów kanałów komunikacji

Podstawową funkcją mapowań w SAP PI jest budowanie zawartości docelowego komunikatu w oparciu o dane zawarte w komunikacie źródłowym. Parametry techniczne, takie jak np. nazwa pliku, ścieżka, adres serwera, konfiguruje się zwykle w kanale komunikacji.

Czasem jednak zachodzi potrzeba dynamicznego ustawienia tych parametrów w mapowaniu – również w zależności od przesyłanych danych. Dla najprostszych przypadków (jak zmiana nazwy docelowego pliku), można skorzystać z mechanizmu Variable Substitution, jednak o wiele większe możliwości daje funkcja ASMA (Adapter-Specific Message Attributes).

Dla większości adapterów istnieje zestaw atrybutów kanału komunikacji, który można zdefiniować w nagłówku komunikatu PI korzystając z obiektów konfiguracji dynamicznej (Dynamic Configuration). Dla poszczególnych atrybutów można włączyć konfigurację dynamiczną z ASMA w zakładce Advanced ustawień kanału komunikacji:

Adapter Specific Message Attributes (ASMA)

Adapter Specific Message Attributes (ASMA)

Konfiguracja dynamiczna ASMA w funkcjach użytkownika Java (UDF)

Atrybuty komunikatu w konfiguracji dynamicznej można ustawić za pomocą własnych funkcji użytkownika – UDF (User-Defined Functions). Każda definiowana przez użytkownika funkcja standardowo otrzymuje obiekt Container. Za pomocą jego metod, można pobrać obiekt konfiguracji dynamicznej:

[codesyntax lang=”java”]

DynamicConfiguration conf = (DynamicConfiguration) container
 .getTransformationParameters()
 .get(StreamTransformationConstants.DYNAMIC_CONFIGURATION);

[/codesyntax]

Kolejnym krokiem jest utworzenie par klucz – wartość dla każdego konfigurowanego atrybutu. Należy przy tym pamiętać o przestrzeni nazw właściwej dla danego typu kanału komunikacji. Przykładowe atrybuty dostępne dla wybranych kanałów komunikacji:


 

File Adapter (pliki) – przestrzeń nazw: http://sap.com/xi/XI/System/File

  • FileName – nazwa pliku
  • Directory – katalog
  • TargetTempFileName – nazwa tymczasowego pliku (jeśli jest używany)

 

Mail Adapter (e-mail) – przestrzeń nazw: http://sap.com/xi/XI/System/Mail

  • THeaderFROM – nadawca
  • THeaderTO – odbiorca
  • THeaderCC – odbiorca kopii (DW)
  • THeaderBCC – odbiorca ukrytej kopii (UDW)
  • THeaderSUBJECT – tytuł e-maila

 

JMS Adapter – przestrzeń nazw: http://sap.com/xi/XI/System/JMS

  • DCJMSCorrelationID – Correlation ID
  • DCJMSMessageID – Message ID
  • DCJMSMessageQueue – Message Queue

HTTP Adapter – przestrzeń nazw: http://sap.com/xi/XI/System/HTTP

  • URL

Znając nazwę klucza i przestrzeń nazw, klucz tworzymy następującą metodą:

[codesyntax lang=”java”]

DynamicConfigurationKey key = DynamicConfigurationKey.create(
 “http://sap.com/xi/XI/System/File”,
 “FileName”);

[/codesyntax]

Pozostaje przypisanie pary klucz – wartość do konfiguracji dynamicznej. W poniższym przykładzie funkcja UDF ustawia atrybut – nazwę pliku – w oparciu o wejściowy ciąg znaków (parametr filename):

Adapter Specific Message Attributes (ASMA)

Adapter Specific Message Attributes (ASMA)

Listę atrybutów, jakie można ustawić dynamicznie dla danego kanału komunikacji, można znaleźć na stronie Using Adapter-Specific Message Attributes in the Message Header, przechodząc do interesującego nas typu kanału komunikacji, w sekcji Define Adapter-Specific Message Attributes.

Konfiguracja dynamiczna w mapowaniach XSLT

Alternatywą dla funkcji Java (UDF) w celu ustawienia atrubutów kanału komunikacji w konfiguracji dynamicznej, są mapowania XSLT. Mechanizm ten jest opisany w pomocy SAP na stronie XSLT Mapping of Adapter-Specific Message Attributes.

Zastosowanie

Dzięki temu, że konfiguracja dynamiczna jest dostępna z poziomu mapowania, otwierają się szerokie możliwości programowego ustawienia atrybutów kanału komunikacji. Możliwe zastosowania nie ograniczają się do przykładów:

  • ustawienie docelowego katalogu w zależności od numeru zakładu, składu SAP
  • wpisanie numeru zamówienia, faktury lub klienta w nazwie pliku
  • ustawienie odbiorcy e-maila wg adresu w komunikacie źródłowym
  • ustawienie tematu e-maila w zależności od zawartości komunikatu
  • dynamiczna budowa URL docelowej usługi HTTP

User Defined Functions – własne funkcje w mapowaniach SAP PI

User Defined Functions (UDF) to funkcje zdefiniowane przez programistę, które mogą być wykorzystywane w mapowaniach graficznych SAP PI. Funkcje te definiowane są w języku Java i umożliwiają uruchomienie dowolnego kodu na etapie mapowania pól komunikatów XML, znacznie rozszerzając zakres operacji, jakie można wykonać na polach i wartościach komunikatu.

W mapowaniach graficznych UDF reprezentowane są przez jeden blok. Dzięki im wykorzystaniu, można przykładowo uprościć realizację stosunkowo prostej logiki, której implementacja wymagałaby użycia dużej liczby standardowych bloków:

udf-01

UDF tworzy się przez kliknięcie w ikonę czystej kartki w lewym dolnym rogu edytora mapowań graficznych:

udf-02

W najprostszym wariancie wystarczy uzupełnić podstawowe dane – nazwę i etykietę funkcji, oraz nazwę argumentów wejściowych. Wartość argumentów będzie można przypisywać podobnie jak w przypadku standardowych bloków mapowania graficznego – za pomocą strzałek na wejściu i wyjściu funkcji:

udf-02a

Kolejnym krokiem jest implementacja funkcji w języku Java. Wejście i wyjście jest realizowane jak w innych funkcjach / metodach Java – poprzez argumenty i polecenie return. Na poniższej ilustracji znajduje się definicja UDF o takim samym działaniu jak na przykładzie mapowania graficznego powyżej.

udf-03

Parametry UDF

Wartości konfiguracyjne można określić jako parametry UDF. Będą również przekazywane do funkcji jak argumenty, lecz ich wartość przypisuje się na poziomie mapowania graficznego.

udf-04

udf-05

Testowanie UDF

Po zapisaniu funkcji, można jej użyć w mapowaniu graficznym, podłączając wejścia i wyjście. Podobnie jak w przypadku standardowych bloków, po uruchomieniu testu można prześledzić listę podawanych i zwracanych przez UDF wartości za pomocą funkcji Display Queue:

udf-06

W powyższym przykładzie UDF została wykorzystana do uproszczenia implementacji mapowania. W zależności od potrzeb, programista może wykorzystać szereg możliwości języka Java, które pozwolą na implementację bardziej złożonych mapowań, niż pozwalają na to standardowe bloki mapowania graficznego.

Przegląd nowych funkcji w SAP Process Integration 7.31

Ograniczenia wcześniejszych wersji: SAP PI 7.11

  • Adaptery Idoc oraz HTTP nie są dostępne dla Integrated Configuration
  • Mapowanie jednego komunikatu do wielu (1:n) nie jest możliwe w ICO
  • Reguły routingu na podstawie zawartości komunikatu nie mogą być użyte w ICO

Nowe mozliwości połączeń dla Advanced Adapter Engine

IDOC_AAE

  • Przesyłanie wielu Idoców jednocześnie (Idoc packaging), ale nie dla interfejsów wychodzących
  • Moduły adaptera mogą być dodane dla konfiguracji dla Idoców
  • Wsparcie dla ALEAUDIT

HTTP_AAE

  • Nowe funkcje: POST and Multipart document

SFTP adapter

  • dodatek dostępny od wersji PI 7.11 SP08

Ulepszenia dla Integrated Configuration

Mapowanie jeden do wielu możliwe w ICO

  • mapowanie 1:n
  • Reguły routingu na podstawie zawartości komunikatu przychodzącego

PI 7.31 ICO Multimapping

Narzędzia do monitorowania 

  • Monitoring komunikatów Idoc (zastępuje transakcję IDX5)

PI 7.31 Idoc Monitor

  • Monitoring metadanych

PI 7.31 Metadata Monitor

  • Nowy monitoring komunikatów

PI 7.31 Message Monitor

 

  • Opcja ‚Ping’ dla kanału komunikacyjnego
    • Sprawdzenie połączenia
    • Użytkownik/hasło
    • Uprawnienia (np. dostęp do FTP)
    • Ustawienia zapory sieciowej

PI 7.31 Ping 1

 

PI 7.31 Ping 2

Wyszukiwanie komunikatów po zawartości

  • Nie ma potrzeby użycia TREX
  • Zazwyczaj używane do przeszukiwania po polach kluczowych (Numer zamówienia, Numer partnera)
  • Osobne filtry definiowane dla poszczególnych interfejsów
  • Pozwala na przeszukiwanie dla klucza zdefiniowanego jako:
    • XPATH

      XPATH

    • Dynamic Header

      Dynamic Header

  • Indeksowanie jest możliwe dla komunikatów przetworzonych przed zdefiniowaniem filtra
  • Indeks jest usuwany kiedy komunikat jest zarchiwizowany

 

 

Konfiguracja połączenia IDOC_AAE dla PI 7.31 single stack

1. Ustalenie danych dla GatewayHostGatewayService 

  • Nalezy zalogować się do SLD i wybrać Administration -> Settings zakładka Parameters i tam z rozwijanej listy All:

SLD Gateway PI/PO 7.31 single stack

2. Utworzenie połączeń RFC do systemu SAP, z którego będą wysyłane Idoci

  • Po zalogowaniu się do SAP NetWeaver Administrator (NWA) należy przejść do Configuration -> Infrastructure -> Destinations

SAP NWA Destinations

 

  • Parametry połączenia:

Hosting System: Local Java System PID
Destination Name: XI_IDOC_DEFAULT_DESTINATION
Destination Type: RFC

SAP NWA Destinations step 1

 

W kolejnych krokach należy podać parametry połączenia do systemu SAP oraz dane logowania:

SAP NWA Destinations step 2

 

Aby upewnić się, że połączenie działa prawidłowo można skorzystać z opcji Ping Destination. Test powinien zakończyć się komunikatem Successfully connected to system <PID> as user <user>

Ping destination

3. Utworzenie połączenia JCo (Java Connector)

  • Po zalogowaniu się do SAP NetWeaver Administrator (NWA) należy przejść do Configuration -> Infrastructure -> Jco RFC Provider

JCo RFC Provider

 

  • Należy utworzyć nowe połączenie korzystając z opcji Create, parametry w pierwszym kroku:

Program ID: XI_IDOC_DEFAULT_PID
Gateway Host: z punktu 1
Gateway Service: z punktu 1

JCo step 1

 

  • W kolejnym kroku należy podać nazwę połączenia z punktu 2., w tym przypadku XI_IDOC_DEFAULT_DESTINATION

JCo step 2

 

Po zapisaniu należy uruchomić połączenie korzystając z opcji Start, prawidłowy komunikat to JCo servers started

4. Wprowadzenie parametrów dla Resource Adapter inboundRA

  • Po zalogowaniu się do SAP NetWeaver Administrator (NWA) należy przejść do Configuration -> Infrastructure -> Application Resources i przefiltrować listę zasobów po *inboundRA*

Resource Adapter step 1

  • W zakładce Properties należy wprowadzić następujące wartości lub upewnić się, że takie są tam już obecne:

GatewayServer – tak jak w punkcie 1.
ProgramID – tak jak w punkcie 3. – XI_IDOC_DEFAULT_PID
MaxReaderThreadCount – wartość pomiędzy 5 a 10
DestinationName – tak jak w punkcie 2. – XI_IDOC_DEFAULT_DESTINATION
GatewayService – tak jak w punkcie 1. – sapgw01
Local – true
BindingKey – PI_AAE_IDOC

Resource Adapter step 2

  • Po zapisaniu parametrów należy uruchomić aplikację: More Actions -> Start Applications i wybrać z listy com.sap.aii.adapter.idoc.sapjra.inboundRA

Resource Adapter step 3

5. Utworzenie połączenia RFC w systemie SAP wysyłającym Idoci do PI

  • W transakcji SM59 należy utworzyć nowe połączenie typu (T) TCP/IP Connection używając parametrów:

Activation Type: Registered Server Program
Program ID: tak jak w punkcie 3. – XI_IDOC_DEFAULT_PID
Gateway Host: tak jak w punkcie 1.
Gateway Service: tak jak w punkcie 1. – sapgw01

SM59 TCP/IP Connection

 

SM59 TCP/IP Connection

 

  • Po przetestowaniu połączenia powinien się pojawić komunikat:

SM59 RFC connection test

 

6. Utworzenie kanału komunikacyjnego na PI

  • W odróżnieniu do konfiguracji Idoc dla Integration Engine (ABAP) wymagany jest kanał komunikacyjny typu Sender, który będzie użyty w Integrated Configuration. 
  •  Parametr RFC Server Parameters należy ustawić na Default, a w Ack Destination podać połączenie z punktu 2. – XI_IDOC_DEFAULT_DESTINATION

Idoc_AAE sender channel

 

Po wykonaniu powyższych kroków system PI jest przygotowany na konfigurację scenariuszy dla Idoców przychodzących.

W trakcie tworzenia poradnika wykorzystane zostały informacje dostępne na stronach help.sap.com oraz scn.sap.com

Mapowanie XSLT do pliku płaskiego

W niektórych sytuacjach wymagane jest przesłanie pliku wynikowego jako płaskiego o określonej długości każdego pola. W przypadku adaptera plikowego można z powodzeniem skorzystać z File Content Conversion, jednak w przypadku na przykład wywołania usługi sieciowej najlepszym rozwiązaniem będzie przekształcenie XSLT. Dla przykładowego pliku wejściowego:

[codesyntax lang=”xml” lines=”normal”]

<Order>
   <Header>
      <DocumentNumber>001</DocumentNumber>
      <Date>20140401</Date>
   </Header>
   <Line>
      <ItemNumber>1</ItemNumber>
      <Material>1203040</Material>
      <Quantity>10</Quantity>
      <UOM>PCE</UOM>
   </Line>
   <Line>
      <ItemNumber>2</ItemNumber>
      <Material>2349040</Material>
      <Quantity>20</Quantity>
      <UOM>PCE</UOM>
   </Line>
</Order>

[/codesyntax]

Po zastosowaniu transformacji tworzącej nową linię dla każdego powtórzenia elementu <Line> i ustawiającej długości każdego pola na odpowiednio 20, 20, 3, 20, 5, 5:
[codesyntax lang=”xml” lines=”normal”]

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
   <xsl:output method="text" indent="yes" encoding="UTF-8" />
   <xsl:variable name="DocumentNumber">
      <xsl:call-template name="padRightSide">
         <xsl:with-param name="stringToPad" select="Order/Header/DocumentNumber" />
         <xsl:with-param name="totalLength" select="20" />
      </xsl:call-template>
   </xsl:variable>
   <xsl:variable name="Date">
      <xsl:call-template name="padRightSide">
         <xsl:with-param name="stringToPad" select="Order/Header/Date" />
         <xsl:with-param name="totalLength" select="20" />
      </xsl:call-template>
   </xsl:variable>
   <xsl:template match="/Order">
      <xsl:for-each select="Line">
         <!-- Repeat header data -->
         <xsl:copy-of select="$DocumentNumber" />
         <xsl:copy-of select="$Date" />
         <!-- Item data -->
         <xsl:call-template name="padRightSide">
            <xsl:with-param name="stringToPad" select="ItemNumber" />
            <xsl:with-param name="totalLength" select="3" />
         </xsl:call-template>
         <xsl:call-template name="padRightSide">
            <xsl:with-param name="stringToPad" select="Material" />
            <xsl:with-param name="totalLength" select="20" />
         </xsl:call-template>
         <xsl:call-template name="padRightSide">
            <xsl:with-param name="stringToPad" select="Quantity" />
            <xsl:with-param name="totalLength" select="5" />
         </xsl:call-template>
         <xsl:call-template name="padRightSide">
            <xsl:with-param name="stringToPad" select="UOM" />
            <xsl:with-param name="totalLength" select="5" />
         </xsl:call-template>
         <!-- End Line -->
         <xsl:text />
      </xsl:for-each>
   </xsl:template>
   <xsl:template name="padRightSide">
      <xsl:param name="totalLength" />
      <xsl:param name="padChar" select="' '" />
      <xsl:param name="stringToPad" />
      <xsl:param name="padBuffer" select="concat($padChar,$padChar,$padChar,$padChar,$padChar, $padChar,$padChar,$padChar,$padChar,$padChar )" />
      <xsl:variable name="vNewString" select="concat($stringToPad, $padBuffer)" />
      <xsl:choose>
         <xsl:when test="not(string-length($vNewString) &gt;= $totalLength)">
            <xsl:call-template name="padRightSide">
               <xsl:with-param name="stringToPad" select="$vNewString" />
               <xsl:with-param name="totalLength" select="$totalLength" />
               <xsl:with-param name="padChar" select="$padChar" />
               <xsl:with-param name="padBuffer" select="$padBuffer" />
            </xsl:call-template>
         </xsl:when>
         <xsl:otherwise>
            <xsl:variable name="output">
               <xsl:value-of disable-output-escaping="no" select="substring($vNewString,1,$totalLength)" />
            </xsl:variable>
            <xsl:value-of select="$output" />
         </xsl:otherwise>
      </xsl:choose>
   </xsl:template>
</xsl:stylesheet>

[/codesyntax]

otrzymujemy:
001 20140401 1 1203040 10 PCE
001 20140401 2 2349040 20 PCE