Cookbook: XI 2.0 Inboundproxy

Posten Sie hier Tutorials & Cookbooks.
1 Beitrag • Seite 1 von 1
1 Beitrag Seite 1 von 1

Cookbook: XI 2.0 Inboundproxy

Beitrag von Azreal (Specialist / 181 / 1 / 0 ) » 16.05.2005 19:37
Folgender Guide soll die Welt des XI - genauer die Inbound Proxys der an XI angeschlossenen Systeme - etwas näher bringen. Das am Ende dieses Beitrages angehängte Coding simuliert einen Proxyaufruf vergleichbar mit dem Testreport SPRX_TEST_INBOUND. Der Vorteil dieses Reports ist jedoch, daß man die Möchkeit hat alle Eingaben im Vorraus zu definieren. Sodaß ein beherzter click auf den 'ausführen? Button reicht um die XML seiner Wahl in das System zu jagen.

Meine Intension dahinter war einfach die Tatsache, daß ich es Leid war bei der Implementierung eines Inboundproxys immer die gleichen Angaben in der SPRX_TEST_INBOUND machen zu müssen (auch eine Variante anzulegen war mir zu - naja). Zudem mußte ich damals andauernd in den Debugger springen und das Sendende System setzten (diese Funktion wird von dem Standardtestreport nicht unterstützt) Und wie es sich für einen Programmierer gehört ist dann folgender Report dabei herausgekommen.

Der Report gliedert sich im Grunde in vier Teile.
1. XML-String erstellen
Per concatenate wird hier das XML zusammengebastelt. Als Vorlage diente mir ein Original aus der SXMB_MONI. Gewisse Platzhalter lassen auch eine Generik zu. z.B. wie folgt:

Code: Alles auswählen.

CONCATENATE l_xml_string '<ns1:Vorname>' lv_name '</Vorname>' INTO l_xml_string.
Der konkatinierte String muß nun in einen RAW string umgewandelt werden. Am einfachsten geht das mittels folgender Klasse CL_ABAP_CONV_OUT_CE.

2. XML 2 ABAP Mapper
Im zweiten Schritt kommt der XML 2 ABAP mapper. Die Daten liegen derzeit ja im XML-Format vor. Innerhalb eines Proxies sind diese jedoch in einer generierten komplexen Struktur. Gemapped wird das ganze durch generiertes XSLT Mapping. Wie das Mapping aussehen soll zieht wird über das IFR ermittelt. Dazu ist es notwendig Namespace und Interface das aufgerufen werden soll zu nennen:

Code: Alles auswählen.

* Namespace des empfangenden Interfaces
lv_receiver-interface-namespace = 'XYZ_interface_namespace'.
* Empfangendes interface
lv_receiver-interface-name = 'XYZ_interface_name'.
Entegen der sonst allgemeingltigen ABAP Zeichenkettenpolitik muß man hier die kompletten Namen nicht in Großbuchstaben schreiben, da diese Informationen vom IFR kommen und da dies Java ist wird nicht so auf Groß/Kleinschreibung geachtet.

Mit folgender Zeile werden die informationen über den Proxy gezogen:

Code: Alles auswählen.

lo_registry = cl_proxy_inbound_registry=>create_from_ifr_name( p_interface  = lv_receiver-interface ).
Danach wird das passende XSLT gesucht:

Code: Alles auswählen.

lo_xslt = cl_proxy_stylesheet_runtime=>create_from_method
Existiert kein Mapping (z.B. beim Erstaufruf), dann wird schnell eins generiert:

Code: Alles auswählen.

lo_xslt->generate( ).
Nicht wundern, wenn das Mapping in der SE80 bei euren lokalen Objekten auftaucht - Das XSLT scheint immer bei dem User zu liegen der als erster die Codingzeilen durchläuft.

Danach wird aus den Interfacedaten noch die ABAPStruktur initialisiert. Und letztendlich wird Mapping mittels CALL TRANSFORMATION durchgeführt.

