DBA Data[Home] [Help]

PACKAGE BODY: APPS.FND_LOG_REPOSITORY

Source


1 package body FND_LOG_REPOSITORY as
2 /* $Header: AFUTLGRB.pls 120.12 2006/09/18 14:19:08 pferguso ship $ */
3 
4    --
5    -- PRIVATE TYPES, VARIABLES
6    --
7 
8    /*
9    **  For INIT Procedure
10    */
11    type MODULE_TAB_TYPE   is table of varchar2(255) index by binary_integer;
12 
13    MODULE_TAB         MODULE_TAB_TYPE;
14    TABLE_SIZE         binary_integer := 0;  /* the size of above tables*/
15 
16    AFLOG_ENABLED_X   BOOLEAN         := TRUE;/* default should never be used.*/
17    AFLOG_FILENAME_X  VARCHAR2(255)   := NULL;
18    AFLOG_LEVEL_X     NUMBER          := 6;/* default should never be used.*/
19    AFLOG_MODULE_X    VARCHAR2(2000)  := NULL;
20    AFLOG_BUFFER_SIZE_X      NUMBER   := 1000;
21    AFLOG_BUFFER_MODE_X      NUMBER   := 0;
22    SESSION_ID_X      NUMBER          := NULL;
23    USER_ID_X         NUMBER          := NULL;
24 
25    SELF_INITED_X     BOOLEAN         := FALSE;
26 
27    TXN_SESSION	     NUMBER	     := NULL;
28    TXN_MACHINE	     VARCHAR2(64)    := NULL;
29    TXN_PROCESS       VARCHAR2(9)     := NULL;
30    TXN_PROGRAM       VARCHAR2(48)    := NULL;
31    TXN_INSTANCE      VARCHAR2(16)  := NULL;
32 
33    /* For Buffered Mode */
34    G_BUFFER_POS	     NUMBER        := 1;
35    MODULE_TABLE FND_TABLE_OF_VARCHAR2_255;
36    LOG_LEVEL_TABLE FND_TABLE_OF_NUMBER;
37    MESSAGE_TEXT_TABLE FND_TABLE_OF_VARCHAR2_4000;
38    SESSION_ID_TABLE FND_TABLE_OF_NUMBER;
39    USER_ID_TABLE FND_TABLE_OF_NUMBER;
40    TIMESTAMP_TABLE FND_TABLE_OF_DATE;
41    LOG_SEQUENCE_TABLE FND_TABLE_OF_NUMBER;
42    ENCODED_TABLE FND_TABLE_OF_VARCHAR2_1;
43    NODE_TABLE varchar2(60) := NULL;
44    NODE_IP_ADDRESS_TABLE varchar2(30) := NULL;
45    PROCESS_ID_TABLE varchar2(120) := NULL;
46    JVM_ID_TABLE varchar2(120) := NULL;
47    THREAD_ID_TABLE FND_TABLE_OF_VARCHAR2_120;
48    AUDSID_TABLE FND_TABLE_OF_NUMBER;
49    DB_INSTANCE_TABLE FND_TABLE_OF_NUMBER;
50    TRANSACTION_CONTEXT_ID_TABLE FND_TABLE_OF_NUMBER;
51 
52    /*
53    **  For GET_CONTEXT Function
54    **     Types for storing context info before calling autonomous
55    **     logging procedures, like
56    **     FND_LOG_REPOSITORY.String_Unchecked_Internal2
57    */
58    type CONTEXT_REC is record (
59            a_col   varchar2(30),
60            a_val    varchar2(4000) );
61    type CONTEXT_ARRAY is table of CONTEXT_REC
62          index by binary_integer;
63 
64    /* For Proxy Alerting */
65    G_PRX_CHILD_TRANS_CONTEXT_ID NUMBER;
66    G_PRX_SESSION_ID fnd_log_messages.session_id%TYPE;
67    G_PRX_USER_ID fnd_log_messages.user_id%TYPE;
68    G_PRX_SESSION_MODULE fnd_log_exceptions.session_module%TYPE;
69    G_PRX_SESSION_ACTION fnd_log_exceptions.session_action%TYPE;
70    G_PRX_MODULE fnd_log_messages.module%TYPE;
71    G_PRX_NODE fnd_log_messages.node%TYPE;
72    G_PRX_NODE_IP_ADDRESS fnd_log_messages.node_ip_address%TYPE;
73    G_PRX_PROCESS_ID fnd_log_messages.process_id%TYPE;
74    G_PRX_JVM_ID fnd_log_messages.jvm_id%TYPE;
75    G_PRX_THREAD_ID fnd_log_messages.thread_id%TYPE;
76    G_PRX_AUDSID fnd_log_messages.audsid%TYPE;
77    G_PRX_DB_INSTANCE fnd_log_messages.db_instance%TYPE;
78 
79    /*
80     * For Proxy Alerting: Index values to use within CONTEXT_ARRAY.
81     * This is mostly for code readability in order to avoid passing
82     * many separate parameters.
83     *
84     * Procedure INIT_CHILD_CONTEXT will look for different context
85     * values from the context array as follows:
86     *
87     * E.g. for child context user id:
88     * l_user_id := p_context_array(CCI_USER_ID).a_val;
89     */
90    CCI_USER_ID CONSTANT NUMBER := 1;
91    CCI_RESP_APPL_ID CONSTANT NUMBER := 2;
92    CCI_RESPONSIBILITY_ID CONSTANT NUMBER := 3;
93    CCI_SECURITY_GROUP_ID CONSTANT NUMBER := 4;
94    CCI_COMPONENT_TYPE CONSTANT NUMBER := 5;
95    CCI_COMPONENT_APPL_ID CONSTANT NUMBER := 6;
96    CCI_COMPONENT_ID CONSTANT NUMBER := 7;
97    CCI_SESSION_ID CONSTANT NUMBER := 8;
98    CCI_SESSION_ACTION CONSTANT NUMBER := 9;
99    CCI_SESSION_MODULE CONSTANT NUMBER := 10;
100    CCI_MODULE CONSTANT NUMBER := 11;
101    CCI_NODE CONSTANT NUMBER := 12;
102    CCI_NODE_IP_ADDRESS CONSTANT NUMBER := 13;
103    CCI_PROCESS_ID CONSTANT NUMBER := 14;
104    CCI_JVM_ID CONSTANT NUMBER := 15;
105    CCI_THREAD_ID CONSTANT NUMBER := 16;
106    CCI_AUDSID CONSTANT NUMBER := 17;
107    CCI_DB_INSTANCE CONSTANT NUMBER := 18;
108 
109    /* fnd_log_enabled_tracing BOOLEAN := FALSE; */
110 
111 /***For debugging purpose */
112  PROCEDURE DEBUG(p_msg IN VARCHAR2) is
113  l_num number;
114   l_msg 		VARCHAR2(100);
115  --config_file UTL_FILE.FILE_TYPE;
116  begin
117     ------Debug using file system
118     --config_file := UTL_FILE.FOPEN ('/slot03/oracle/oam12devdb/9.2.0/appsutil/outbound/oam12dev', 'debugFC.txt', 'A');
119     --l_msg  := dbms_utility.get_time || '   ' || p_msg;
120     --UTL_FILE.PUT_LINE(config_file, l_msg);
121     --UTL_FILE.fclose(config_file);
122 
123     ------Debug using DB
124     --insert into DEBUG_FND_LOG_REPOSITORY(MSG) values(p_msg);
125     --commit;
126     --dbms_output.put_line(p_msg);
127     l_msg := null;
128  end DEBUG;
129 
130 
131 
132    /**
133     *  Private function for checking if alerting is enabled.
134     *  This method checks if Alerting is enabled at severity level defined by
135     *   input parameter p_msg_sev. If not, it returns false.
136     *         If yes, it checks if limit for maximum number of alerts has
137     *  been reached. If yes - it returns false
138     *
139     *  Argeuments
140     *      p_msg_sev  Raised Alert severity.
141     */
142    FUNCTION IS_ALERTING_ENABLED(p_msg_sev IN VARCHAR2) return boolean is
143       l_retu boolean;
144       l_sys_al_level varchar2(80);  /*fnd_profile_options.PROFILE_OPTION_NAME%TYPE*/
145       l_alertCount number;
146       l_pr_al_count number;
147    begin
148       l_retu := FALSE;
149 	if (p_msg_sev IS NULL)THEN
150            return l_retu;
151       end if;
152 
153       l_sys_al_level := fnd_profile.value('OAM_ENABLE_SYSTEM_ALERT');
154       DEBUG('IS_ALERTING_ENABLED::l_sys_al_level' || l_sys_al_level || ' p_msg_sev' || p_msg_sev );
155       --Check Valid profile value
156 	if ((l_sys_al_level <> '00_NONE')  AND (l_sys_al_level <> '10_CRITICAL')
157        AND(l_sys_al_level <> '20_ERROR') AND (l_sys_al_level <> '30_WARNING'))THEN
158            return l_retu;
159       end if;
160 
161 
162 
163 	if (l_sys_al_level = '00_NONE')THEN
164            return l_retu;
165       end if;
166 
167       l_sys_al_level := substr(l_sys_al_level, 4);
168       DEBUG('IS_ALERTING_ENABLED: Pr OAM_ENABLE_SYSTEM_ALERT enable. Next Check :sys_al_level' || l_sys_al_level);
169       DEBUG('IS_ALERTING_ENABLED::p_msg_sev' || p_msg_sev);
170 
171 
172 	if (l_sys_al_level >= p_msg_sev)THEN
173         l_pr_al_count := fnd_profile.value('OAM_MAX_SYSTEM_ALERT');
174         select count(*) into l_alertCount from FND_LOG_UNIQUE_EXCEPTIONS
175             where STATUS = 'N';
176         DEBUG('IS_ALERTING_ENABLED: can log msg Sevrity lower Next chek:l_pr_al_count' || l_pr_al_count);
177         DEBUG('IS_ALERTING_ENABLED::l_alertCount' || l_alertCount);
178         if (l_alertCount < l_pr_al_count)  then
179            l_retu := TRUE;
180         end if;
181       end if;
182 
183         if(l_retu = true) then
184            DEBUG('IS_ALERTING_ENABLED:Can log :return true');
185         else
186            DEBUG('IS_ALERTING_ENABLED:Can Not log:return false');
187         end if;
188       return l_retu;
189    end IS_ALERTING_ENABLED;
190 
191 
192    /*
193    ** FND_LOG_REPOSITORY.INIT_TRANSACTION_INTERNAL
194    **
195    ** Description:
196    ** Initializes a log transaction.  A log transaction
197    ** corresponds to an instance or invocation of a single
198    ** component.  (e.g. A concurrent request, service process,
199    ** open form, ICX function)
200    **
201    */
202 
203    PROCEDURE INIT_TRANSACTION_INTERNAL(
204                P_TRANSACTION_TYPE            IN VARCHAR2 DEFAULT NULL,
205                P_TRANSACTION_ID              IN NUMBER   DEFAULT NULL,
206                P_COMPONENT_TYPE              IN VARCHAR2 DEFAULT NULL,
207                P_COMPONENT_APPL_ID           IN VARCHAR2 DEFAULT NULL,
208                P_COMPONENT_ID                IN NUMBER   DEFAULT NULL,
209                P_SESSION_ID                  IN NUMBER   DEFAULT NULL,
210                P_USER_ID                     IN NUMBER   DEFAULT NULL,
211                P_RESP_APPL_ID                IN NUMBER   DEFAULT NULL,
212                P_RESPONSIBILITY_ID           IN NUMBER   DEFAULT NULL,
213                P_SECURITY_GROUP_ID           IN NUMBER   DEFAULT NULL,
214 	       P_PARENT_CONTEXT_ID	     IN NUMBER 	 DEFAULT NULL)  is
215    pragma AUTONOMOUS_TRANSACTION;
216 	l_transaction_context_id number;
217      begin
218        insert into FND_LOG_TRANSACTION_CONTEXT
219          (TRANSACTION_CONTEXT_ID,
220           SESSION_ID,
221           TRANSACTION_TYPE,
222           TRANSACTION_ID,
223           USER_ID,
224           RESP_APPL_ID,
225           RESPONSIBILITY_ID,
226           SECURITY_GROUP_ID,
227           COMPONENT_TYPE,
228           COMPONENT_APPL_ID,
229           COMPONENT_ID,
230           CREATION_DATE,
231 	  PARENT_CONTEXT_ID
232          ) values
233 	 (FND_LOG_TRANSACTION_CTX_ID_S.nextval,
234           nvl(P_SESSION_ID, -1),
235           P_TRANSACTION_TYPE,
236           nvl(P_TRANSACTION_ID, -1),
237           nvl(P_USER_ID, -1),
238           nvl(P_RESP_APPL_ID, -1),
239           nvl(P_RESPONSIBILITY_ID, -1),
240           nvl(P_SECURITY_GROUP_ID, -1),
241           P_COMPONENT_TYPE,
242           nvl(P_COMPONENT_APPL_ID, -1),
243           nvl(P_COMPONENT_ID, -1),
244           sysdate,
245 	  P_PARENT_CONTEXT_ID
246          ) RETURNING TRANSACTION_CONTEXT_ID into l_transaction_context_id;
247 
248        if (p_parent_context_id is null) then
249 	 FND_LOG.G_TRANSACTION_CONTEXT_ID := l_transaction_context_id;
250        else
251 	 -- called for a proxy so set the child transaction context id
252 	 G_PRX_CHILD_TRANS_CONTEXT_ID := l_transaction_context_id;
253        end if;
254 
255        commit;
256      end INIT_TRANSACTION_INTERNAL;
257 
258 
259    /*
260    **   GET_CONTEXT- Gathers context info within the session,
261    **   before calling autonomous logging procedures, like
262    **   FND_LOG_REPOSITORY.String_Unchecked_Internal2
263    */
264    PROCEDURE GET_CONTEXT (SESSION_ID    IN NUMBER DEFAULT NULL,
265                  USER_ID         IN NUMBER   DEFAULT NULL,
266                  NODE            IN VARCHAR2 DEFAULT NULL,
267                  NODE_IP_ADDRESS IN VARCHAR2 DEFAULT NULL,
268                  PROCESS_ID      IN VARCHAR2 DEFAULT NULL,
269                  JVM_ID          IN VARCHAR2 DEFAULT NULL,
270                  THREAD_ID       IN VARCHAR2 DEFAULT NULL,
271                  AUDSID          IN NUMBER   DEFAULT NULL,
272                  DB_INSTANCE     IN NUMBER   DEFAULT NULL,
273 		 CONTEXT_OUT     OUT NOCOPY  CONTEXT_ARRAY) is
274    begin
275       -- Populate l_context column names
276       -- Not really used right now, except to clarify.  May be helpful if
277       -- Get_Context becomes public.
278 /*
279       CONTEXT_OUT(1).a_col := 'SESSION_ID';
280       CONTEXT_OUT(2).a_col := 'USER_ID';
281       CONTEXT_OUT(3).a_col := 'NODE';
282       CONTEXT_OUT(4).a_col := 'NODE_IP_ADDRESS';
283       CONTEXT_OUT(5).a_col := 'PROCESS_ID';
284       CONTEXT_OUT(6).a_col := 'JVM_ID';
285       CONTEXT_OUT(7).a_col := 'THREAD_ID';
286       CONTEXT_OUT(8).a_col := 'AUDSID';
287       CONTEXT_OUT(9).a_col := 'DB_INSTANCE';
288       CONTEXT_OUT(10).a_col := 'TRANSACTION_CONTEXT_ID';
289       CONTEXT_OUT(11).a_col := 'SESSION_MODULE';
290       CONTEXT_OUT(12).a_col := 'SESSION_ACTION';
291 */
292 
293       if (TXN_SESSION is NULL) then
294         TXN_SESSION := userenv('SESSIONID');
295         TXN_INSTANCE := userenv('INSTANCE');
296         begin
297           select substrb(machine,1,60), process, program
298             into TXN_MACHINE, TXN_PROCESS, TXN_PROGRAM
299             from v$session
300             where audsid = TXN_SESSION;
301         exception
302         when others then
303           null;
304         end;
305       end if;
306 
307       /* 1. SESSION_ID */
308       if (SESSION_ID IS NULL) then
309         if SELF_INITED_X then
310           CONTEXT_OUT(1).a_val := SESSION_ID_X;
311         else
312           CONTEXT_OUT(1).a_val := icx_sec.g_session_id;
313         end if;
314       else
315         CONTEXT_OUT(1).a_val := SESSION_ID;
316       end if;
317 
318       /* 2. USER_ID */
319       if (USER_ID IS NULL) then
320         if SELF_INITED_X then
321           CONTEXT_OUT(2).a_val := USER_ID_X;
322         else
323           CONTEXT_OUT(2).a_val := fnd_profile.value('USER_ID');
324         end if;
325       else
326         CONTEXT_OUT(2).a_val := USER_ID;
327       end if;
328 
329       /* 3. NODE */
330       if (NODE IS NULL) then
331          CONTEXT_OUT(3).a_val := TXN_MACHINE;
332       else
333          CONTEXT_OUT(3).a_val := NODE;
334       end if;
335 
336       /* 4. NODE_IP_ADDRESS */
337       if (NODE_IP_ADDRESS IS NULL) then
338          CONTEXT_OUT(4).a_val := null;
339       else
340          CONTEXT_OUT(4).a_val := NODE_IP_ADDRESS;
341       end if;
342 
343 
344       /* 5. PROCESS_ID */
345       if (PROCESS_ID IS NULL) then
346          CONTEXT_OUT(5).a_val := TXN_PROCESS;
347       else
348          CONTEXT_OUT(5).a_val := PROCESS_ID;
349       end if;
350 
351       /* 6. JVM_ID */
352       if (JVM_ID IS NULL) then
353          if ( (INSTR(LOWER(TXN_PROGRAM), 'java') <> 0) OR
354               (INSTR(LOWER(TXN_PROGRAM),  'jre') <> 0) ) then
355             CONTEXT_OUT(6).a_val := TXN_PROCESS;
356          else
357             CONTEXT_OUT(6).a_val := null;
358          end if;
359       else
360          CONTEXT_OUT(6).a_val := JVM_ID;
361       end if;
362 
363       /* 7. THREAD_ID */
364       if (THREAD_ID IS NULL) then
365          CONTEXT_OUT(7).a_val := null;
366       else
367          CONTEXT_OUT(7).a_val := THREAD_ID;
368       end if;
369 
370       /* 8. AUDSID */
371       if (AUDSID IS NULL) then
372          CONTEXT_OUT(8).a_val := TXN_SESSION;
373       else
374          CONTEXT_OUT(8).a_val := AUDSID;
375       end if;
376 
377       /* 9. DB_INSTANCE */
378       if (DB_INSTANCE IS NULL) then
379          CONTEXT_OUT(9).a_val := TXN_INSTANCE;
380       else
381          CONTEXT_OUT(9).a_val := DB_INSTANCE;
382       end if;
383 
384       /* 10. TRANSACTION_CONTEXT_ID */
385       if (FND_LOG.G_TRANSACTION_CONTEXT_ID is NULL) THEN
386 
387         /* create a new transaction context on the fly */
388         FND_LOG.G_TRANSACTION_CONTEXT_ID := init_trans_int_with_context(
389                                                 fnd_global.conc_request_id,
390                                                 fnd_global.form_id,
391                                                 fnd_global.form_appl_id,
392                                                 fnd_global.conc_process_id,
393                                                 fnd_global.conc_queue_id,
394                                                 fnd_global.queue_appl_id,
395                                                 icx_sec.g_session_id,
396                                                 fnd_global.user_id,
397                                                 fnd_global.resp_appl_id,
398                                                 fnd_global.resp_id,
399                                                 fnd_global.security_group_id
400                                                 );
401 
402 
403       end if;
404 
405       CONTEXT_OUT(10).a_val := FND_LOG.G_TRANSACTION_CONTEXT_ID;
406 
407    end GET_CONTEXT;
408 
409    /*
410    **   GET_TRANSACTION_CONTEXT- Gathers transaction context info within
411    **   the session, before calling autonomous procedures, like
412    **   FND_LOG_REPOSITORY.Init_Transaction_Internal
413    */
414    PROCEDURE GET_TRANSACTION_CONTEXT ( SESSION_ID   IN NUMBER   DEFAULT NULL,
415                  USER_ID                     IN NUMBER   DEFAULT NULL,
416                  RESP_APPL_ID                IN NUMBER   DEFAULT NULL,
417                  RESPONSIBILITY_ID           IN NUMBER   DEFAULT NULL,
418                  SECURITY_GROUP_ID           IN NUMBER   DEFAULT NULL,
419 		 CONTEXT_OUT		     OUT NOCOPY  CONTEXT_ARRAY) is
420    begin
421       -- Populate CONTEXT_OUT column names
422       -- Not really used right now, except to clarify.  May be helpful if
423       -- Get_Transaction_Context becomes public.
424 /*
425       CONTEXT_OUT(1).a_col := 'SESSION_ID';
426       CONTEXT_OUT(2).a_col := 'USER_ID';
427       CONTEXT_OUT(3).a_col := 'RESP_APPL_ID';
428       CONTEXT_OUT(4).a_col := 'RESPONSIBILITY_ID';
429       CONTEXT_OUT(5).a_col := 'SECURITY_GROUP_ID';
430 */
431       /* 1. SESSION_ID */
432       if (SESSION_ID is NOT NULL) then
433         CONTEXT_OUT(1).a_val := SESSION_ID;
434       elsif ((SESSION_ID_X is NOT NULL) and
435           (SESSION_ID_X <> -1 )) then
436         CONTEXT_OUT(1).a_val := SESSION_ID_X;
437       else
438         CONTEXT_OUT(1).a_val := icx_sec.g_session_id;
439       end if;
440 
441 
442       /* 2. USER_ID */
443       if (USER_ID is NOT NULL) then
444         CONTEXT_OUT(2).a_val := USER_ID;
445       elsif ((USER_ID_X is NOT NULL) and
446              (USER_ID_X <> -1)) then
450       else
447         CONTEXT_OUT(2).a_val := USER_ID_X;
448       elsif (FND_GLOBAL.user_id is NOT NULL) then
449         CONTEXT_OUT(2).a_val := FND_GLOBAL.user_id;
451         CONTEXT_OUT(2).a_val := -1;
452       end if;
453 
454       /* 3. RESP_APPL_ID */
455       if (RESP_APPL_ID is NOT NULL) then
456         CONTEXT_OUT(3).a_val := RESP_APPL_ID;
457       else
458          CONTEXT_OUT(3).a_val := FND_GLOBAL.resp_appl_id;
459       end if;
460 
461       /* 4. RESP_ID */
462       if (RESPONSIBILITY_ID is NOT NULL) then
463         CONTEXT_OUT(4).a_val := RESPONSIBILITY_ID;
464       else
465         CONTEXT_OUT(4).a_val := FND_GLOBAL.resp_id;
466       end if;
467 
468       /* 5. SECURITY_GROUP_ID */
469       if (SECURITY_GROUP_ID is NOT NULL) then
470         CONTEXT_OUT(5).a_val := SECURITY_GROUP_ID;
471       else
472         CONTEXT_OUT(5).a_val := FND_GLOBAL.security_group_id;
473       end if;
474 
475    end GET_TRANSACTION_CONTEXT;
476 
477    /*
478    ** SELF_INIT- Initialize the logging system automatically.  Note that
479    ** in the case of Forms initialization, this routine does not obviate the
480    ** need for the INIT routine to be called by AOL, because when the
481    ** code is self inited, the user/resp context may not exist (so only site
482    ** level profiles would exist).  This self initialization will allow the
483    ** site level profiles to be acted upon, and later the actual
484    ** INIT call will allow the user level profiles to control logging.
485    */
486    PROCEDURE SELF_INIT  is
487    begin
488       INIT;
489       SELF_INITED_X := TRUE;
490    end;
491 
492 
493    /*
494    **  Determines whether logging is enabled or disabled for this module
495    **  and level.
496    */
497    function CHECK_ACCESS_INTERNAL(MODULE_IN IN VARCHAR2,
498                                   LEVEL_IN  IN NUMBER) return BOOLEAN is
499    begin
500       if(NOT SELF_INITED_X) then
501          SELF_INIT;
502       end if;
503 
504       if (NOT AFLOG_ENABLED_X) then
505          return FALSE;
506       end if;
507       if (LEVEL_IN < AFLOG_LEVEL_X) then
508          return FALSE;
509       end if;
510       if(TABLE_SIZE = 0) then
511          return TRUE;  /* If no module is specified, log for all modules*/
512       end if;
513       for IDX in 1..TABLE_SIZE loop
514          if UPPER(MODULE_IN) like MODULE_TAB(IDX)  then
515             return TRUE;
516          end if;
517       end loop;
518       return FALSE;
519    end;
520 
521    /*
522    **  Private - for ATG only.
523    **  POST_EXCEPTION
524    **  Description:
525    **  Inserts extended exception information into FND_LOG_EXCEPTIONS and
526    **  posts the exception / unexpected error to the Business Event System
527    **
528    **  Arguments:
529    **      Module      - Module name (See FND_LOG standards)
530    **      Message_Id  - The unique identifier of the message from
531    **                    FND_LOG_MESSAGES.Log_Sequence
532    */
533    FUNCTION POST_EXCEPTION ( P_MODULE                 IN VARCHAR2,
534                              P_LOG_SEQUENCE           IN NUMBER,
535                              P_MESSAGE_APP            IN VARCHAR2 DEFAULT NULL,
536                              P_MESSAGE_NAME           IN VARCHAR2 DEFAULT NULL)
537                                                         return BOOLEAN is
538        l_msg_text           varchar2(2000);
539        l_enc_msg            varchar2(2000) := null;
540        l_msg_app            varchar2(50);
541        l_msg_name           varchar2(30);
542        l_base_lang          varchar2(4);  -- Base language_code for install
543        l_msg_cat            varchar2(10); -- Message category
544        l_msg_sev            varchar2(10); -- Message severity
545        l_cur_lang           varchar2(64);
546        l_cur_date_lang      varchar2(64);
547        l_cur_sort           varchar2(64);
548        l_ex_id              number;
549        l_txn_id             number;
550        l_session_action     varchar2(32);
551        l_session_module     varchar2(48);
552        l_is_new_alert       boolean := false;
553        l_occ_count         number;
554        l_max_occ_count     number;
555 
556 
557    pragma AUTONOMOUS_TRANSACTION;
558 
559    begin
560 
561         select MESSAGE_TEXT, TRANSACTION_CONTEXT_ID
562             into l_enc_msg, l_txn_id
563             from FND_LOG_MESSAGES
564             where LOG_SEQUENCE = P_LOG_SEQUENCE;
565 
566         if ((P_MESSAGE_APP IS NOT NULL) and
567             (P_MESSAGE_NAME IS NOT NULL)) then
568             l_msg_app := P_MESSAGE_APP;
569             l_msg_name := P_MESSAGE_NAME;
570         else
571           FND_MESSAGE.PARSE_ENCODED(l_enc_msg,
572                                     l_msg_app,
573                                     l_msg_name);
574         end if;
575 
576 		l_msg_name := UPPER(l_msg_name);
577 
578         select LANGUAGE_CODE
579           into l_base_lang
580           from FND_LANGUAGES
581           where INSTALLED_FLAG = 'B';
582 
583         /**
584          * Added Check for Proxy Alerting. If child context is set use
585          * sesion module and action for child instead of current session.
586          */
587         if (G_PRX_CHILD_TRANS_CONTEXT_ID is null) then
588           select module, action
592 	else
589             into l_session_module, l_session_action
590             from v$session
591 	    where audsid = userenv('SESSIONID');
593 	  l_session_module := G_PRX_SESSION_MODULE;
594 	  l_session_action := G_PRX_SESSION_ACTION;
595       	end if;
596 
597         begin
598           select CATEGORY, SEVERITY
599             into l_msg_cat, l_msg_sev
600             from FND_NEW_MESSAGES fnm,
601                  FND_APPLICATION  fa
602            where fnm.APPLICATION_ID = fa.APPLICATION_ID
603              and fa.APPLICATION_SHORT_NAME = l_msg_app
604              and fnm.MESSAGE_NAME = l_msg_name
605              and fnm.LANGUAGE_CODE = l_base_lang;
606         exception
607           when others then
608              FND_MESSAGE.SET_NAME ('FND', 'SQL-Generic error');
609              FND_MESSAGE.SET_TOKEN ('ERRNO', sqlcode, FALSE);
610              FND_MESSAGE.SET_TOKEN ('REASON', sqlerrm, FALSE);
611              FND_MESSAGE.SET_TOKEN ('ROUTINE',
612                                 'FND_LOG_REPOSITORY.POST_EXCEPTION', FALSE);
613 
614              rollback;
615              return FALSE;
616         end;
617 
618 	if ((l_msg_cat IS NULL) or (l_msg_sev IS NULL) or (IS_ALERTING_ENABLED(l_msg_sev) = FALSE)) THEN
619            rollback;
620            return FALSE;
621         end if;
622 
623 
624         /* Here we need to  insert the translated message text into MESSAGE_TEXT        */
625         /* First we will save the current language, then switch our session to English, */
626         /* retrieve the English message text, then switch back to the original language */
627         select value
628          into l_cur_lang
629          from v$nls_parameters
630          where parameter = 'NLS_LANGUAGE';
631         select value
632          into l_cur_date_lang
633          from v$nls_parameters
634          where parameter = 'NLS_DATE_LANGUAGE';
635         select value
636          into l_cur_sort
637          from v$nls_parameters
638          where parameter = 'NLS_SORT';
639 
640         dbms_session.set_nls('NLS_LANGUAGE', 'AMERICAN');
641 
642         fnd_message.set_encoded(l_enc_msg);
643 
644         l_msg_text := fnd_message.get;
645 
646         dbms_session.set_nls('NLS_LANGUAGE', '"' || l_cur_lang || '"');
647         dbms_session.set_nls('NLS_DATE_LANGUAGE', '"' || l_cur_date_lang || '"');
648         dbms_session.set_nls('NLS_SORT', '"' || l_cur_sort || '"');
649 
650 
651         /* Unique exception enhancement: Check fnd_log_unique_exceptions table for a row */
652         /* with this same message. If one exists already, increment the exception count  */
653         /* If this is the first one, insert a new row into fnd_log_unique_exceptions     */
654         begin
655           l_is_new_alert := false;
656           select unique_exception_id, count
657             into l_ex_id, l_occ_count
658             from fnd_log_unique_exceptions
659             where encoded_message = l_enc_msg
660             and status in ('N', 'O');
661 
662           /** Check if limit for occrrences has been reached **/
663           l_max_occ_count := fnd_profile.value('OAM_MAX_OCCURRENCES_PER_ALERT');
664           if(l_occ_count >= l_max_occ_count) then
665              rollback;
666              DEBUG('Not Logging occ l_occ_count = l_max_occ_count'|| l_max_occ_count);
667              return FALSE;
668           end if;
669 
670           update fnd_log_unique_exceptions flue
671              set flue.count = flue.count + 1
672              where flue.unique_exception_id = l_ex_id;
673 
674         exception
675           when no_data_found then
676             select fnd_log_unique_exception_s.nextval
677               into l_ex_id
678               from dual;
679 
680 		insert into fnd_log_unique_exceptions (
681 		  UNIQUE_EXCEPTION_ID,
682 		  ENCODED_MESSAGE,
683 		  ENGLISH_MESSAGE,
684 		  STATUS,
685 		  COUNT,
686 		  SEVERITY,
687 		  CATEGORY,
688 		  CREATED_BY,
689 		  CREATION_DATE,
690 		  LAST_UPDATED_BY,
691 		  LAST_UPDATE_DATE,
692 		  LAST_UPDATE_LOGIN
693 		 )
694            values (
695               l_ex_id,
696               l_enc_msg,
697               l_msg_text,
698               'N',
699               1,
700               l_msg_sev,
701               l_msg_cat,
702               USER_ID_X,
703               sysdate,
704               USER_ID_X,
705               sysdate,
706               USER_ID_X);
707           l_is_new_alert := true;
708            DEBUG('Logged Alert'|| l_ex_id);
709 
710         end;
711 
712 
713         /* Log extended exception information in FND_LOG_EXCEPTIONS */
714         insert into FND_LOG_EXCEPTIONS (
715            LOG_SEQUENCE,
716            SESSION_MODULE,
717            SESSION_ACTION,
718            UNIQUE_EXCEPTION_ID,
719            ACKNOWLEDGED,
720 	       MESSAGE_TEXT,
721 	       TRANSACTION_CONTEXT_ID
722         ) values
723         (
724            P_LOG_SEQUENCE,
725            substrb(l_session_module,1,48),
726            substrb(l_session_action,1,32),
727            l_ex_id,
728            'N',
729 	       l_msg_text,
730 	       l_txn_id
731         );
732 
733         DEBUG('Logging occ P_LOG_SEQUENCE' || P_LOG_SEQUENCE);
737                          to_char(P_LOG_SEQUENCE) );
734 
735         /* Always Post exception to Business Event System */
736         WF_EVENT.RAISE('oracle.apps.fnd.system.exception',
738 
739         commit;
740         return TRUE;
741 
742 
743    exception
744           when others then
745              FND_MESSAGE.SET_NAME ('FND', 'SQL-Generic error');
746              FND_MESSAGE.SET_TOKEN ('ERRNO', sqlcode, FALSE);
747              FND_MESSAGE.SET_TOKEN ('REASON', sqlerrm, FALSE);
748              FND_MESSAGE.SET_TOKEN ('ROUTINE',
749                                  'FND_LOG_REPOSITORY.POST_EXCEPTION', FALSE);
750          rollback;
751          return FALSE;
752 
753    end POST_EXCEPTION;
754 
755    /*
756    **  Writes the message to the log file for the spec'd level and module
757    **  without checking if logging is enabled at this level.  This
758    **  routine is only to be called from the AOL implementations of
759    **  the AFLOG interface, in languages like JAVA or C.
760    **  If the SESSION_ID and/or USER_ID is not passed, it defaults to the
761    **  value that was passed upon INIT.
762    */
763    PROCEDURE STRING_UNCHECKED_INTERNAL(LOG_LEVEL IN NUMBER,
764                     MODULE        IN VARCHAR2,
765                     MESSAGE_TEXT  IN VARCHAR2,
766                     SESSION_ID    IN NUMBER   DEFAULT NULL,
767                     USER_ID       IN NUMBER   DEFAULT NULL,
768                     CALL_STACK    IN VARCHAR2 DEFAULT NULL,
769                     ERR_STACK     IN VARCHAR2 DEFAULT NULL) is
770 
771       SESSION_ID_Z  NUMBER;
772       USER_ID_Z     NUMBER;
773 
774    pragma AUTONOMOUS_TRANSACTION;
775    begin
776       if(NOT SELF_INITED_X) then
777          SELF_INIT;
778       end if;
779 
780       if (SESSION_ID is not NULL) then
781          SESSION_ID_Z := SESSION_ID;
782       else
783          SESSION_ID_Z := SESSION_ID_X;
784       end if;
785 
786       if (USER_ID is not NULL) then
787          USER_ID_Z := USER_ID;
788       else
789          USER_ID_Z := USER_ID_X;
790       end if;
791 
792       if (AFLOG_FILENAME_X is not NULL) then
793          null; /* Eventually we will want to add code that will log to a */
794                /* file if they set the filename, but for now we will just */
795 	       /* log to table */
796       end if;
797 
798 
799       INSERT INTO FND_LOG_MESSAGES (
800            ECID_ID,
801            ECID_SEQ,
802            CALLSTACK,
803            ERRORSTACK,
804            MODULE,
805            LOG_LEVEL,
806            MESSAGE_TEXT,
807            SESSION_ID,
808            USER_ID,
809            TIMESTAMP,
810            LOG_SEQUENCE
811       ) values
812       (
813            SYS_CONTEXT('USERENV', 'ECID_ID'),
814            SYS_CONTEXT('USERENV', 'ECID_SEQ'),
815            CALL_STACK,
816            ERR_STACK,
817            SUBSTRB(MODULE,1,255),
818            LOG_LEVEL,
819            SUBSTRB(MESSAGE_TEXT, 1, 4000),
820            SESSION_ID_Z,
821            USER_ID_Z,
822            SYSDATE,
823            FND_LOG_MESSAGES_S.NEXTVAL
824       );
825 
826       commit;
827    end;
828 
829    /* Clears in memory buffered messages */
830    PROCEDURE DELETE_BUFFERED_TABLES is
831    begin
832            TIMESTAMP_TABLE.delete;
833            LOG_SEQUENCE_TABLE.delete;
834            MODULE_TABLE.delete;
835            LOG_LEVEL_TABLE.delete;
836            MESSAGE_TEXT_TABLE.delete;
837            SESSION_ID_TABLE.delete;
838            USER_ID_TABLE.delete;
839            ENCODED_TABLE.delete;
840            THREAD_ID_TABLE.delete;
841            AUDSID_TABLE.delete;
842            DB_INSTANCE_TABLE.delete;
843            TRANSACTION_CONTEXT_ID_TABLE.delete;
844    end;
845 
846    /* Flushes any buffered messages */
847    FUNCTION FLUSH return NUMBER is
848    l_log_seq NUMBER := NULL;
849    begin
850        if (G_BUFFER_POS > 1) then
851            l_log_seq := BULK_INSERT_PVT(MODULE_TABLE,
852                                 LOG_LEVEL_TABLE,
853                                 MESSAGE_TEXT_TABLE,
854                                 SESSION_ID_TABLE,
855                                 USER_ID_TABLE,
856                                 TIMESTAMP_TABLE,
857                                 LOG_SEQUENCE_TABLE,
858                                 ENCODED_TABLE,
859                                 NODE_TABLE,
860                                 NODE_IP_ADDRESS_TABLE,
861                                 PROCESS_ID_TABLE,
862                                 JVM_ID_TABLE,
863                                 THREAD_ID_TABLE,
864                                 AUDSID_TABLE,
865                                 DB_INSTANCE_TABLE,
866                                 TRANSACTION_CONTEXT_ID_TABLE,
867                                 (G_BUFFER_POS - 1) );
868 
869            l_log_seq := LOG_SEQUENCE_TABLE(G_BUFFER_POS - 1);
870 
871            DELETE_BUFFERED_TABLES;
872            G_BUFFER_POS := 1;
873         end if;
874            return l_log_seq;
875         exception
876           when others then
877             AFLOG_BUFFER_MODE_X := 0;
878             G_BUFFER_POS := 1;
879             DELETE_BUFFERED_TABLES;
883         return l_log_seq;
880             STR_UNCHKED_INT_WITH_CONTEXT(6, 'fnd.plsql.fnd_log_repository', 'Buffered Logging Failed! ' ||
881                                             'Please report to Oracle Development. sqlcode=' || sqlcode ||
882                                             '; sqlerrm=' || sqlerrm);
884    end FLUSH;
885 
886    /*
887    ** Private- Flushes any buffered messages, and resets to non-buffered mode
888    */
889    PROCEDURE RESET_BUFFERED_MODE is
890      l_count NUMBER := 0;
891    begin
892      l_count := FLUSH;
893      AFLOG_BUFFER_MODE_X := 0;
894    end RESET_BUFFERED_MODE;
895 
896    /*
897    ** Enables buffered mode based on AFLOG_BUFFER_MODE Profile
898    */
899    PROCEDURE SET_BUFFERED_MODE is
900      l_buffer_size NUMBER := NULL;
901      l_buffer_mode NUMBER := NULL;
902    begin
903 
904     if ( AFLOG_ENABLED_X = TRUE) then
905 
906       l_buffer_size := TO_NUMBER(FND_PROFILE.VALUE('AFLOG_BUFFER_SIZE'));
907       l_buffer_mode := TO_NUMBER(FND_PROFILE.VALUE('AFLOG_BUFFER_MODE'));
908 
909       if ( l_buffer_size > -1 ) then
910          AFLOG_BUFFER_SIZE_X := l_buffer_size;
911       end if;
912 
913       if ( l_buffer_mode > -1 ) then
914          AFLOG_BUFFER_MODE_X := l_buffer_mode;
915       end if;
916 
917       if ( AFLOG_BUFFER_MODE_X > 0 ) then
918 	MODULE_TABLE := FND_TABLE_OF_VARCHAR2_255();
919 	LOG_LEVEL_TABLE := FND_TABLE_OF_NUMBER();
920 	MESSAGE_TEXT_TABLE := FND_TABLE_OF_VARCHAR2_4000();
921 	SESSION_ID_TABLE := FND_TABLE_OF_NUMBER();
922 	USER_ID_TABLE := FND_TABLE_OF_NUMBER();
923 	TIMESTAMP_TABLE := FND_TABLE_OF_DATE();
924 	LOG_SEQUENCE_TABLE := FND_TABLE_OF_NUMBER();
925 	ENCODED_TABLE := FND_TABLE_OF_VARCHAR2_1();
926 	THREAD_ID_TABLE := FND_TABLE_OF_VARCHAR2_120();
927 	AUDSID_TABLE := FND_TABLE_OF_NUMBER();
928 	DB_INSTANCE_TABLE := FND_TABLE_OF_NUMBER();
929 	TRANSACTION_CONTEXT_ID_TABLE := FND_TABLE_OF_NUMBER();
930       end if;
931 
932     end if;
933    end SET_BUFFERED_MODE;
934 
935    /*
936    **  Private -- Should only be called by STR_UNCHKED_INT_WITH_CONTEXT
937    **  Writes the message to the log file for the spec'd level and module
938    **  without checking if logging is enabled at this level.
939    */
940    FUNCTION STRING_UNCHECKED_INTERNAL2(LOG_LEVEL IN NUMBER,
941                     MODULE          IN VARCHAR2,
942                     MESSAGE_TEXT    IN VARCHAR2,
943                     LOG_SEQUENCE    IN NUMBER,
944                     ENCODED         IN VARCHAR2 DEFAULT 'N',
945                     SESSION_ID      IN NUMBER   DEFAULT NULL,
946                     USER_ID         IN NUMBER,
947                     NODE            IN VARCHAR2 DEFAULT NULL,
948                     NODE_IP_ADDRESS IN VARCHAR2 DEFAULT NULL,
949                     PROCESS_ID      IN VARCHAR2 DEFAULT NULL,
950                     JVM_ID          IN VARCHAR2 DEFAULT NULL,
951                     THREAD_ID       IN VARCHAR2 DEFAULT NULL,
952                     AUDSID          IN NUMBER   DEFAULT NULL,
953                     DB_INSTANCE     IN NUMBER   DEFAULT NULL,
954                     TRANSACTION_CONTEXT_ID IN NUMBER DEFAULT NULL,
955                     CALL_STACK      IN VARCHAR2 DEFAULT NULL,
956                     ERR_STACK       IN VARCHAR2 DEFAULT NULL) return NUMBER is
957    pragma AUTONOMOUS_TRANSACTION;
958    l_log_seq NUMBER := NULL;
959    cur_time DATE := NULL;
960    first_buf_time DATE := NULL;
961 
962    begin
963 
964    /* Only buffer log_level < 4 message, i.e. no error messages */
965    if (AFLOG_BUFFER_MODE_X > 0 and LOG_LEVEL < 4) then
966 
967      if (G_BUFFER_POS > TIMESTAMP_TABLE.COUNT) then
968        TIMESTAMP_TABLE.extend(AFLOG_BUFFER_SIZE_X);
969        LOG_SEQUENCE_TABLE.extend(AFLOG_BUFFER_SIZE_X);
970        MODULE_TABLE.extend(AFLOG_BUFFER_SIZE_X);
971        LOG_LEVEL_TABLE.extend(AFLOG_BUFFER_SIZE_X);
972        MESSAGE_TEXT_TABLE.extend(AFLOG_BUFFER_SIZE_X);
973        SESSION_ID_TABLE.extend(AFLOG_BUFFER_SIZE_X);
974        USER_ID_TABLE.extend(AFLOG_BUFFER_SIZE_X);
975        ENCODED_TABLE.extend(AFLOG_BUFFER_SIZE_X);
976        THREAD_ID_TABLE.extend(AFLOG_BUFFER_SIZE_X);
977        AUDSID_TABLE.extend(AFLOG_BUFFER_SIZE_X);
978        DB_INSTANCE_TABLE.extend(AFLOG_BUFFER_SIZE_X);
979        TRANSACTION_CONTEXT_ID_TABLE.extend(AFLOG_BUFFER_SIZE_X);
980      end if;
981 
982      /* This is the default Sequenced mode for AFLOG_BUFFER_MODE */
983      /* if ( AFLOG_BUFFER_MODE_X = 2 ) then */
984      -- Better to always do this so log_level>=4 messages are in sequence
985           select FND_LOG_MESSAGES_S.NEXTVAL
986             into  LOG_SEQUENCE_TABLE(G_BUFFER_POS)
987             from dual;
988      /* end if; */
989 
990        TIMESTAMP_TABLE(G_BUFFER_POS) := SYSDATE;
991        MODULE_TABLE(G_BUFFER_POS) := MODULE;
992        LOG_LEVEL_TABLE(G_BUFFER_POS) := LOG_LEVEL;
993        MESSAGE_TEXT_TABLE(G_BUFFER_POS) := MESSAGE_TEXT;
994        SESSION_ID_TABLE(G_BUFFER_POS) := SESSION_ID;
995        USER_ID_TABLE(G_BUFFER_POS) := USER_ID;
996        ENCODED_TABLE(G_BUFFER_POS) := ENCODED;
997 
998        NODE_TABLE := NODE;
999        NODE_IP_ADDRESS_TABLE := NODE_IP_ADDRESS;
1000        PROCESS_ID_TABLE := PROCESS_ID;
1001        JVM_ID_TABLE := JVM_ID;
1002 
1003        THREAD_ID_TABLE(G_BUFFER_POS) := THREAD_ID;
1004        AUDSID_TABLE(G_BUFFER_POS) := AUDSID;
1005        DB_INSTANCE_TABLE(G_BUFFER_POS) := DB_INSTANCE;
1009        /* Flush if buffering for > 5 mins
1006        TRANSACTION_CONTEXT_ID_TABLE(G_BUFFER_POS) := TRANSACTION_CONTEXT_ID;
1007        G_BUFFER_POS := G_BUFFER_POS + 1;
1008 
1010        if (G_BUFFER_POS > 1) then
1011          cur_time := SYSDATE;
1012          first_buf_time := TIMESTAMP_TABLE(1);
1013 	 if ( ((cur_time - first_buf_time)*24*60) > 5) then
1014 	   l_log_seq := FLUSH;
1015          end if;
1016        end if;
1017        */
1018 
1019        /* Flush if buffer >  AFLOG_BUFFER_SIZE_X */
1020        if (G_BUFFER_POS > AFLOG_BUFFER_SIZE_X) then
1021    	   l_log_seq := FLUSH;
1022        end if;
1023    else
1024 
1025 
1026       INSERT INTO FND_LOG_MESSAGES (
1027 	 ECID_ID,
1028          ECID_SEQ,
1029          CALLSTACK,
1030          ERRORSTACK,
1031          MODULE,
1032          LOG_LEVEL,
1033          MESSAGE_TEXT,
1034          SESSION_ID,
1035          USER_ID,
1036 	 TIMESTAMP,
1037          LOG_SEQUENCE,
1038          ENCODED,
1039          NODE,
1040          NODE_IP_ADDRESS,
1041          PROCESS_ID,
1042          JVM_ID,
1043          THREAD_ID,
1044          AUDSID,
1045          DB_INSTANCE,
1046          TRANSACTION_CONTEXT_ID
1047       ) values
1048       (
1049 	 SYS_CONTEXT('USERENV', 'ECID_ID'),
1050          SYS_CONTEXT('USERENV', 'ECID_SEQ'),
1051          CALL_STACK,
1052 	 ERR_STACK,
1053          SUBSTRB(MODULE,1,255),
1054          LOG_LEVEL,
1055          SUBSTRB(MESSAGE_TEXT, 1, 4000),
1056          SESSION_ID,
1057          nvl(USER_ID, -1),
1058 	 SYSDATE,
1059          FND_LOG_MESSAGES_S.NEXTVAL,
1060          ENCODED,
1061          substrb(NODE,1,60),
1062          substrb(NODE_IP_ADDRESS,1,30),
1063          substrb(PROCESS_ID,1,120),
1064          substrb(JVM_ID,1,120),
1065          substrb(THREAD_ID,1,120),
1066          AUDSID,
1067          DB_INSTANCE,
1068          TRANSACTION_CONTEXT_ID
1069       ) returning log_sequence into l_log_seq;
1070       commit;
1071    end if;
1072       return l_log_seq;
1073    end;
1074 
1075    /*
1076    **  Gathers context information within the same session, then
1077    **  calls the private, autonmous procedure STRING_UNCHECKED_INTERNAL2,
1078    **  passing context information to be logged in AFLOG tables
1079    **
1080    **  A wrapper API that calls String_Unchecked_Internal2 using the
1081    **  context values from internal cache of the context values.
1082    **  This routine is only to be called from the AOL implementations of
1083    **  the AFLOG interface, in languages like JAVA or C.
1084    **  If the SESSION_ID and/or USER_ID is not passed, it defaults to the
1085    **  value that was passed upon INIT.
1086    **  (NOTE: Recommend use FUNCTION STR_UNCHKED_INT_WITH_CONTEXT(..) instead
1087    */
1088    PROCEDURE STR_UNCHKED_INT_WITH_CONTEXT(LOG_LEVEL IN NUMBER,
1089                     MODULE          IN VARCHAR2,
1090                     MESSAGE_TEXT    IN VARCHAR2,
1091                     ENCODED         IN VARCHAR2 DEFAULT 'N',
1092                     SESSION_ID      IN NUMBER   DEFAULT NULL,
1093                     USER_ID         IN NUMBER   DEFAULT NULL,
1094                     NODE            IN VARCHAR2 DEFAULT NULL,
1095                     NODE_IP_ADDRESS IN VARCHAR2 DEFAULT NULL,
1096                     PROCESS_ID      IN VARCHAR2 DEFAULT NULL,
1097                     JVM_ID          IN VARCHAR2 DEFAULT NULL,
1098                     THREAD_ID       IN VARCHAR2 DEFAULT NULL,
1099                     AUDSID          IN NUMBER   DEFAULT NULL,
1100                     DB_INSTANCE     IN NUMBER   DEFAULT NULL,
1101                     CALL_STACK      IN VARCHAR2 DEFAULT NULL,
1102                     ERR_STACK       IN VARCHAR2 DEFAULT NULL) is
1103      l_seq NUMBER;
1104    begin
1105      l_seq := STR_UNCHKED_INT_WITH_CONTEXT(LOG_LEVEL,
1106                     MODULE,
1107                     MESSAGE_TEXT,
1108                     ENCODED,
1109                     SESSION_ID,
1110                     USER_ID,
1111                     NODE,
1112                     NODE_IP_ADDRESS,
1113                     PROCESS_ID,
1114                     JVM_ID,
1115                     THREAD_ID,
1116                     AUDSID,
1117                     DB_INSTANCE,
1118                     CALL_STACK,
1119                     ERR_STACK
1120 	      );
1121    end;
1122 
1123    /*
1124    **  Gathers context information within the same session, then
1125    **  calls the private, autonmous procedure STRING_UNCHECKED_INTERNAL2,
1126    **  passing context information to be logged in AFLOG tables
1127    **
1128    **  A wrapper API that calls String_Unchecked_Internal2 using the
1129    **  context values from internal cache of the context values.
1130    **  This routine is only to be called from the AOL implementations of
1131    **  the AFLOG interface, in languages like JAVA or C.
1132    **  If the SESSION_ID and/or USER_ID is not passed, it defaults to the
1133    **  value that was passed upon INIT.
1134    **
1135    **  Returns the log_sequence of the logged message- needed for Attachments
1136    */
1137    FUNCTION STR_UNCHKED_INT_WITH_CONTEXT(LOG_LEVEL IN NUMBER,
1138                     MODULE          IN VARCHAR2,
1139                     MESSAGE_TEXT    IN VARCHAR2,
1140                     ENCODED         IN VARCHAR2 DEFAULT 'N',
1141                     SESSION_ID      IN NUMBER   DEFAULT NULL,
1142                     USER_ID         IN NUMBER   DEFAULT NULL,
1143                     NODE            IN VARCHAR2 DEFAULT NULL,
1144                     NODE_IP_ADDRESS IN VARCHAR2 DEFAULT NULL,
1148                     AUDSID          IN NUMBER   DEFAULT NULL,
1145                     PROCESS_ID      IN VARCHAR2 DEFAULT NULL,
1146                     JVM_ID          IN VARCHAR2 DEFAULT NULL,
1147                     THREAD_ID       IN VARCHAR2 DEFAULT NULL,
1149                     DB_INSTANCE     IN NUMBER   DEFAULT NULL,
1150                     CALL_STACK      IN VARCHAR2 DEFAULT NULL,
1151                     ERR_STACK       IN VARCHAR2 DEFAULT NULL) RETURN NUMBER is
1152       l_context  CONTEXT_ARRAY;
1153       l_encoded  VARCHAR2(1) := null;
1154       l_log_sequence  number;
1155       l_posted        boolean := FALSE;
1156       l_module   varchar2(256);
1157    begin
1158 
1159       /* check for null values */
1160       if message_text is null then
1161          return -1;
1162       end if;
1163 
1164       if module is null then
1165          l_module := 'MODULE_UNKNOWN';
1166       else
1167          l_module := MODULE;
1168       end if;
1169 
1170       if log_level is null then
1171         return -1;
1172       end if;
1173 
1174 
1175       if(NOT SELF_INITED_X) then
1176          SELF_INIT;
1177       end if;
1178 
1179       GET_CONTEXT (
1180                    SESSION_ID      => SESSION_ID,
1181                    USER_ID         => USER_ID,
1182                    NODE            => NODE,
1183                    NODE_IP_ADDRESS => NODE_IP_ADDRESS,
1184                    PROCESS_ID      => PROCESS_ID,
1185                    JVM_ID          => JVM_ID,
1186                    THREAD_ID       => THREAD_ID,
1187                    AUDSID          => AUDSID,
1188                    DB_INSTANCE     => DB_INSTANCE,
1189 		   CONTEXT_OUT     => l_context);
1190 
1191       if (upper(ENCODED) in ('Y', 'N')) then
1192          l_encoded := ENCODED;
1193       else
1194          l_encoded := 'N';
1195       end if;
1196 
1197       if (AFLOG_FILENAME_X is not NULL) then
1198          null; /* Eventually we will want to add code that will log to a */
1199                /* file if they set the filename, but for now we will just */
1200                /* log to table */
1201       end if;
1202 
1203       /**
1204        * Added for proxy alerting. Check if child context is set. If yes,
1205        * use the child transaction context Id.
1206        */
1207       if (G_PRX_CHILD_TRANS_CONTEXT_ID is not null) then
1208 	if G_PRX_MODULE is null then
1209           l_module := 'MODULE_UNKNOWN';
1210         else
1211           l_module := G_PRX_MODULE;
1212         end if;
1213         l_context(1).a_val := G_PRX_SESSION_ID;
1214         l_context(2).a_val := G_PRX_USER_ID;
1215 	l_context(3).a_val := G_PRX_NODE;
1216         l_context(4).a_val := G_PRX_NODE_IP_ADDRESS;
1217         l_context(5).a_val := G_PRX_PROCESS_ID;
1218         l_context(6).a_val := G_PRX_JVM_ID;
1219         l_context(7).a_val := G_PRX_THREAD_ID;
1220 	if (G_PRX_AUDSID is null) then
1221 	  l_context(8).a_val := -1;
1222 	else
1223   	  l_context(8).a_val := G_PRX_AUDSID;
1224 	end if;
1225         l_context(9).a_val := G_PRX_DB_INSTANCE;
1226 	l_context(10).a_val := G_PRX_CHILD_TRANS_CONTEXT_ID;
1227       end if;
1228 
1229       l_log_sequence := STRING_UNCHECKED_INTERNAL2(LOG_LEVEL => LOG_LEVEL,
1230                     MODULE          => l_module,
1231                     MESSAGE_TEXT    => MESSAGE_TEXT,
1232                     LOG_SEQUENCE    => l_log_sequence,
1233                     ENCODED         => l_encoded,
1234                     SESSION_ID      => to_number(l_context(1).a_val),
1235                     USER_ID         => to_number(l_context(2).a_val),
1236                     NODE            => l_context(3).a_val,
1237                     NODE_IP_ADDRESS => l_context(4).a_val,
1238                     PROCESS_ID      => l_context(5).a_val,
1239                     JVM_ID          => l_context(6).a_val,
1240                     THREAD_ID       => l_context(7).a_val,
1241                     AUDSID          => l_context(8).a_val,
1242                     DB_INSTANCE     => l_context(9).a_val,
1243                     TRANSACTION_CONTEXT_ID => l_context(10).a_val,
1244                     CALL_STACK      => CALL_STACK,
1245                     ERR_STACK       => ERR_STACK);
1246 
1247       /* Unexpected errors are posted as exceptions */
1248       if (l_encoded = 'Y') and (LOG_LEVEL = FND_LOG.LEVEL_UNEXPECTED) then
1249          l_posted :=  POST_EXCEPTION(P_MODULE         => l_module,
1250                                      P_LOG_SEQUENCE   => l_log_sequence);
1251       end if;
1252 
1253       return l_log_sequence;
1254 
1255       end;
1256 
1257    /**
1258     * Inserts a empty BLOB for the P_LOG_SEQUENCE
1259     */
1260    PROCEDURE INSERT_BLOB(P_LOG_SEQUENCE IN NUMBER, PCHARSET IN VARCHAR2,
1261 		PMIMETYPE IN VARCHAR2, PENCODING IN VARCHAR2, PLANG IN VARCHAR2,
1262 		PFILE_EXTN IN VARCHAR2, PDESC IN VARCHAR2) is
1263    pragma AUTONOMOUS_TRANSACTION;
1264      begin
1265           INSERT INTO FND_LOG_ATTACHMENTS fla
1266           (
1267                 LOG_SEQUENCE,
1268 		CHARSET,
1269 		MIMETYPE,
1270 		ENCODING,
1271 		LANGUAGE,
1272 		FILE_EXTN,
1273 		DESCRIPTION,
1274                 CONTENT
1275           ) values
1276           (
1277                 P_LOG_SEQUENCE,
1278 		PCHARSET,
1279 		PMIMETYPE,
1280 		PENCODING,
1281 		PLANG,
1282 		PFILE_EXTN,
1283 		PDESC,
1287      end;
1284                 EMPTY_BLOB()
1285           );
1286           commit;
1288 
1289    /**
1290     * For AOL/J Internal use ONLY!
1291     * Returns a BLOB for the P_LOG_SEQUENCE
1292     *
1293     * Called from Client and Server PL/SQL
1294     */
1295    PROCEDURE GET_BLOB_INTERNAL(P_LOG_SEQUENCE IN NUMBER,
1296                         LOG_BLOB OUT NOCOPY BLOB,
1297                         P_CHARSET IN VARCHAR2 DEFAULT 'ascii',
1298                         P_MIMETYPE IN VARCHAR2 DEFAULT 'text/html',
1299                         P_ENCODING IN VARCHAR2 DEFAULT NULL,
1300                         P_LANG IN VARCHAR2 DEFAULT NULL,
1301                         P_FILE_EXTN IN VARCHAR2 DEFAULT 'txt',
1302 			P_DESC IN VARCHAR2 DEFAULT NULL) is
1303       l_log_sequence NUMBER := -1;
1304    begin
1305       if ( P_LOG_SEQUENCE is NULL or P_LOG_SEQUENCE < 0 ) then
1306          LOG_BLOB := NULL;
1307          return;
1308       end if;
1309 
1310       select content
1311         into LOG_BLOB
1312         from FND_LOG_ATTACHMENTS fla
1313         where fla.log_sequence = P_LOG_SEQUENCE for UPDATE;
1314       return;
1315 
1316       EXCEPTION
1317   	WHEN NO_DATA_FOUND THEN
1318         begin
1319 	  select flm.log_sequence
1320             into l_log_sequence
1321             from fnd_log_messages flm
1322             where flm.log_sequence = P_LOG_SEQUENCE;
1323 
1324 	  -- If log_sequence does not exist in fnd_log_messages
1325           -- its an invalid log_sequence, return NULL
1326 	  EXCEPTION
1327             WHEN NO_DATA_FOUND THEN
1328 	      LOG_BLOB := NULL;
1329 	      return;
1330         END;
1331 
1332 	-- If log_sequence exists create attachment
1333 	INSERT_BLOB(P_LOG_SEQUENCE, P_CHARSET, P_MIMETYPE, P_ENCODING, P_LANG, P_FILE_EXTN, P_DESC);
1334 
1335         select content
1336           into LOG_BLOB
1337           from FND_LOG_ATTACHMENTS fla
1338           where fla.log_sequence = P_LOG_SEQUENCE for UPDATE;
1339       end GET_BLOB_INTERNAL;
1340 
1341    /*
1342    ** FND_LOG_REPOSITORY.METRIC_INTERNAL
1343    ** Description:
1344    **  Private -- Should only be called by METRIC_INTERNAL_WITH_CONTEXT
1345    **  Writes a metric value out to the FND tables in an autonomous
1346    **  transaction.
1347    */
1348    PROCEDURE METRIC_INTERNAL(MODULE        IN VARCHAR2,
1349                     METRIC_CODE            IN VARCHAR2,
1350                     METRIC_SEQUENCE        IN NUMBER,
1351                     TYPE                   IN VARCHAR2,
1352                     STRING_VALUE           IN VARCHAR2,
1353                     NUMBER_VALUE           IN NUMBER,
1354                     DATE_VALUE             IN DATE,
1355                     TRANSACTION_CONTEXT_ID IN NUMBER,
1356                     SESSION_MODULE         IN VARCHAR2,
1357                     SESSION_ACTION         IN VARCHAR2,
1358                     NODE                   IN VARCHAR2,
1359                     NODE_IP_ADDRESS        IN VARCHAR2,
1360                     PROCESS_ID             IN VARCHAR2,
1361                     JVM_ID                 IN VARCHAR2,
1362                     THREAD_ID              IN VARCHAR2,
1363                     AUDSID                 IN VARCHAR2,
1364                     DB_INSTANCE            IN VARCHAR2) is
1365    pragma AUTONOMOUS_TRANSACTION;
1366      begin
1367        insert into FND_LOG_METRICS
1368         (MODULE,
1369          METRIC_CODE,
1370          METRIC_SEQUENCE,
1371          TYPE,
1372          STRING_VALUE,
1373          NUMBER_VALUE,
1374          DATE_VALUE,
1375          TIME,
1376          EVENT_KEY,
1377          TRANSACTION_CONTEXT_ID,
1378          SESSION_MODULE,
1379          SESSION_ACTION,
1380          NODE,
1381          NODE_IP_ADDRESS,
1382          PROCESS_ID,
1383          JVM_ID,
1384          THREAD_ID,
1385          AUDSID,
1386          DB_INSTANCE
1387         ) values
1388         (SUBSTRB(MODULE,1,255),
1389          METRIC_CODE,
1390          METRIC_SEQUENCE,
1391          TYPE,
1392          STRING_VALUE,
1393          NUMBER_VALUE,
1394          DATE_VALUE,
1395          SYSDATE,
1396          null,
1397          TRANSACTION_CONTEXT_ID,
1398          substrb(SESSION_MODULE,1,48),
1399          substrb(SESSION_ACTION,1,32),
1400          substrb(NODE,1,60),
1401          substrb(NODE_IP_ADDRESS,1,30),
1402          substrb(PROCESS_ID,1,120),
1403          substrb(JVM_ID,1,120),
1404          substrb(THREAD_ID,1,120),
1405          AUDSID,
1406          DB_INSTANCE
1407          );
1408        commit;
1409      end METRIC_INTERNAL;
1410 
1411 
1412    /*
1413    **  Convert the string into date format, store in global variable
1414    */
1415    PROCEDURE METRIC_STRING_TO_DATE(DATE_VC IN VARCHAR2 DEFAULT NULL) is
1416    begin
1417 
1418       if (DATE_VC IS NOT NULL) then
1419          FND_LOG_REPOSITORY.G_METRIC_DATE := FND_CONC_DATE.STRING_TO_DATE(DATE_VC);
1420          if (FND_LOG_REPOSITORY.G_METRIC_DATE IS NULL) then
1421             select SYSDATE
1422             into FND_LOG_REPOSITORY.G_METRIC_DATE
1423             from dual;
1424          end if;
1425       else
1426          select SYSDATE
1427          into FND_LOG_REPOSITORY.G_METRIC_DATE
1428          from dual;
1429       end if;
1430 
1431    end METRIC_STRING_TO_DATE;
1432 
1433 
1434    /*
1438    **
1435    **  Gathers context information within the same session, then
1436    **  calls the private, autonmous procedure METRIC_INTERNAL,
1437    **  passing context information to be logged in AFLOG tables
1439    **  A wrapper API that calls Metric_Internal using the
1440    **  context values from internal cache of the context values.
1441    **  This routine is only to be called from the AOL implementations of
1442    **  the AFLOG interface, in languages like JAVA or C.
1443    **  If the SESSION_ID is not passed, it defaults to the value that
1444    **  was passed upon INIT.
1445    */
1446    PROCEDURE METRIC_INTERNAL_WITH_CONTEXT(MODULE IN VARCHAR2,
1447                     METRIC_CODE            IN VARCHAR2,
1448                     METRIC_VALUE_STRING    IN VARCHAR2 DEFAULT NULL,
1449                     METRIC_VALUE_NUMBER    IN NUMBER   DEFAULT NULL,
1450                     METRIC_VALUE_DATE      IN DATE     DEFAULT NULL,
1451                     SESSION_ID             IN NUMBER   DEFAULT NULL,
1452                     NODE                   IN VARCHAR2 DEFAULT NULL,
1453                     NODE_IP_ADDRESS        IN VARCHAR2 DEFAULT NULL,
1454                     PROCESS_ID             IN VARCHAR2 DEFAULT NULL,
1455                     JVM_ID                 IN VARCHAR2 DEFAULT NULL,
1456                     THREAD_ID              IN VARCHAR2 DEFAULT NULL,
1457                     AUDSID                 IN NUMBER   DEFAULT NULL,
1458                     DB_INSTANCE            IN NUMBER   DEFAULT NULL) is
1459       l_context          CONTEXT_ARRAY;
1460       l_metric_sequence  number;
1461       l_type             varchar2(1);
1462       l_metric_value_date date;
1463 
1464       begin
1465       if(NOT SELF_INITED_X) then
1466          SELF_INIT;
1467       end if;
1468 
1469       GET_CONTEXT (
1470                    SESSION_ID      => SESSION_ID,
1471                    USER_ID         => -1,
1472                    NODE            => NODE,
1473                    NODE_IP_ADDRESS => NODE_IP_ADDRESS,
1474                    PROCESS_ID      => PROCESS_ID,
1475                    JVM_ID          => JVM_ID,
1476                    THREAD_ID       => THREAD_ID,
1477                    AUDSID          => AUDSID,
1478                    DB_INSTANCE     => DB_INSTANCE,
1479 		   CONTEXT_OUT     => l_context);
1480 
1481       select module, action
1482           into l_context(11).a_val, l_context(12).a_val
1483           from v$session
1484           where audsid = TXN_SESSION;
1485 
1486       select FND_LOG_METRICS_S.NEXTVAL
1487         into l_metric_sequence
1488         from dual;
1489 
1490       if (METRIC_VALUE_STRING is NOT NULL) then
1491         l_type := 'S';
1492       elsif (METRIC_VALUE_NUMBER is NOT NULL) then
1493         l_type := 'N';
1494       else
1495         l_type := 'D';
1496         if (METRIC_VALUE_DATE is NULL) then
1497            l_metric_value_date := FND_LOG_REPOSITORY.G_METRIC_DATE;
1498         else
1499            l_metric_value_date := METRIC_VALUE_DATE;
1500         end if;
1501 
1502       end if;
1503 
1504       if (AFLOG_FILENAME_X is not NULL) then
1505          null; /* Eventually we will want to add code that will log to a */
1506                /* file if they set the filename, but for now we will just */
1507                /* log to table */
1508       end if;
1509 
1510       METRIC_INTERNAL(MODULE               => MODULE,
1511                     METRIC_CODE            => METRIC_CODE,
1512                     METRIC_SEQUENCE        => l_metric_sequence,
1513                     TYPE                   => l_type,
1514                     STRING_VALUE           => METRIC_VALUE_STRING,
1515                     NUMBER_VALUE           => METRIC_VALUE_NUMBER,
1516                     DATE_VALUE             => l_metric_value_date,
1517                     TRANSACTION_CONTEXT_ID => l_context(10).a_val,
1518                     SESSION_MODULE         => l_context(11).a_val,
1519                     SESSION_ACTION         => l_context(12).a_val,
1520                     NODE                   => l_context(3).a_val,
1521                     NODE_IP_ADDRESS        => l_context(4).a_val,
1522                     PROCESS_ID             => l_context(5).a_val,
1523                     JVM_ID                 => l_context(6).a_val,
1524                     THREAD_ID              => l_context(7).a_val,
1525                     AUDSID                 => l_context(8).a_val,
1526                     DB_INSTANCE            => l_context(9).a_val);
1527 
1528       end METRIC_INTERNAL_WITH_CONTEXT;
1529 
1530    /*
1531    ** FND_LOG_REPOSITORY.METRICS_EVENT_INTERNAL
1532    ** Description:
1533    **  Private -- Should only be called by METRICS_EVENT_INT_WITH_CONTEXT
1534    **  Posts the pending metrics for the current component
1535    **  session to the Business Event system and updates the pending
1536    **  metrics with the event key in an autonomous transaction. The
1537    **  metrics will be bundled in an XML message included in the
1538    **  event.  The event will be named:
1539    **  "oracle.apps.fnd.system.metrics"
1540    **
1541    ** Arguments:
1542    **     CONTEXT_ID - Context id to post metrics for
1543    */
1544 
1545    PROCEDURE METRICS_EVENT_INTERNAL(CONTEXT_ID IN NUMBER) IS
1546       l_event_key number;
1547       pragma AUTONOMOUS_TRANSACTION;
1548 
1549    cnt    number;
1550 
1551    begin
1552 
1553       /*
1554          2983052: Check for rows in FND_LOG_METRICS
1555          If no metrics actually logged, don't raise an event.
1556       */
1560         where TRANSACTION_CONTEXT_ID = CONTEXT_ID;
1557       select count(1)
1558         into cnt
1559         from FND_LOG_METRICS
1561 
1562       if cnt = 0 then
1563         return;
1564       end if;
1565 
1566       select FND_METRICS_EVENT_KEY_S.nextval
1567         into l_event_key
1568         from dual;
1569 
1570       update FND_LOG_METRICS
1571          set EVENT_KEY = l_event_key
1572        where EVENT_KEY is NULL
1573          and TRANSACTION_CONTEXT_ID = CONTEXT_ID;
1574 
1575       begin
1576          WF_EVENT.RAISE('oracle.apps.fnd.system.metrics',
1577                         to_char(l_event_key) );
1578          commit;
1579       exception
1580          when others then
1581             FND_MESSAGE.SET_NAME ('FND', 'SQL-Generic error');
1582             FND_MESSAGE.SET_TOKEN ('ERRNO', sqlcode, FALSE);
1583             FND_MESSAGE.SET_TOKEN ('REASON', sqlerrm, FALSE);
1584             FND_MESSAGE.SET_TOKEN ('ROUTINE',
1585                                     'FND_LOG_REPOSITORY.METRIC_EVENT_INTERNAL', FALSE);
1586             rollback;
1587       end;
1588 
1589    end METRICS_EVENT_INTERNAL;
1590 
1591    /*
1592    ** FND_LOG_REPOSITORY.METRICS_EVENT_INT_WITH_CONTEXT
1593    ** Description:
1594    **  A wrapper API that calls Metrics_Event_Internal using the
1595    **  context values from internal cache of the context values.
1596    **  This routine is only to be called from the AOL implementations of
1597    **  the AFLOG interface, in languages like JAVA or C.
1598    **
1599    ** Arguments:
1600    **     CONTEXT_ID - Context id to post metrics for
1601    */
1602    PROCEDURE METRICS_EVENT_INT_WITH_CONTEXT (CONTEXT_ID IN NUMBER DEFAULT NULL)IS
1603       l_context_id number;
1604 
1605    begin
1606       if CONTEXT_ID is NOT NULL then
1607          l_context_id := CONTEXT_ID;
1608       else
1609          l_context_id := FND_LOG.G_TRANSACTION_CONTEXT_ID;
1610       end if;
1611 
1612       METRICS_EVENT_INTERNAL(l_context_id);
1613 
1614    end METRICS_EVENT_INT_WITH_CONTEXT;
1615 
1616 
1617 
1618    /*
1619    ** FND_LOG_REPOSITORY.INIT_TRANS_INT_WITH_CONTEXT
1620    ** Description:
1621    ** A wrapper API that calls Init_Transaction_Internal using the
1622    ** context values from internal cache of the context values.
1623    ** This routine is only to be called from the AOL implementations of
1624    ** the AFLOG interface, in languages like JAVA or C.
1625    ** If the SESSION_ID and/or USER_ID is not passed, it defaults to the
1626    ** value that was passed upon INIT.
1627    **
1628    ** Initializes a log transaction.  A log transaction
1629    ** corresponds to an instance or invocation of a single
1630    ** component.  (e.g. A concurrent request, service process,
1631    ** open form, ICX function)
1632    **
1633    ** This routine should be called only after
1634    ** FND_GLOBAL.INITIALIZE, since some of the context information
1635    ** is retrieved from FND_GLOBAL.
1636    **
1637    ** Arguments:
1638    **   CONC_REQUEST_ID       - Concurrent request id
1639    **   FORM_ID               - Form id
1640    **   FORM_APPLICATION_ID   - Form application id
1641    **   CONCURRENT_PROCESS_ID - Service process id
1642    **   CONCURRENT_QUEUE_ID   - Service queue id
1643    **   QUEUE_APPLICATION_ID  - Service queue application id
1644    **
1645    ** Use only the arguments that apply to the caller.
1646    ** Any argument that does not apply should be passed as NULL
1647    ** i.e. when calling from a form, pass in FORM_ID and FORM_APPLICATION_ID
1648    ** and leave all other parameters NULL.
1649    **
1650    ** Returns:
1651    **   ID of the log transaction context
1652    **
1653    */
1654    FUNCTION INIT_TRANS_INT_WITH_CONTEXT (CONC_REQUEST_ID             IN NUMBER DEFAULT NULL,
1655                                          FORM_ID                     IN NUMBER DEFAULT NULL,
1656                                          FORM_APPLICATION_ID         IN NUMBER DEFAULT NULL,
1657                                          CONCURRENT_PROCESS_ID       IN NUMBER DEFAULT NULL,
1658                                          CONCURRENT_QUEUE_ID         IN NUMBER DEFAULT NULL,
1659                                          QUEUE_APPLICATION_ID        IN NUMBER DEFAULT NULL,
1660                                          SESSION_ID                  IN NUMBER DEFAULT NULL,
1661                                          USER_ID                     IN NUMBER DEFAULT NULL,
1662                                          RESP_APPL_ID                IN NUMBER DEFAULT NULL,
1663                                          RESPONSIBILITY_ID           IN NUMBER DEFAULT NULL,
1664                                          SECURITY_GROUP_ID           IN NUMBER DEFAULT NULL)
1665                                                           return NUMBER is
1666 
1667       l_context                 context_array;
1668       l_transaction_type        varchar2(30);
1669       l_transaction_id          number;
1670       l_component_appl_id       number;
1671       l_component_type          varchar2(30);
1672       l_component_id            number;
1673       l_transaction_context_id  number;
1674       l_form_id                 number;
1675       l_form_application_id     number;
1676 
1677       begin
1678       if(NOT SELF_INITED_X) then
1679          SELF_INIT;
1680       end if;
1681 
1682       GET_TRANSACTION_CONTEXT (
1683                      SESSION_ID          => SESSION_ID,
1684                      USER_ID             => USER_ID,
1685                      RESP_APPL_ID        => RESP_APPL_ID,
1686                      RESPONSIBILITY_ID   => RESPONSIBILITY_ID,
1687                      SECURITY_GROUP_ID   => SECURITY_GROUP_ID,
1688 		     CONTEXT_OUT	 => l_context);
1689 
1690       -- concurrent processes
1691       -- order is important here, must check for a concurrent process before
1692       -- a concurrent request.
1693       if concurrent_process_id is not null and
1694              (concurrent_process_id > 0 or concurrent_process_id = -999) then
1695 
1696         -- ignore this value, the real value will be along soon...
1697         if  concurrent_process_id = -999 then
1698             return null;
1699         end if;
1700 
1701         -- see if a transaction context exists for this process
1702         begin
1703           select transaction_context_id
1704             into l_transaction_context_id
1705             from fnd_log_transaction_context
1706             where transaction_type = 'SERVICE'
1707             and transaction_id = concurrent_process_id;
1708 
1709           return l_transaction_context_id;
1710 
1711         exception
1712              when no_data_found then
1713                -- create a new transaction context
1714                l_transaction_type  := 'SERVICE';
1715                l_transaction_id    := concurrent_process_id;
1716                l_component_id      := concurrent_queue_id;
1717                l_component_appl_id := queue_application_id;
1718                l_component_type    := 'SERVICE_INSTANCE';
1719         end;
1720 
1721       -- concurrent requests
1722       elsif conc_request_id is not null and conc_request_id > 0 then
1723 
1724         -- see if a transaction context exists for this request
1725         begin
1726           select transaction_context_id
1727             into l_transaction_context_id
1728             from fnd_log_transaction_context
1729             where transaction_type = 'REQUEST'
1730             and transaction_id = conc_request_id;
1731 
1732           return l_transaction_context_id;
1733 
1734         exception
1735              when no_data_found then
1736                -- create a new transaction context
1737                l_transaction_type  := 'REQUEST';
1738                l_transaction_id    := conc_request_id;
1739                l_component_id      := FND_GLOBAL.conc_program_id;
1740                l_component_appl_id := FND_GLOBAL.prog_appl_id;
1741                l_component_type    := 'CONCURRENT_PROGRAM';
1742         end;
1743 
1744       -- forms
1745       elsif form_id is not null and (form_id > 0 or form_id = -999) then
1746 
1747         l_transaction_id := TXN_SESSION; -- using AUDSID as the transaction_id
1748 
1749          if form_id = -999 then
1750             l_form_id := null;
1751             l_form_application_id := null;
1752          else
1753             l_form_id := form_id;
1754             l_form_application_id := form_application_id;
1755          end if;
1756 
1757         -- see if a transaction context exists for this form
1758         begin
1759           select transaction_context_id
1760             into l_transaction_context_id
1761             from fnd_log_transaction_context
1762             where transaction_type = 'FORM'
1763             and transaction_id = l_transaction_id;
1764 
1765           return l_transaction_context_id;
1766 
1767         exception
1768              when no_data_found then
1769                -- create a new transaction context for this form
1770                l_transaction_type  := 'FORM';
1771                l_component_id      := l_form_id;
1772                l_component_appl_id := l_form_application_id;
1773                l_component_type    := 'FORM';
1774         end;
1775 
1776       -- ICX sessions, ICX transactions
1777       elsif icx_sec.g_session_id is not null and icx_sec.g_session_id > 0 then
1778 
1779         -- see if a transaction context exists for this session
1780         begin
1781           l_component_id := null;
1782 
1783 	  -- Check for finer ICX Transaction
1784           if icx_sec.g_transaction_id is not null and icx_sec.g_transaction_id > 0 then
1785 	    begin
1786           	select transaction_context_id
1787             	  into l_transaction_context_id
1788             	  from fnd_log_transaction_context
1789             	  where transaction_type = 'ICX'
1790             	  and transaction_id = icx_sec.g_transaction_id
1791 		  and session_id = icx_sec.g_session_id
1792 		  and user_id = to_number(l_context(2).a_val)
1793 		  and resp_appl_id = to_number(l_context(3).a_val)
1794 		  and responsibility_id = to_number(l_context(4).a_val)
1795 		  and security_group_id = to_number(l_context(5).a_val)
1796 	          and rownum = 1; -- there maybe previous duplicate rows
1797           	return l_transaction_context_id;
1798 
1799         	exception
1800              	  when no_data_found then
1801                	  -- create a new transaction context
1802 		  null;
1803          /*
1804                	  begin
1805                     select function_id
1806                       into l_component_id
1807                       from icx_transactions
1808                       where transaction_id = icx_sec.g_transaction_id;
1809                     exception
1810                       when others then
1811                         l_component_id := null;
1812                   end;
1813 	  */
1814             end;
1815 
1816 	  else
1817 	  -- Check for coarser ICX Session
1818             begin
1822                   where transaction_type = 'ICX'
1819                 select transaction_context_id
1820                   into l_transaction_context_id
1821                   from fnd_log_transaction_context
1823                   and session_id = icx_sec.g_session_id
1824 		  and transaction_id = -1
1825                   and user_id = to_number(l_context(2).a_val)
1826                   and resp_appl_id = to_number(l_context(3).a_val)
1827                   and responsibility_id = to_number(l_context(4).a_val)
1828                   and security_group_id = to_number(l_context(5).a_val)
1829 	          and rownum = 1; -- there maybe previous duplicate rows
1830                 return l_transaction_context_id;
1831 
1832                 exception
1833                   when no_data_found then
1834                   -- create a new transaction context
1835 		  null;
1836 	  /*
1837                   begin
1838                     select function_id
1839                       into l_component_id
1840                       from icx_sessions
1841                       where session_id = icx_sec.g_session_id;
1842                     exception
1843                       when others then
1844                         l_component_id := null;
1845                   end;
1846 	  */
1847             end;
1848           end if;
1849 
1850           l_transaction_type  := 'ICX';
1851           l_transaction_id    := icx_sec.g_transaction_id;
1852           l_component_appl_id := null;
1853           l_component_type    := 'FUNCTION';
1854         end;
1855 
1856       -- if none of the above, check for 'UNKNOWN' context
1857       else
1858 
1859         begin
1860           select transaction_context_id
1861             into l_transaction_context_id
1862             from fnd_log_transaction_context
1863             where transaction_type = 'UNKNOWN'
1864             and session_id = -1
1865             and transaction_id = -1
1866             and user_id = to_number(l_context(2).a_val)
1867             and resp_appl_id = to_number(l_context(3).a_val)
1868             and responsibility_id = to_number(l_context(4).a_val)
1869             and security_group_id = to_number(l_context(5).a_val)
1870 	    and rownum = 1; -- there maybe previous duplicate rows
1871           return l_transaction_context_id;
1872         exception
1873           when no_data_found then
1874             l_transaction_type := 'UNKNOWN';
1875             l_transaction_id := -1;
1876             l_component_type := null;
1877             l_component_appl_id := -1;
1878             l_component_id := -1;
1879 	end;
1880 
1881       end if;
1882 
1883 
1884      INIT_TRANSACTION_INTERNAL(
1885                P_TRANSACTION_TYPE            => l_transaction_type,
1886                P_TRANSACTION_ID              => l_transaction_id,
1887                P_COMPONENT_TYPE              => l_component_type,
1888                P_COMPONENT_APPL_ID           => l_component_appl_id,
1889                P_COMPONENT_ID                => l_component_id,
1890                P_SESSION_ID                  => to_number(l_context(1).a_val),
1891                P_USER_ID                     => to_number(l_context(2).a_val),
1892                P_RESP_APPL_ID                => to_number(l_context(3).a_val),
1893                P_RESPONSIBILITY_ID           => to_number(l_context(4).a_val),
1894                P_SECURITY_GROUP_ID           => to_number(l_context(5).a_val));
1895 
1896    return FND_LOG.G_TRANSACTION_CONTEXT_ID;
1897 
1898    end INIT_TRANS_INT_WITH_CONTEXT;
1899 
1900 
1901    /*
1902    ** Internal- This routine initializes the logging system from the
1903    ** profiles.  AOL will normally call this routine to initialize the
1904    ** system so the API consumer should not need to call it.
1905    ** The SESSION_ID is a unique identifier (like the ICX_SESSION id)
1906    ** The USER_ID is the name of the apps user.
1907    */
1908    PROCEDURE INIT(SESSION_ID   IN NUMBER default NULL,
1909                   USER_ID      IN NUMBER default NULL) is
1910         POS       NUMBER;
1911         NEXTPOS   NUMBER;
1912 		DATA_SIZE NUMBER;
1913 
1914    begin
1915       if(SESSION_ID is NULL) then
1916          SESSION_ID_X := icx_sec.g_session_id;
1917       else
1918          SESSION_ID_X := SESSION_ID;
1919       end if;
1920 
1921       if(USER_ID is NULL) then
1922          USER_ID_X    := to_number(FND_PROFILE.VALUE('USER_ID'));
1923       else
1924          USER_ID_X := USER_ID;
1925       end if;
1926 
1927       if(USER_ID_X is NULL) then
1928          USER_ID_X    := -1;
1929       end if;
1930 
1931 
1932       if (SUBSTR(FND_PROFILE.VALUE('AFLOG_ENABLED'), 1, 1) = 'Y') then
1933          AFLOG_ENABLED_X     := TRUE;
1934          AFLOG_FILENAME_X    := SUBSTR(FND_PROFILE.VALUE('AFLOG_FILENAME'), 1,
1935                                  255);
1936          AFLOG_LEVEL_X       := TO_NUMBER(FND_PROFILE.VALUE('AFLOG_LEVEL'));
1937          AFLOG_MODULE_X      := UPPER(SUBSTR(
1938                                    FND_PROFILE.VALUE('AFLOG_MODULE'),
1939                                    1, 2000));
1940       else
1941          AFLOG_ENABLED_X     := FALSE;
1942          AFLOG_FILENAME_X    := NULL;
1943          AFLOG_LEVEL_X       := NULL;
1944          AFLOG_MODULE_X      := NULL;
1945       end if;
1946 
1947       /* Set up the global level in the log package so it won't have */
1948       /* to call through in order to find out whether logging is */
1949       /* enabled at this level. */
1950       if (AFLOG_ENABLED_X) then
1951 		FND_LOG.G_CURRENT_RUNTIME_LEVEL := AFLOG_LEVEL_X;
1952 
1953 		/* Tracing disabled for initial 12.0 release
1954         if (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_EXCEPTION) then
1955           DBMS_TRACE.SET_PLSQL_TRACE(DBMS_TRACE.trace_all_exceptions);
1956           fnd_log_enabled_tracing := true;
1957         elsif (fnd_log_enabled_tracing) then
1958           DBMS_TRACE.CLEAR_PLSQL_TRACE;
1959           fnd_log_enabled_tracing := false;
1960 		end if;
1961 		*/
1962       else
1963 		FND_LOG.G_CURRENT_RUNTIME_LEVEL := 99999;
1964 		/*
1965 	    if (fnd_log_enabled_tracing) then
1966           DBMS_TRACE.CLEAR_PLSQL_TRACE;
1967           fnd_log_enabled_tracing := false;
1968 		end if;
1969 		*/
1970       end if;
1971 
1975       else
1972       /* Store away the module list in the module table */
1973       if(AFLOG_MODULE_X is null) then
1974          TABLE_SIZE := 0;
1976          POS := 1;
1977          TABLE_SIZE := 0;
1978          DATA_SIZE := LENGTH(AFLOG_MODULE_X);
1979          while POS <= DATA_SIZE loop
1980             NEXTPOS := INSTR(AFLOG_MODULE_X, ',', POS);
1981             if(NEXTPOS = 0) then
1982                NEXTPOS := DATA_SIZE + 1;
1983             end if;
1984             TABLE_SIZE := TABLE_SIZE + 1;
1985             MODULE_TAB(TABLE_SIZE) := UPPER(LTRIM(RTRIM(
1986                 SUBSTR(AFLOG_MODULE_X, POS, NEXTPOS - POS))))||'%';
1987             POS := NEXTPOS+1; /* Advance past the comma */
1988          end loop;
1989       end if;
1990 
1991       SELF_INITED_X := TRUE;
1992 
1993       /* Deferred Init: All initialization is now deferred to GET_CONTEXT */
1994       FND_LOG.G_TRANSACTION_CONTEXT_ID := null;
1995 
1996    exception
1997      when OTHERS then
1998         /* Make sure that an exception here does not stop Apps initialization */
1999         null;
2000    end;
2001 
2002    /**
2003     *  Private procedure called from AppsLog.java if buffering messages
2004     *  for Bulk logging. AppsLog.java can buffer (if setAsynchMode is enabled)
2005     *  messages with the context returned from this procedure (to preserve
2006     *  the context and sequence) and periodically flushes by calling BULK_INSERT_PVT().
2007     */
2008    PROCEDURE GET_BULK_CONTEXT_PVT (
2009                                 LOG_SEQUENCE_OUT OUT NOCOPY NUMBER,
2010                                 TIMESTAMP_OUT    OUT NOCOPY DATE,
2011                                 DBSESSIONID_OUT  OUT NOCOPY NUMBER,
2012                                 DBINSTANCE_OUT   OUT NOCOPY NUMBER,
2013                                 TXN_ID_OUT       OUT NOCOPY NUMBER
2014                                 ) is
2015      l_context  CONTEXT_ARRAY;
2016    begin
2017 
2018      if(NOT SELF_INITED_X) then
2019        SELF_INIT;
2020        if(FND_LOG.G_TRANSACTION_CONTEXT_ID is null) then
2021 	  GET_CONTEXT(CONTEXT_OUT => l_context);
2022        end if;
2023      end if;
2024 
2025      select FND_LOG_MESSAGES_S.NEXTVAL
2026 	into LOG_SEQUENCE_OUT
2027 	from dual;
2028 
2029      TIMESTAMP_OUT := sysdate;
2030      DBSESSIONID_OUT := TXN_SESSION;
2031      DBINSTANCE_OUT := TXN_INSTANCE;
2032      TXN_ID_OUT := FND_LOG.G_TRANSACTION_CONTEXT_ID;
2033 
2034    end GET_BULK_CONTEXT_PVT;
2035 
2036    /**
2037     *  Private function for Bulk logging messages
2038     */
2039    FUNCTION BULK_INSERT_PVT(MODULE_IN IN FND_TABLE_OF_VARCHAR2_255,
2040                         LOG_LEVEL_IN IN FND_TABLE_OF_NUMBER,
2041                         MESSAGE_TEXT_IN IN FND_TABLE_OF_VARCHAR2_4000,
2042                         SESSION_ID_IN IN FND_TABLE_OF_NUMBER,
2043                         USER_ID_IN IN FND_TABLE_OF_NUMBER,
2044                         TIMESTAMP_IN IN FND_TABLE_OF_DATE,
2045                         LOG_SEQUENCE_IN IN FND_TABLE_OF_NUMBER,
2046                         ENCODED_IN IN FND_TABLE_OF_VARCHAR2_1,
2047                         NODE_IN IN varchar2,
2048                         NODE_IP_ADDRESS_IN IN varchar2,
2049                         PROCESS_ID_IN IN varchar2,
2050                         JVM_ID_IN IN varchar2,
2051                         THREAD_ID_IN IN FND_TABLE_OF_VARCHAR2_120,
2052                         AUDSID_IN IN FND_TABLE_OF_NUMBER,
2053                         DB_INSTANCE_IN IN FND_TABLE_OF_NUMBER,
2054 			TRANSACTION_CONTEXT_ID_IN IN FND_TABLE_OF_NUMBER,
2055 			SIZE_IN IN NUMBER) RETURN NUMBER is
2056   pragma AUTONOMOUS_TRANSACTION;
2057       l_node     varchar2(60);
2058       l_node_ip_address varchar2(30);
2059       l_process_id varchar2(120);
2060       l_jvm_id   varchar2(120);
2061       l_posted   boolean := FALSE;
2062       i          NUMBER;
2063   begin
2064 
2065     if(NOT SELF_INITED_X) then
2066        SELF_INIT;
2067     end if;
2068 
2069     l_node := substrb(NODE_IN,1,60);
2070     l_node_ip_address := substrb(NODE_IP_ADDRESS_IN,1,30);
2071     l_process_id := substrb(nvl(PROCESS_ID_IN, TXN_PROCESS),1,120);
2072     l_jvm_id := substrb(JVM_ID_IN,1,120);
2073 
2074     FORALL i IN 1..SIZE_IN
2075       INSERT INTO FND_LOG_MESSAGES (
2076          MODULE,
2077          LOG_LEVEL,
2078          MESSAGE_TEXT,
2079          SESSION_ID,
2080          USER_ID,
2081          TIMESTAMP,
2082          LOG_SEQUENCE,
2083          ENCODED,
2084          NODE,
2085          NODE_IP_ADDRESS,
2086          PROCESS_ID,
2087          JVM_ID,
2088          THREAD_ID,
2089          AUDSID,
2090          DB_INSTANCE,
2091          TRANSACTION_CONTEXT_ID
2092       ) values
2093       (
2094          MODULE_IN(i),
2095          LOG_LEVEL_IN(i),
2096          MESSAGE_TEXT_IN(i),
2097          SESSION_ID_IN(i),
2098          nvl(USER_ID_IN(i), -1),
2099          nvl(TIMESTAMP_IN(i), sysdate),
2100          nvl(LOG_SEQUENCE_IN(i), FND_LOG_MESSAGES_S.NEXTVAL),
2101          ENCODED_IN(i),
2102          l_node,
2103          l_node_ip_address,
2104          l_process_id,
2105          l_jvm_id,
2106          substrb(THREAD_ID_IN(i),1,120),
2107          AUDSID_IN(i),
2108          DB_INSTANCE_IN(i),
2109          TRANSACTION_CONTEXT_ID_IN(i)
2110       );
2111 
2112     commit;
2113 
2114 
2115     /* Typically there won't be any UNEXPECTED messages logged using this Function */
2116     /* Unexpected errors are posted as exceptions */
2117 /*
2118     FOR i IN 1..SIZE_IN LOOP
2119       if (ENCODED_IN(i) = 'Y') and (LOG_LEVEL_IN(i) = FND_LOG.LEVEL_UNEXPECTED) then
2120          l_posted :=  POST_EXCEPTION(P_MODULE         => MODULE_IN(i),
2121                                      P_LOG_SEQUENCE   => LOG_SEQUENCE_IN(i),
2122                                      P_SESSION_MODULE => NULL,
2126 */
2123                                      P_SESSION_ACTION => NULL);
2124       end if;
2125     END LOOP;
2127     return SIZE_IN;
2128   end BULK_INSERT_PVT;
2129 
2130 /*============================================================================
2131  * Proxy Alerting related Procedures - Start
2132  *===========================================================================*/
2133  /** For Debugging Only
2134  PROCEDURE DUMP_CC is
2135 
2136  BEGIN
2137    DEBUG('=============================================');
2138    DEBUG('G_PRX_CHILD_TRANS_CONTEXT_ID: ' || G_PRX_CHILD_TRANS_CONTEXT_ID);
2139    DEBUG('G_PRX_SESSION_ID: ' || G_PRX_SESSION_ID);
2140    DEBUG('G_PRX_USER_ID: ' || G_PRX_USER_ID);
2141    DEBUG('G_PRX_SESSION_MODULE: ' || G_PRX_SESSION_MODULE);
2142    DEBUG('G_PRX_SESSION_ACTION: ' || G_PRX_SESSION_ACTION);
2143    DEBUG('G_PRX_MODULE: ' || G_PRX_MODULE);
2144    DEBUG('G_PRX_NODE: ' || G_PRX_NODE);
2145    DEBUG('G_PRX_NODE_IP_ADDRESS: ' || G_PRX_NODE_IP_ADDRESS);
2146    DEBUG('G_PRX_PROCESS_ID: ' || G_PRX_PROCESS_ID);
2147    DEBUG('G_PRX_JVM_ID: ' || G_PRX_JVM_ID);
2148    DEBUG('G_PRX_THREAD_ID: ' || G_PRX_THREAD_ID);
2152  */
2149    DEBUG('G_PRX_AUDSID: ' || G_PRX_AUDSID);
2150    DEBUG('G_PRX_DB_INSTANCE: ' || G_PRX_DB_INSTANCE);
2151  END DUMP_CC;
2153 
2154  /**
2155   * Fetches context information for the given concurrent request ID and
2156   * places them in the given CONTEXT_ARRAY output variable.
2157   */
2158  PROCEDURE FETCH_CONTEXT_FOR_CONC_REQ(
2159 	p_request_id IN NUMBER,
2160 	p_info_type IN VARCHAR2 DEFAULT 'ALL',
2161 	p_context_array OUT NOCOPY CONTEXT_ARRAY) is
2162 
2163  BEGIN
2164    --
2165    -- Fetch basic transaction context information for the given request id
2166    --
2167    if (p_info_type = 'ALL') then
2168      begin
2169        	select fcr.requested_by, fcr.responsibility_application_id,
2170 	       fcr.responsibility_id, fcr.security_group_id,
2171 	       'CONCURRENT_PROGRAM', fcr.program_application_id,
2172 	       fcr.concurrent_program_id
2173 	  into
2174 	    p_context_array(CCI_USER_ID).a_val,
2175 	    p_context_array(CCI_RESP_APPL_ID).a_val,
2176 	    p_context_array(CCI_RESPONSIBILITY_ID).a_val,
2177 	    p_context_array(CCI_SECURITY_GROUP_ID).a_val,
2178 	    p_context_array(CCI_COMPONENT_TYPE).a_val,
2179 	    p_context_array(CCI_COMPONENT_APPL_ID).a_val,
2180 	    p_context_array(CCI_COMPONENT_ID).a_val
2181 	  from fnd_concurrent_requests fcr
2182 	  where fcr.request_id = p_request_id;
2183      exception
2184 	when no_data_found then
2185 	    p_context_array(CCI_USER_ID).a_val := null;
2186 	    p_context_array(CCI_RESP_APPL_ID).a_val := null;
2187 	    p_context_array(CCI_RESPONSIBILITY_ID).a_val := null;
2188 	    p_context_array(CCI_SECURITY_GROUP_ID).a_val := null;
2189 	    p_context_array(CCI_COMPONENT_TYPE).a_val := null;
2190 	    p_context_array(CCI_COMPONENT_APPL_ID).a_val := null;
2191 	    p_context_array(CCI_COMPONENT_ID).a_val := null;
2192      end;
2193    end if;
2194    --
2195    -- Attempt to fetch additional info that we might be able to get
2196    --
2197    if (p_info_type = 'ALL' or p_info_type = 'ADDITIONAL') then
2198      begin
2199 	select fcr.requested_by, fcr.oracle_session_id, fcr.os_process_id,
2200 		gv.module, gv.action, '-1'
2201 	  into
2202 	    p_context_array(CCI_USER_ID).a_val,
2203 	    p_context_array(CCI_AUDSID).a_val,
2204 	    p_context_array(CCI_PROCESS_ID).a_val,
2205 	    p_context_array(CCI_SESSION_MODULE).a_val,
2206 	    p_context_array(CCI_SESSION_ACTION).a_val,
2207 	    p_context_array(CCI_SESSION_ID).a_val
2208 	  from fnd_concurrent_requests fcr,
2209 	       gv$session gv
2210 	  where fcr.request_id = p_request_id
2211 		and fcr.oracle_session_id = gv.audsid (+);
2212      exception
2213 	when no_data_found then
2214 	   p_context_array(CCI_USER_ID).a_val := null;
2215 	   p_context_array(CCI_AUDSID).a_val := null;
2216 	   p_context_array(CCI_PROCESS_ID).a_val := null;
2217 	   p_context_array(CCI_SESSION_MODULE).a_val := null;
2218 	   p_context_array(CCI_SESSION_ACTION).a_val := null;
2219 	   p_context_array(CCI_SESSION_ID).a_val := null;
2220      end;
2221    end if;
2222    --
2223    -- Also set some additional variables that we won't be able to fetch
2224    --
2225    p_context_array(CCI_MODULE).a_val := null;
2226    p_context_array(CCI_NODE).a_val := null;
2227    p_context_array(CCI_NODE_IP_ADDRESS).a_val := null;
2228    p_context_array(CCI_JVM_ID).a_val := null;
2229    p_context_array(CCI_THREAD_ID).a_val := null;
2230    p_context_array(CCI_DB_INSTANCE).a_val := null;
2231 
2232  END FETCH_CONTEXT_FOR_CONC_REQ;
2233 
2234   /**
2235    * Initializes a child transaction context using the given information.
2236    *
2237    * If p_transaction_id and p_transaction_type are provided, the procedure
2238    * attempts to fetch additional transaction context.
2239    *
2240    * Otherwise, Procedure INIT_CHILD_CONTEXT will look for transaction context
2241    * values from the context array as follows:
2242    *
2243    * E.g. for child context user id:
2244    * l_user_id := p_child_context_array(CCI_USER_ID).a_val;
2245    */
2246   PROCEDURE INIT_CHILD_CONTEXT (
2247 	p_parent_context_id IN NUMBER,
2248 	p_transaction_id IN NUMBER DEFAULT NULL,
2249 	p_transaction_type IN VARCHAR2 DEFAULT NULL
2250 	--p_child_context_array IN CONTEXT_ARRAY
2251 	) is
2252     l_child_context_exists boolean := TRUE;
2253     l_context_array CONTEXT_ARRAY;
2254     l_child_context_fetched_all boolean := FALSE;
2255   BEGIN
2256     --
2257     -- Initialize child transaction context if necessary
2258     --
2259     if (p_transaction_id is not null and p_transaction_type is not null) then
2260       begin
2261         --
2262         -- Check if child context already exists
2263         --
2264         select transaction_context_id into G_PRX_CHILD_TRANS_CONTEXT_ID
2265 	  from fnd_log_transaction_context
2266 	  where transaction_id = p_transaction_id
2267 	  and transaction_type = p_transaction_type
2268 	  and parent_context_id = p_parent_context_id;
2269       exception
2270 	when no_data_found then
2271 	  l_child_context_exists := FALSE;
2272       end;
2273 
2274       if (l_child_context_exists = FALSE) then
2275 	--
2276 	-- Today we only have a usecase for REQUEST but we can
2277         -- plug-in for other transaction types in the future
2278         -- as we understand more use cases
2279 	--
2280 	if (p_transaction_type = 'REQUEST') then
2281 	  fetch_context_for_conc_req(
2282 		p_request_id => p_transaction_id,
2283 		p_info_type => 'ALL',
2284 		p_context_array => l_context_array);
2285 	  l_child_context_fetched_all := TRUE;
2286 	end if;
2287 
2288 	--
2289 	-- Here, call init_transaction_internal to create a new
2290 	-- row for child context in fnd_log_transaction_context
2291 	--
2292 	init_transaction_internal(
2293 	  p_transaction_type => p_transaction_type,
2294 	  p_transaction_id => p_transaction_id,
2295 	  p_component_type => l_context_array(CCI_COMPONENT_TYPE).a_val,
2299 	  p_user_id => to_number(l_context_array(CCI_USER_ID).a_val),
2296 	  p_component_appl_id => to_number(l_context_array(CCI_COMPONENT_APPL_ID).a_val),
2297 	  p_component_id => to_number(l_context_array(CCI_COMPONENT_ID).a_val),
2298 	  p_session_id => to_number(l_context_array(CCI_SESSION_ID).a_val),
2300 	  p_resp_appl_id => to_number(l_context_array(CCI_RESP_APPL_ID).a_val),
2301 	  p_responsibility_id => to_number(l_context_array(CCI_RESPONSIBILITY_ID).a_val),
2302 	  p_security_group_id => to_number(l_context_array(CCI_SECURITY_GROUP_ID).a_val),
2303 	  p_parent_context_id => p_parent_context_id);
2304       end if;
2305 /*
2306     elsif (p_child_context_array is not null) then
2307 	--
2308 	-- Transaction Id and type were not provided, so we simply
2309 	-- initialize a new transaction context based on the
2310 	-- information provided.
2311 	--
2312 	init_transaction_internal(
2313 	  p_transaction_type => 'UNKNOWN',
2314 	  p_transaction_id => -1,
2315 	  p_component_type => p_child_context_array(CCI_COMPONENT_TYPE),
2316 	  p_component_appl_id => to_number(p_child_context_array(CCI_COMPONENT_APPL_ID).a_val),
2317 	  p_component_id => to_number(p_child_context_array(CCI_COMPONENT_ID).a_val),
2318 	  p_session_id => to_number(p_child_context_array(CCI_SESSION_ID).a_val),
2319 	  p_user_id => to_number(p_child_context_array(CCI_USER_ID).a_val),
2320 	  p_resp_appl_id => to_number(p_child_context_array(CCI_RESP_APPL_ID).a_val),
2321 	  p_responsibility_id => to_number(p_child_context_array(CCI_RESPONSIBILITY_ID).a_val),
2322 	  p_security_group_id => to_number(p_child_context_array(CCI_SECURITY_GROUP_ID).a_val),
2323 	  p_parent_context_id => p_parent_context_id);
2324 */
2325     end if;
2326 
2327     --
2328     -- Now fetch additional context context such as
2329     -- session_action, session_module, etc if we already havent done so
2330     --
2331     if (p_transaction_type = 'REQUEST' and
2332 	l_child_context_fetched_all = FALSE) then
2333 	fetch_context_for_conc_req(
2334 		p_request_id => p_transaction_id,
2335 		p_info_type => 'ADDITIONAL',
2336 		p_context_array => l_context_array);
2337     end if;
2338 
2339     --
2340     -- Set the globals for the additional context information
2341     -- if available.
2342     --
2343     if (p_transaction_type is not null and p_transaction_id is not null) then
2344       G_PRX_SESSION_ID := to_number(l_context_array(CCI_SESSION_ID).a_val);
2345       G_PRX_USER_ID := to_number(l_context_array(CCI_USER_ID).a_val);
2346       G_PRX_SESSION_MODULE := l_context_array(CCI_SESSION_MODULE).a_val;
2347       G_PRX_SESSION_ACTION := l_context_array(CCI_SESSION_ACTION).a_val;
2348       G_PRX_MODULE := l_context_array(CCI_MODULE).a_val;
2349       G_PRX_NODE := l_context_array(CCI_NODE).a_val;
2350       G_PRX_NODE_IP_ADDRESS := l_context_array(CCI_NODE_IP_ADDRESS).a_val;
2351       G_PRX_PROCESS_ID := l_context_array(CCI_PROCESS_ID).a_val;
2352       G_PRX_JVM_ID := l_context_array(CCI_JVM_ID).a_val;
2353       G_PRX_THREAD_ID := l_context_array(CCI_THREAD_ID).a_val;
2354       G_PRX_AUDSID := to_number(l_context_array(CCI_AUDSID).a_val);
2355       G_PRX_DB_INSTANCE := to_number(l_context_array(CCI_DB_INSTANCE).a_val);
2356 /*
2357     elsif (p_child_context_array is not null) then
2358       G_PRX_SESSION_ID := to_number(p_child_context_array(CCI_SESSION_ID).a_val);
2359       G_PRX_USER_ID := to_number(p_child_context_array(CCI_USER_ID).a_val);
2360       G_PRX_SESSION_MODULE := p_child_context_array(CCI_SESSION_MODULE).a_val;
2361       G_PRX_SESSION_ACTION := p_child_context_array(CCI_SESSION_ACTION).a_val;
2362       G_PRX_MODULE := p_child_context_array(CCI_MODULE).a_val;
2363       G_PRX_NODE := l_context_array(CCI_NODE).a_val;
2364       G_PRX_NODE_IP_ADDRESS := p_child_context_array(CCI_NODE_IP_ADDRESS).a_val;
2365       G_PRX_PROCESS_ID := p_child_context_array(CCI_PROCESS_ID).a_val;
2366       G_PRX_JVM_ID := p_child_context_array(CCI_JVM_ID).a_val;
2367       G_PRX_THREAD_ID := p_child_context_array(CCI_THREAD_ID).a_val;
2368       G_PRX_AUDSID := to_number(p_child_context_array(CCI_AUDSID).a_val);
2369       G_PRX_DB_INSTANCE := to_number(p_child_context_array(CCI_DB_INSTANCE).a_val);
2370 */
2371     end if;
2372   END INIT_CHILD_CONTEXT;
2373 
2374 
2375   /**
2376    * API for setting a child context (for proxy alerting) for the given
2377    * concurrent request ID.
2378    *
2379    * This API will first initialize the proxy context (i.e. the current
2380    * transaction context) if not already initialized. It will then
2381    * initialize the child transaction context for the given concurrent
2382    * request ID if it has not been initialized already.
2383    */
2384   PROCEDURE SET_CHILD_CONTEXT_FOR_CONC_REQ (
2385 	p_request_id IN NUMBER ) is
2386     l_context CONTEXT_ARRAY;
2387   BEGIN
2388     -- Initialize the parent (current) transaction context if not
2389     -- already initialized.
2390     if(NOT SELF_INITED_X) then
2391       SELF_INIT;
2392     end if;
2393 
2394     if(FND_LOG.G_TRANSACTION_CONTEXT_ID is null) then
2395       GET_CONTEXT(CONTEXT_OUT => l_context);
2396     end if;
2397 
2398 
2399     -- Now, initialize the child transaction context if not already
2400     -- initialized.
2401     if (G_PRX_CHILD_TRANS_CONTEXT_ID is null) then
2402       INIT_CHILD_CONTEXT(
2403 	p_parent_context_id => fnd_log.g_transaction_context_id,
2404 	p_transaction_id => p_request_id,
2405 	p_transaction_type => 'REQUEST');
2406     end if;
2407 
2408     --DUMP_CC;
2409   END SET_CHILD_CONTEXT_FOR_CONC_REQ;
2410 
2411   /**
2412    * This API clears the G_CHILD_TRANSACTION_CONTEXT_ID variable
2413    * along with any other globals associated with the child
2414    * context for proxy alerting.
2415    */
2416   PROCEDURE CLEAR_CHILD_CONTEXT is
2417 
2418   BEGIN
2419     G_PRX_CHILD_TRANS_CONTEXT_ID := null;
2420     G_PRX_SESSION_MODULE := null;
2421     G_PRX_SESSION_ACTION := null;
2422     G_PRX_MODULE := null;
2423     G_PRX_NODE := null;
2424     G_PRX_NODE_IP_ADDRESS := null;
2425     G_PRX_PROCESS_ID := null;
2429     G_PRX_DB_INSTANCE := null;
2426     G_PRX_JVM_ID := null;
2427     G_PRX_THREAD_ID := null;
2428     G_PRX_AUDSID := null;
2430     G_PRX_SESSION_ID := null;
2431     G_PRX_USER_ID := null;
2432 
2433     --DUMP_CC;
2434   END CLEAR_CHILD_CONTEXT;
2435 
2436 /*============================================================================
2437  * Proxy Alerting related Procedures - End
2438  *===========================================================================*/
2439 
2440 
2441 end FND_LOG_REPOSITORY;