Oracle EBS Service Invocation Framework (Business Events – SIF)
Merhaba,
Bu yazıda, Oracle EBS üzerinde iş olaylarını kullanarak web servis çağırma yöntemini aktaracağım. Servislerin çağrılması için kullanılan framework adı literatürde Service Invocation Framework (SIF) olarak geçmektedir. Bu framework, iş olayları üzerine kuruludur. Dolayısıyla uygulama üzerinde iş olay tanımı ve ilgili olaya ait abonelik tanımlarının yapılması gerekmektedir. Bu tanımlamalar tamamlandıktan sonra Pl/Sql, Workflow veya Java kullanarak iş olayını başlatabiliriz.
Detaylı bilgiye aşağıdaki adresten ulaşabilirsiniz.
https://docs.oracle.com/cd/E18727_01/doc.121/e12169/T511175T513090.htm
Web Servis çağrı talebi ve dönen cevabı için birer adet olmak üzere minimumda toplam iki adet iş olayının tanımlanması gerekir.
Talep İş Olayı
1.E-Business Suite sistemine giriş yapılır. “Workflow Administrator Web (New) -> Administrator Workflow” altında “Business Events” ekran fonksiyonu seçilir.
2. “Create Event” butonu ile iş olayı yaratma ekranı açılır.
3. İş olayının oluşturma formunda gerekli bilgiler aşağıdaki gibi doldurulur.
4. Oluşturduğumuz İş olayı aratılır ve “Subscription” ikonuna tıklanır. Talep iş olayı için iki adet abonelik tanımlanacaktır. Birincisi servisi çağırmak için tanımlanırken ikincisi ise hata durumunda WFERROR iş akışını başlatmak için kullanılır.
5. “Create Subscription” butonuna tıklanarak, abonelik oluşturma sayfasına geçiş yapılır.
6. Abonelik formu aşağıdaki gibi doldurulur ve “Next” butonuna basılır.
Bu abonelik servisi çağırmak için kullanılacaktır. Dikkat edilmesi gereken alan “Phase” parametresidir. Bu alana verilen değer 100’ün altında bir değer ise, servis çağrımı senkron şekilde olacaktır. Ancak bildiğim kadarıyla bu sadece Java tarafından çağrılan iş olayları için geçerlidir. Bu örnekte, iş olayını biz Pl/Sql kullanarak çağıracağımız için, iş olayımız WF_JAVA_DEFERRED tablosuna düşecektir. Bu tablo Oracle EBS’in “Message Queue” tablosudur. Tabloya düşen iş olayları sırayla ve belli bir zaman aralığında “Java Deferred Engine” tarafından işlenir.
“Rule” alanını “Message” olarak seçmemiz gerekmektedir zira bu abonelik içerisine XML talep zarfı eklenecektir.
7. Servis tanım adresi (WSDL) “WSDL Url” alanına yazılır. Karşı servisi çağrıabilmek için, servisin karşı adreste kurulu ve çalışır durumda olması gerekmektedir. Lokal bilgisayarımızdan servis tanımı seçememekteyiz.
8. Bu adımda servis seçilir ve “Next” butonuna basılır.
9. Bu adımda “Port” seçilir ve “Next” butonuna basılır.
10. Bu adımda servisin hangi fonksiyonunun çağrılacağı seçilir ve “Next” butonuna basılır.
11. “Java Rule Function” alanı servisi çağıran java sınıfının tanımının yapıldığı yerdir. Eğer kendi değişikliklerinizi servis çağrımına entegre etmek istiyorsanız, bu sınıfı Extend ederek yapabilirsiniz.
Bu adımda “Owner Name” ve “Owner Tag” alanlarında servisin sahibi olan kullanıcı adı ve modül seçilmesi gerekmektedir.
Not: 12.1.3 için aşağıdaki gibi seçilirken, 12.2.4 için lisans tanımı yapılmış bir EBS modülü seçilmelidir. Aksi taktirde, iş olayı çağrılamaz.
12. Talep iş olayı için ikinci bir abonelik oluşturulması gerekmektedir. Bu abonelik, çağrı için tanımlanan aboneliğin hataya düştüğü durumlarda, WFERROR iş akışını başlatıp, hata detayı ile ilgili bildirim göndermek için kullanılacaktır. “Create Subscription” butonu ile devam edilir.
13.”Source Type” alanı “External” olarak seçilir. “Rule Data” alanı ise “Key” seçilir. İş olayları başlatılırken bir adet anahtar değer ile başlatılır. Aynı değer iki abonelikte de kullanılır. “Next” butonuna basılarak devam edilir.
14. “Workflow Type” alanı “WFERROR” ve “Workflow Process” alanı “DEFAULT_EVENT_ERROR2” olarak seçilir. Owner alanları doldurulur ve “Apply” butonuna basılır.
Talep İş olayı için son durum aşağıdaki gibidir.
Cevap İş Olayı
1. Servisten dönen cevabı alabilmek için ikinci bir iş olayı tanımlamak gerekmektedir. Bu iş olayı bir abonelik sahibi olacaktır ve bu abonelik dönen cevabı alacaktır. “Create Event” butonu ile iş olayı oluşturma formu açılır.
2. Bilgiler aşağıdaki gibi doldurulur ve “Apply” butonuna basılır.
3. İş olayı aratılır ve “Subscription” ikonuna tıklanır.
4. “Create Subscription” butonuna tıklanır ve abonelik oluşturma formu açılır.
5. “Rule Data” alanı “message” olarak seçilir. Bu sefer “Action” alanı “Custom” olarak seçilir ve “Next” butonuna basılır.
6. Dönen cevabı almak ve işlemek için de java veya pl/sql kullanılabilir. Bu örnekte pl/sql kullanılacaktır. Pl/sql fonlsiyonunun belli bir formata uygun olması gerekmektedir. İlerleyen adımlarda kod bölümünde bu formatı göreceğiz. “Apply” butonuna basılır.
Bu aşamada iş olayları ve aboneliklerini oluşturma işlemi tamamlanmıştır.
EBS Service Agents
İş olay ve aboneliklerinin çalışabilmesi için “EBS Service Agents” bölümü altında aşağıdaki üç “Engine” çalışır durumda olması gerekmektedir.
- Web Services IN Agent
- Web Services OUT Agent
- Workflow Java Deferred Agent Listener (JMS queue için kullanılmaktadır. Mesajları WF_JAVA_DEFERRED tablosundan çekecektir.)
TABLO: xxanil_service_response
Bu tabloyu servis cevabını yazmak için kullanacağız.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
drop table xxanil_service_response; create table xxanil_service_response ( id number primary key, event_key varchar2(80), event_name varchar2(80), response clob, creation_date date ); create sequence xxanil_service_response_s start with 1; |
PROCEDURE: get_service_response
Bu prosedürü DML operasyonu için kullanacağız.
1 2 3 4 5 6 7 |
create or replace procedure insert_service_reponse(p_response in clob, p_event_key in varchar2, p_event_name in varchar2) is begin insert into xxanil_service_response values (xxanil_service_response_s.nextval, p_event_key, p_Event_name, p_response, sysdate); commit; end; |
FUNCTION: get_service_response
Fonksiyonun iskeletine dikkat ediniz. İsimleri p_subscription_guid ve p_event olmak üzere iki adet parametre olmak zorundadır. p_subscription_guid raw tipinde in parametresidir. p_event ise dönen cevabın da olduğu wf_event_t obje ve out tipindedir. Bu obje tipinden iş olayı anahtarını, adını, mesajını ve başka parametrelerini çekebiliriz. Bu fonksiyon “SUCCESS” veya “ERROR” dönmelidir.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
create or replace function get_service_response ( p_subscription_guid in raw, p_event in out nocopy wf_event_t ) return varchar2 is l_node varchar2(30); l_version integer; l_from varchar2(2000); l_eventName varchar2(80); l_eventkey varchar2(80); l_paramlist wf_parameter_list_t; l_eventData clob; l_messageHandle varchar2(100); begin l_eventkey := p_event.GetEventKey(); l_eventName := p_event.getEventName(); l_paramList := p_event.getParameterList(); l_eventData := p_event.getEventData(); insert_service_reponse (l_eventData, l_eventKey, l_eventName); return 'SUCCESS'; end get_service_response; |
Güvenlikli Servisler
Eğer çağrılacak servis güvenli servis ise, kullanıcı adını ve parolayı iş olayına parametre olarak geçmemiz gerekiyor. SIF bize servis talebinin header bölümünde yer alan güvenlik etiketlerine müdahale şansı tanımıyor. Dolayısıyla bir adet şifre objesi oluşturmamız gerekiyor. İş olayını çağrırken bu şifre objesinin adını göndereceğiz.
Aşağıdaki kodla şifre objesi oluşturabilirsiniz. l_module değişkeni modül adını alır, l_key değişkeni şifrenizin anahtarı iken, l_value ise şifre değerinizdir.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
declare sysResp number; appResp number; l_module varchar2(30) := 'SQLAP'; --MODULE l_key varchar2(30) := 'ANIL_KEY'; --KEY NAME l_value varchar2(500) := '111111'; --PASSWORD begin -- get SYSTEM_ADMINISTRATOR resp and app ids for global init .. begin select RESPONSIBILITY_ID, APPLICATION_ID into sysResp, appResp from FND_RESPONSIBILITY where RESPONSIBILITY_KEY = 'SYSTEM_ADMINISTRATOR'; fnd_global.apps_initialize( 0, sysResp, appResp); exception when others then -- fail back to seeded values fnd_global.apps_initialize(0,20420,1); end; fnd_vault.put(l_module, l_key, l_value); end; / commit; |
İş Olayını Çağırma
İş olayını çağırmak için pl/sql içinde wf_event paketindeki raise prosedürünü kullanacağız.
Önemli Not: Eğer servis talep xml zarfınızın en tepesinde (soap:envelope) namespace var ise, bu tanımlamaları xml zarfının başlık ve gövdesine indirmeniz gerekmektedir.
Değişkenler
- l_parameters: wf_parameter_list_t tipinde bir collection. İş olayı parametre listesi. İş olayına eklenen standart parametreleri bu record grup ile set edeceğiz.
- l_request_body: talep xml gövdesi
- l_request_header: talep xml başlığı
- l_event_key: çağırma anahtarı
1 2 3 4 5 6 |
l_parameters wf_parameter_list_t := wf_parameter_list_t (); l_request_body clob; l_request_header clob; l_event_key varchar2 (50) := 'ANIL-TEST-5'; |
Parametreler
Parametre Adı | Açıklama |
---|---|
WFBES_SOAP_USERNAME | Güvenlikli servisler için kullanıcı adının atanacağı parametre. |
WFBES_SOAP_PASSWORD_MOD | Güvenlikli servisler için yukarıda oluşturduğumuz şifre objesinin modülü. |
WFBES_SOAP_PASSWORD_KEY | Güvenlikli servisler için yukarıda oluşturduğumuz şifre objesinin anahtarı. |
WFBES_CALLBACK_EVENT | İş olayının cevabında hangi iş olayının başlatılacağı. Bu noktada ikinci yarattığımız iş olayını kullanacağız. |
WFBES_CALLBACK_AGENT | Web servis dönüş engine seçimi. Standart olan "Web Services IN Agent" engine'nini kullanacağız. |
WFBES_INPUT_taicsheader | Başlık parametresi. |
WFBES_INPUT_header | Başlık parametresi. |
WFBES_INPUT_tAICSHeader | Başlık parametresi. |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
wf_event.addparametertolist ( p_name => 'WFBES_SOAP_USERNAME', p_value => 'ANIL', p_parameterlist => l_parameters ); wf_event.addparametertolist ( p_name => 'WFBES_SOAP_PASSWORD_MOD', p_value => 'SQLAP', p_parameterlist => l_parameters ); wf_event.addparametertolist ( p_name => 'WFBES_SOAP_PASSWORD_KEY', p_value => 'ANIL_KEY', p_parameterlist => l_parameters ); wf_event.addparametertolist ( p_name => 'WFBES_CALLBACK_EVENT', p_value => 'XX_TEST_EVENT_RESPONSE', p_parameterlist => l_parameters ); wf_event.addparametertolist ( p_name => 'WFBES_CALLBACK_AGENT', p_value => 'WF_WS_JMS_IN', p_parameterlist => l_parameters ); l_request_header := '<xx:SOAHeader xmlns:xx="http://xmlns.oracle.com/apps/xx/soaprovider/plsql/xx_test_service/"> <xx:Responsibility>TR_PAYABLES_MANAGER</xx:Responsibility> <xx:RespApplication>SQLAP</xx:RespApplication> <xx:SecurityGroup>STANDARD</xx:SecurityGroup> <xx:NLSLanguage>TURKISH</xx:NLSLanguage> <xx:Org_Id/> </xx:SOAHeader>'; wf_event.addparametertolist ( p_name => 'WFBES_INPUT_taicsheader', p_value => l_request_header, p_parameterlist => l_parameters ); wf_event.addparametertolist ( p_name => 'WFBES_INPUT_header', p_value => l_request_header, p_parameterlist => l_parameters ); wf_event.addparametertolist ( p_name => 'WFBES_INPUT_tAICSHeader', p_value => l_request_header, p_parameterlist => l_parameters ); |
Gövdenin eklenmesi ve çağrım kodu
1 2 3 4 5 6 7 8 9 10 11 12 13 |
l_request_body := '<test:InputParameters xmlns:test="http://xmlns.oracle.com/apps/xx/soaprovider/plsql/xx_test_service/test_function/"> <test:PARAM>123</test:PARAM> </test:InputParameters>'; wf_event.raise (p_event_name => 'XX_TEST_EVENT_REQUEST', p_event_key => l_event_key, p_event_data => l_request_body, p_parameters => l_parameters, p_send_date => sysdate ); commit; |
Bütün kod:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
declare l_parameters wf_parameter_list_t := wf_parameter_list_t (); l_request_body clob; l_request_header clob; l_event_key varchar2 (50) := 'ANIL-TEST-5'; begin wf_event.addparametertolist ( p_name => 'WFBES_SOAP_USERNAME', p_value => 'ANIL', p_parameterlist => l_parameters ); wf_event.addparametertolist ( p_name => 'WFBES_SOAP_PASSWORD_MOD', p_value => 'SQLAP', p_parameterlist => l_parameters ); wf_event.addparametertolist ( p_name => 'WFBES_SOAP_PASSWORD_KEY', p_value => 'ANIL_KEY', p_parameterlist => l_parameters ); wf_event.addparametertolist ( p_name => 'WFBES_CALLBACK_EVENT', p_value => 'XX_TEST_EVENT_RESPONSE', p_parameterlist => l_parameters ); wf_event.addparametertolist ( p_name => 'WFBES_CALLBACK_AGENT', p_value => 'WF_WS_JMS_IN', p_parameterlist => l_parameters ); l_request_header := '<xx:SOAHeader xmlns:xx="http://xmlns.oracle.com/apps/xx/soaprovider/plsql/xx_test_service/"> <xx:Responsibility>TR_PAYABLES_MANAGER</xx:Responsibility> <xx:RespApplication>SQLAP</xx:RespApplication> <xx:SecurityGroup>STANDARD</xx:SecurityGroup> <xx:NLSLanguage>TURKISH</xx:NLSLanguage> <xx:Org_Id/> </xx:SOAHeader>'; wf_event.addparametertolist ( p_name => 'WFBES_INPUT_taicsheader', p_value => l_request_header, p_parameterlist => l_parameters ); wf_event.addparametertolist ( p_name => 'WFBES_INPUT_header', p_value => l_request_header, p_parameterlist => l_parameters ); wf_event.addparametertolist ( p_name => 'WFBES_INPUT_tAICSHeader', p_value => l_request_header, p_parameterlist => l_parameters ); l_request_body := '<test:InputParameters xmlns:test="http://xmlns.oracle.com/apps/xx/soaprovider/plsql/xx_test_service/test_function/"> <test:PARAM>123</test:PARAM> </test:InputParameters>'; wf_event.raise (p_event_name => 'XX_TEST_EVENT_REQUEST', p_event_key => l_event_key, p_event_data => l_request_body, p_parameters => l_parameters, p_send_date => sysdate ); commit; end; |
Oracle Workflow kullanarak iş olayını çağırmak için aşağıdaki sayfayı inceleyebilirsiniz.
https://blogs.oracle.com/ebusinesssuiteintegration/entry/invoking_web_service_from_orac_1
OAF sayfasından iş olayını çağırmak için aşağıdaki sayfayı inceleyebilirsiniz.
https://blogs.oracle.com/ebusinesssuiteintegration/entry/r121_-_invoking_web_service_fr
Some genuinely interesting info, well written and broadly user genial. Johnna Radcliffe Nichy