3. Senderparty festlegen
Das ist der Punkt, an dem SPRX_TEST_INBOUND nicht mithalten kann *g* Im Grunde werden hier die Daten für den Proxy vorbereitet. Das Object lo_controller bekommt die XML Nachricht und das Business System zugeschoben (hier wird der SLD name des Businessystems verwendet). Die Tabelle lt_parameters enthält dann die Parameter für den Proxy selbst.

4. Proxy aufrufen
Im letzten Schritt wird dann der Proxy gerufen. Proxytypisch komplett dynamisch ;):
Zuerst den methoden namen zusammenbasteln:

Code: Alles auswählen.

        CONCATENATE lo_registry->object_name lo_registry->object_name1 INTO l_method SEPARATED BY '~'.
und dann den dynamischen call mit unserer parametertabelle:

Code: Alles auswählen.

        CALL METHOD (lo_registry->implementing_class)=>(l_method)
          PARAMETER-TABLE
            lt_parameters.
Der Rest ist Errorhandling. Um so allgmein wie möglich zu bleiben fange ich hier alle Fehler zu zur cx_root Fehlerklasse ab.

Eine Letzte Anmerkung habe ich noch: Ihr solltet euch nicht wundern, wenn dieser Report keine Eintrag in der SXMB_MONI hinterlässt. Ich hab mich hier nur auf das wesentliche beschränkt ;)

Viel Spaß noch!

Gruß Azreal

Code: Alles auswählen.

DATA: lv_error TYPE string VALUE 'success ;)'.

DATA: lo_exception TYPE REF TO cx_root.

DATA: l_conv         TYPE REF TO cl_abap_conv_out_ce,
      l_xml_string   TYPE string,
      l_xml_xstring  TYPE xstring.

***************** 1. * XML-String erstellen **************
CONCATENATE l_xml_string '<?xml version="1.0" encoding="utf-8"?>' INTO l_xml_string.
CONCATENATE l_xml_string '<ns1:XYZ xmlns:ns1="http://..." xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">' INTO l_xml_string.
CONCATENATE l_xml_string '</ns1:XYZ>' INTO l_xml_string.

* XML-String in raw mappen
l_conv = cl_abap_conv_out_ce=>create( encoding = 'UTF-8' ).
l_conv->write( data = l_xml_string ).
l_xml_xstring = l_conv->get_buffer( ).

***************** 2. * XML 2 ABAP Mapper **************
DATA: lt_send_bindings TYPE abap_trans_resbind_tab,
      ls_binding       TYPE abap_trans_resbind,
      ls_parameter     TYPE abap_parmbind,
      lt_parameters    TYPE abap_parmbind_tab.

TYPES: BEGIN OF rmdata,
         bindings TYPE abap_trans_resbind_tab,
         stylesheet TYPE cxsltdesc,
       END OF rmdata.

DATA: ls_rmdata    TYPE rmdata,
      lt_signature TYPE sproxsigtt,
      lo_xslt      TYPE REF TO cl_proxy_stylesheet_runtime,
      lo_registry  TYPE REF TO cl_proxy_inbound_registry,
      lv_receiver TYPE prx_srvc.

FIELD-SYMBOLS: <sig> TYPE sproxsig.

* Namespace des empfangenden Interfaces
lv_receiver-interface-namespace = 'XYZ_interface_namespace'.
* Empfangendes interface
lv_receiver-interface-name = 'XYZ_interface_name'.

TRY.
    TRY.
* Registry object interface aus repository ziehen.
        lo_registry = cl_proxy_inbound_registry=>create_from_ifr_name( p_interface  = lv_receiver-interface ).

* Stylesheet vom Proxy ziehen.
        lo_xslt = cl_proxy_stylesheet_runtime=>create_from_method(
                             p_object   = lo_registry->object
                             p_obj_name = lo_registry->object_name
                             p_method   = lo_registry->object_name1
                             p_extended_xml_handling = '').
        IF lo_xslt->check_timestamp( ) = ''.
