ODI-Prozesse per Webservice z.B. von APEX aus starten


Ziel

Bei Nutzung des ODI ist es hilfreich, ODI-LoadPlans etc. aus einer Anwendung heraus starten zu können. Mit APEX und ODI-Webservices (WS) ist das ganz einfach.

Techn. Voraussetzungen - ODI

Im ODI muss der entsprechende Webservice eingerichtet und URL, User und PWD des WS bekannt sein.

Techn. Umsetzung - APEX

 In APEX selbst erfolgt der eigentliche Aufruf über eine PL-Procedure:
#OWNER#.ODI_RUN.LP_DAM18_LOADER(P_PARTITION_KEY => :P3_PARTITION_KEY);

Techn. Umsetzung - PL - Bau des WS-Envelope

In dieser Proc wird zu einen der Aufruf des Webservices erstellt:
Webservice-Call:
-- *** WS-Call bauen ***
-- Anfang (Kopf/Head)
  c_req_head :=             '<?xml version = ''1.0'' encoding = ''UTF-8''?>';
  c_req_head := c_req_head||'<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://www.w3.org/2005/08/addressing" xmlns:ns2="xmlns.oracle.com/odi/OdiInvoke/">';
  c_req_head := c_req_head||'   <env:Header>';
  c_req_head := c_req_head||'      <ns1:MessageID>uuid:29ad8d20-291d-4f67-aeb1-e24a963a63f1</ns1:MessageID>';
  c_req_head := c_req_head||'      <ns1:Action>xmlns.oracle.com/odi/OdiInvoke/invokeStartLoadPlan</ns1:Action>';
  c_req_head := c_req_head||'      <ns1:To>>'||c_ODI_WEBSERVICE_URL||'</ns1:To>';
  c_req_head := c_req_head||'   </env:Header>';
  c_req_head := c_req_head||'   <env:Body>';
  c_req_head := c_req_head||'      <ns2:OdiStartLoadPlanRequest>';
  c_req_head := c_req_head||'         <Credentials>';
  c_req_head := c_req_head||'            <OdiUser>'|| c_ODI_WS_USR ||'</OdiUser>';
  c_req_head := c_req_head||'            <OdiPassword>'|| c_ODI_WS_USR_PWD ||'</OdiPassword>';
  c_req_head := c_req_head||'            <WorkRepository>'|| c_ODI_WORKREP ||'</WorkRepository>';
  c_req_head := c_req_head||'         </Credentials>';

-- eigentlicher LP-Aufruf
  <StartLoadPlanRequest>
    <LoadPlanName>Name ODI-LoadPlan, z.B. 
      LP_LOADER</LoadPlanName>
    <Context>Name ODI-CONTEXT</Context>
    <Keywords>KEYWORDS oder leer</Keywords>
    <LogLevel>ODI-LOGLEVEL</LogLevel>
-- ggfs mehrfach
    <LoadPlanStartupParameters>
      <Name>Name der ODI-Variable z.B. DAM18.V_QUARTAL</Name>
      <Value>Wert der Variable</Value>
    </LoadPlanStartupParameters>
  </StartLoadPlanRequest>

-- Abschluss (Footer)
  c_req_foot := c_req_foot||'      </ns2:OdiStartLoadPlanRequest>';
  c_req_foot := c_req_foot||'   </env:Body>';
  c_req_foot := c_req_foot||'</env:Envelope>';


Aus c_req_head||c_req_Content||c_req_foot wird der eigentliche Envelope (hier: p_req_text) zusammengefügt.

Die benötigten Variablen sind wie folgt definiert:
-- WebService-Call
  c_req_head   varchar2(32767);
  c_req_foot   varchar2(32767);

Die Parameter zum Webservice können umgebungsabhängig in einer Konfig-Tabelle hinterlegt..
-- Konstanten
  c_DB_NAME  K_UMGEBUNG.DB_NAME%type;
  c_ODI_WEBSERVICE_URL  K_UMGEBUNG.ODI_WEBSERVICE_URL%type;
  c_ODI_WS_USR  K_UMGEBUNG.ODI_WS_USR%type;
  c_ODI_WS_USR_PWD  K_UMGEBUNG.ODI_WS_USR_PWD%type;
  c_ODI_WORKREP  K_UMGEBUNG.ODI_WORKREP%type;

…und entsprechend abgefragt werden:
-- Parameter für aktuelle Umgebung ermitteln 
  select   DB_NAME,   ODI_WEBSERVICE_URL,   ODI_WS_USR,   ODI_WS_USR_PWD,   ODI_WORKREP
    into c_DB_NAME, c_ODI_WEBSERVICE_URL, c_ODI_WS_USR, c_ODI_WS_USR_PWD, c_ODI_WORKREP
    from K_UMGEBUNG
    join v$instance on (db_name = instance_name);


Techn. Umsetzung - PL - Aufruf Webservice

Weiters erfolgt in der PL-Proc der eigentliche Webserviceaufruf:


  v_req := utl_http.begin_request ( c_ODI_WEBSERVICE_URL || '?wsdl', 'POST', 'HTTP/1.1');
  utl_http.set_header (v_req, 'Content-Type', 'text/xml; charset=UTF-8');
  utl_http.set_header (v_req, 'Content-Length', LENGTH (p_req_text));
  utl_http.set_header (v_req, 'SOAPAction', 'xmlns.oracle.com/odi/OdiInvoke/invokeStartLoadPlan');
     
  utl_http.write_text (v_req, p_req_text);

  v_res := utl_http.get_response (v_req);
  utl_http.read_text (v_res, v_res_text);
  utl_http.end_response (v_res); 
 
  -- Response auswerten
  if instr(v_res_text, 'faultstring') > 0 then
    -- Fehler aufgetreten
      log(c_Modul, '*** Fehler ***');
      log(c_Modul, v_res_text);
    else
    -- kein Fehler
      log(c_Modul, 'ok');

  end if;

Die benötigten Variablen sind wie folgt definiert:
  v_req utl_http.req;
  v_res utl_http.resp;
  v_res_text VARCHAR2 (32767);


Fazit

Mit diesen Schritten lassen sich sehr elegant z.B. aus APEX heraus beliebige ODI-Prozesse anstarten, wodurch ein Fachbereich sehr flexibel und autark arbeiten kann.



Kommentare

Beliebte Posts aus diesem Blog

PGA unter Oracle 11g

trunc(sysdate) - nette Spiele mit dem Datum

Datapump - Verzeichnis erstellen