* ABAP 2 XML mapping generieren
          lo_xslt->generate( ).
        ENDIF.
        ls_rmdata-stylesheet = lo_xslt->abap2xml_name.

* initialisieren der ABAP Struktur
        lt_signature = lo_xslt->get_signature( ).
        LOOP AT lt_signature ASSIGNING <sig>.
          ls_binding-name     = <sig>-param.
          CREATE DATA ls_binding-value TYPE (<sig>-typename).
          IF <sig>-decl = sprox_const_dir_importing.
            APPEND ls_binding TO lt_send_bindings.
          ELSEIF <sig>-decl = sprox_const_dir_exporting.
            APPEND ls_binding TO ls_rmdata-bindings.
          ELSEIF <sig>-decl = sprox_const_dir_changing.
            APPEND ls_binding TO lt_send_bindings.
            APPEND ls_binding TO ls_rmdata-bindings.
          ENDIF.
          ls_parameter-name  = <sig>-param.
          ls_parameter-value = ls_binding-value.
          INSERT ls_parameter INTO TABLE lt_parameters.
        ENDLOOP.

* XML auf ABAP mappen
        CALL TRANSFORMATION (lo_xslt->xml2abap_name)
                              SOURCE XML l_xml_xstring
                              RESULT (lt_send_bindings).
      CATCH cx_root.
        lv_error = 'Unable to transform XML'.
    ENDTRY.

***************** 3. * Senderparty festlegen **************
    TRY.
        DATA: lo_controller  TYPE REF TO if_ai_proxy_controller.
        CLASS cl_ai_factory DEFINITION LOAD.
        CLASS cl_ai_posting_controller DEFINITION LOAD.
        lo_controller = cl_ai_posting_controller=>create_controller( ).
*   XML anh㭧en
        lo_controller->set_input_payload( l_xml_xstring ).
*   Name des empfangenden Systems setzten
* 	Empf㭧ersystem festlegen (SLD_NAME)
				lv_receiver-bsn_system = 'SLD_NAME'.
        lo_controller->set_sender_service( lv_receiver ).

*   Controller in parameterliste hinzufügen
        DATA: lo_appl_controller   TYPE REF TO if_ai_posting_controller.
        ls_parameter-name = 'CONTROLLER'.
        lo_appl_controller ?= lo_controller.
        GET REFERENCE OF lo_appl_controller INTO ls_parameter-value.
        INSERT ls_parameter INTO TABLE lt_parameters.
      CATCH cx_root.
        lv_error = 'Unable to fill controller'.
    ENDTRY.
***************** 4. * Proxy aufrufen **************
    TRY.

        DATA: l_method TYPE string.
* Proxy aufrufen
        CONCATENATE lo_registry->object_name lo_registry->object_name1 INTO l_method SEPARATED BY '~'.
        CALL METHOD (lo_registry->implementing_class)=>(l_method)
          PARAMETER-TABLE
            lt_parameters.


      CATCH cx_root INTO lo_exception.
* Problem bei der Verarbeitung:...
        DATA: lv_order_fault TYPE REF TO cx_sus_order_fault.
        DATA: lv_fult TYPE REF TO cx_sy_no_handler.
        DATA: test TYPE REF TO cx_root.

        FIELD-SYMBOLS: <lv_test> TYPE REF TO cx_root.
        ASSIGN lo_exception->previous TO <lv_test>.

        lv_order_fault ?= <lv_test>.
        lv_error = lv_order_fault->standard-fault_text.

    ENDTRY.
  CATCH cx_root.
ENDTRY.

WRITE: lv_error.


Seite 1 von 1

Über diesen Beitrag

Azreal
Unterstütze die Community und teile den Beitrag für mehr Leser und besseren Inhalt:

Vergleichbare Themen

Cookbook: 'REUSE_ALV_GRID_DISPLAY' Wie man ihn benutzt?!
von Azreal » 25.06.2004 15:34