1 package body WF_EVENT as
2 /* $Header: WFEVENTB.pls 120.22.12020000.3 2013/04/25 06:29:14 skandepu ship $ */
3 --------------------------------------------------------------------------
4 /*
5 ** PRIVATE global variables
6 */
7
8 g_packName varchar2(30) :='wf.plsql.wf_event.';
9
10 /*
11 ** Cache Variables
12 ** pv_last_agent_name - the value of agent name
13 ** pv_last_queue_name - the value of queue name, no schema information
14 ** pv_last_schema_name - the value of schema name
15 ** pv_last_recipients - the value of last recipients
16 */
17 pv_last_agent_name varchar2(30);
18 pv_last_queue_name varchar2(80);
19 pv_last_schema_name varchar2(30);
20 pv_last_recipients varchar2(30);
21 pv_last_dequeue_enabled varchar2(7);
22 procedure GetAgentDetails(agent_name in varchar2);
23
24 java_sub varchar2(240) := 'java://';
25
26 NO_SAVEPOINT exception; /* Bug 1840819 */
27 pragma EXCEPTION_INIT(NO_SAVEPOINT,-1086);
28
29 DISPATCH_ERROR exception;
30
31 -- 7625944
32 g_navResetThreshold number; -- threshold to reset navigation to FIRST_MESSAGE
33 -- (applicable to non-TRANSACTIONAL queue agent):
34 -- when reached:
35 -- null value => navigation variable not initialized, will assume default
36 -- navigation (value=0)
37 -- 0 (zero) value => default navigation, ie, navigate rest of queue messages
38 -- value > 0 => limited navigation, ie, navigate messages until number of
39 -- processed messages = g_navResetThreshold, then reset
40 -- message counter and use FIRST_MESSAGE
41 g_currentNavigation BINARY_INTEGER; -- cached value of queue navigation
42 g_processedMessagesCount number :=0; -- count of number of dequeued messages
43 g_groupDequeuing boolean := false; -- flag to mark that dequeueing is by group
44 -- (TRANSACTIONAL), only to be used if
45 -- message grouping is enabled for the agent
46
47 --Cursor to get the group members of one agent group.
48 --We assume that group members are of the same system as agent group.
49 CURSOR agent_group_members(agent_name varchar2,system_name varchar2) is
50 select agt2.name as agt_name,
51 agt2.queue_handler as queue_handler
52 from wf_agent_groups agp ,
53 wf_agents agt1 ,
54 wf_agents agt2 ,
55 wf_systems sys
56 where agt1.name = agent_name
57 and agt1.type = 'GROUP'
58 and agt1.status = 'ENABLED'
59 and agt1.system_guid = sys.guid
60 and sys.name = system_name
61 and agp.group_guid = agt1.guid
62 and agp.member_guid = agt2.guid
63 and agt2.system_guid = sys.guid
64 and agt2.status = 'ENABLED';
65 --------------------------------------------------------------------------
66 /*
67 ** setMessage (PRIVATE) - Generate the Message for this event
68 ** if necessary
69 */
70 PROCEDURE setMessage(p_event in out nocopy wf_event_t)
71 is
72 msg clob;
73 func varchar2(240);
74 cmd varchar2(1000);
75 ename varchar2(240) := p_event.getEventName();
76 ekey varchar2(240) := p_event.getEventKey();
77 eplist wf_parameter_list_t := p_event.getParameterList();
78 executed boolean;
79 -- Note that ORA-06550 is a generic PL/SQL compilation error
80 -- Here it is most likely caused by "Wrong Number of Arguments".
81 plsql_error EXCEPTION;
82 PRAGMA EXCEPTION_INIT(plsql_error, -06550);
83
84 -- bes caching implementation
85 l_event_obj wf_event_obj;
86 begin
87 /*
88 ** mjc We are now going to call this from the dispatcher
89 ** if the subscription rule data is MESSAGE
90 */
91 --if (wf_event.test(ename) = 'MESSAGE') then
92
93 l_event_obj := wf_bes_cache.GetEventByName(ename);
94
95 if (l_event_obj is null) then
96 wf_core.context('Wf_Event', 'setMessage', ename, ekey);
97 wf_core.raise('WFE_EVENT_NOTEXIST');
98 end if;
99
100 func := l_event_obj.GENERATE_FUNCTION;
101
102 if (func is not null) then
103
104 if (wf_log_pkg.level_statement >= fnd_log.g_current_runtime_level) then
105 wf_log_pkg.string2(wf_log_pkg.level_statement,
106 'wf.plsql.wf_event.SetMessage.genfunc_callout',
107 'Start executing generate function - '||func, true);
108 end if;
109
110 WF_BES_DYN_FUNCS.Generate(func,
111 ename,
112 ekey,
113 eplist,
114 msg,
115 executed);
116 if (not executed) then
117 /** The Generate Function has been extended to support the passing
118 of the parameter list as well. To make sure we are compatible
119 with 2.6.0, we catch any error if there are too many parameters
120 and try again with the old API signature (eventname, eventkey)
121 **/
122 -- func came from WF_EVENTS.GENERATE_FUNCTION
123 -- BINDVAR_SCAN_IGNORE
124 cmd := 'begin :v1 := '||func||'(:v2, :v3, :v4); end;';
125 begin
126 execute immediate cmd using in out msg, in ename, in ekey, in eplist;
127 exception
128 when plsql_error then
129 -- BINDVAR_SCAN_IGNORE
130 cmd := 'begin :v1 := '||func||'(:v2, :v3); end;';
131 execute immediate cmd using in out msg, in ename, in ekey;
132 end;
133 end if;
134
135 if (wf_log_pkg.level_statement >= fnd_log.g_current_runtime_level) then
136 wf_log_pkg.string2(wf_log_pkg.level_statement,
137 'wf.plsql.wf_event.SetMessage.genfunc_callout',
138 'End executing generate function - '||func, false);
139 end if;
140
141 else
142 cmd := '<default><event_name>'||ename||'</event_name><event_key>'||
143 p_event.getEventKey()||'</event_key></default>';
144 dbms_lob.createtemporary(msg, FALSE, DBMS_LOB.CALL);
145 dbms_lob.write(msg, length(cmd), 1, cmd);
146 end if;
147
148 p_event.event_data := msg ;
149 -- p_event.setEventData(msg);
150 --end if;
151 exception
152 when others then
153 if (Wf_Core.Error_Name = 'WFE_EVENT_NOTEXIST') then
154 raise;
155 else
156 wf_core.context('Wf_Event', 'setMessage', ename, ekey, func);
157 WF_CORE.Token('ENAME', p_event.event_name);
158 wf_core.token('FUNCTION_NAME', func);
159 WF_CORE.Token('SQLCODE', to_char(sqlcode));
160 WF_CORE.Token('SQLERRM', sqlerrm);
161 WF_CORE.Raise('WFE_DISPATCH_GEN_ERR');
162 end if;
163 end;
164 -----------------------------------------------------------------------
165 /*
166 ** setErrorInfo - <described in WFEVENTS.pls>
167 */
168 PROCEDURE setErrorInfo(p_event in out nocopy wf_event_t,
169 p_type in varchar2)
170 is
171 err_name varchar2(30);
172 err_msg varchar2(2000);
173 err_stack varchar2(2000);
174 begin
175
176 if (wf_log_pkg.level_procedure >= fnd_log.g_current_runtime_level) then
177 wf_log_pkg.string(wf_log_pkg.level_procedure,
178 'wf.plsql.WF_EVENT.setErrorInfo.begin',
179 'Setting Error Info');
180 end if;
181
182 -- First look for a standard WF_CORE exception.
183 wf_core.get_error(err_name, err_msg, err_stack, 2000);
184
185 if (err_name is null) then
186 -- If no WF_CORE exception, look for an Oracle error.
187 err_name := to_char(sqlcode);
188 err_msg := sqlerrm;
189 end if;
190
191 -- set error information into the event --
192 p_event.setErrorMessage(err_msg);
193 p_event.setErrorStack(err_stack);
194 p_event.addParameterToList('ERROR_NAME', err_name);
195 p_event.addParameterToList('ERROR_TYPE', p_type);
196 exception
197 when others then
198 wf_core.context('Wf_Event', 'setErrorInfo', p_event.getEventName());
199 raise;
200 end;
201 -----------------------------------------------------------------------
202 /*
203 ** saveErrorToQueue (PRIVATE) - Save the event to the WF_ERROR queue.
204 */
205 PROCEDURE saveErrorToQueue(p_event in out nocopy wf_event_t)
206 is
207 erragt wf_agent_t;
208 cmd varchar2(1000);
209 begin
210
211 if (wf_log_pkg.level_procedure >= fnd_log.g_current_runtime_level) then
212 wf_log_pkg.string(wf_log_pkg.level_procedure,
213 'wf.plsql.WF_EVENT.saveErrorToQueue.Begin',
214 'saving event to WF_ERROR on '|| wf_event.local_system_name);
215 end if;
216
217 erragt := wf_agent_t('WF_ERROR', wf_event.local_system_name);
218
219 --
220 -- mjc - lets just call the API directly
221 --
222 wf_error_qh.enqueue(p_event, erragt);
223
224 --cmd := 'begin WF_ERROR_QH.enqueue(:v1, :v2); end;';
225 --execute immediate cmd using in p_event,
226 -- in erragt;
227 if (wf_log_pkg.level_procedure >= fnd_log.g_current_runtime_level) then
228 wf_log_pkg.string(wf_log_pkg.level_procedure,
229 'wf.plsql.WF_EVENT.saveErrorToQueue.End',
230 'error info saved');
231 end if;
232 exception
233 when others then
234 wf_core.context('Wf_Event', 'saveErrorToQueue', p_event.getEventName());
235 wf_core.token('FUNCTION_NAME', 'WF_ERROR_QH.enqueue()');
236 --wf_core.raise('WF_EXT_FUNCTION');
237 raise;
238 end;
239 --------------------------------------------------------------------------
240 -----------------------------------------------------------------------
241 /*
242 ** saveErrorToJavaQueue (PRIVATE) - Save the event to the WF_JAVA_ERROR queue.
243 */
244 PROCEDURE saveErrorToJavaQueue(p_event in out nocopy wf_event_t)
245 is
246 erragt wf_agent_t;
247 cmd varchar2(1000);
248 begin
249
250 if (wf_log_pkg.level_procedure >= fnd_log.g_current_runtime_level) then
251 wf_log_pkg.string(wf_log_pkg.level_procedure,
252 'wf.plsql.WF_EVENT.saveErrorToJavaQueue.Begin',
253 'saving event to WF_JAVA_ERROR on '|| wf_event.local_system_name);
254 end if;
255
256 erragt := wf_agent_t('WF_JAVA_ERROR', wf_event.local_system_name);
257
258 --
259 -- mjc - lets just call the API directly
260 --
261 WF_EVENT_OJMSTEXT_QH.enqueue(p_event, erragt);
262
263 --cmd := 'begin WF_ERROR_QH.enqueue(:v1, :v2); end;';
264 --execute immediate cmd using in p_event,
265 -- in erragt;
266 if (wf_log_pkg.level_procedure >= fnd_log.g_current_runtime_level) then
267 wf_log_pkg.string(wf_log_pkg.level_procedure,
268 'wf.plsql.WF_EVENT.saveErrorToJavaQueue.End',
269 'error info saved');
270 end if;
271 exception
272 when others then
273 wf_core.context('Wf_Event', 'saveErrorToQueue', p_event.getEventName());
274 wf_core.token('FUNCTION_NAME', 'WF_EVENT_OJMSTEXT_QH.enqueue()');
275 --wf_core.raise('WF_EXT_FUNCTION');
276 raise;
277 end;
278 --------------------------------------------------------------------------
279 /*
280 ** isDeferToJava (PRIVATE)
281 * returns true : if current subscription is Java or the event has a
282 * Java generate function or there exists a subsequent
283 * Java subscription when max threshold is reached
284 * returns false: otherwise
285 */
286 FUNCTION isDeferToJava(max_threshold_reached in boolean,
287 p_event_name in varchar2,
288 p_source_type in varchar2,
289 p_rule_func in varchar2,
290 p_rule_data in varchar2,
291 p_phase in pls_integer)
292 return boolean
293 is
294 -- bes caching implementation
295 l_event_obj wf_event_obj;
296 l_subs_list wf_event_subs_tab;
297 l_java_defer boolean;
298 l_java_gen boolean;
299 l_phase number;
300 l_rule_func varchar2(240);
301 l_rule_data varchar2(8);
302 begin
303 if (wf_log_pkg.level_procedure >= fnd_log.g_current_runtime_level) then
304 wf_log_pkg.string(wf_log_pkg.level_procedure,
305 'wf.plsql.WF_EVENT.isDeferToJava.begin',
306 'Checking for Java subscription/generate');
307 end if;
308
309 if (p_rule_func is not null AND
310 UPPER(substr(p_rule_func, 0, length(java_sub))) = UPPER(java_sub)) then
311 -- this is a Java subscription. Return true
312 if (wf_log_pkg.level_procedure >= fnd_log.g_current_runtime_level) then
313 wf_log_pkg.string(wf_log_pkg.level_statement,
314 'wf.plsql.WF_EVENT.isDeferToJava.Subscription',
315 'found a Java subscription');
316 end if;
317 return true;
318 end if;
319
320 -- event should be in cache by now
321 l_event_obj := wf_bes_cache.GetEventByName(p_event_name);
322
323 if (l_event_obj is null) then
324 return false;
325 end if;
326
327 -- set flag to true if java generate function is not null
328 if (l_event_obj.JAVA_GENERATE_FUNC is not null) then
329 l_java_gen := true;
330 else
331 l_java_gen := false;
332 end if;
333
334 -- Now Checking Generate Functions
335 if (not max_threshold_reached) then
336
337 if (l_java_gen AND p_rule_data is not null AND
338 p_rule_data = 'MESSAGE' and p_source_type = 'LOCAL') then
339 -- this is a Java generate function.
340 if (wf_log_pkg.level_procedure >= fnd_log.g_current_runtime_level) then
341 wf_log_pkg.string(wf_log_pkg.level_statement,
342 'wf.plsql.WF_EVENT.isDeferToJava.Subscription',
343 'found a Java generate function');
344 end if;
345 return true;
346 else
347 return false;
348 end if;
349 else
350
351 -- we have event and subscription list from the cache
352 -- o if a subsequent subscription has a java rule func
353 -- o if the event has a java generate function and a subsequent
354 -- subscription has MESSAGE rule data
355
356 l_java_defer := false;
357 l_subs_list := wf_bes_cache.GetSubscriptions(p_event_name, p_source_type, null);
358
359 if (l_subs_list is not null) then
360 for i in 1..l_subs_list.COUNT loop
361 l_phase := l_subs_list(i).PHASE;
362 l_rule_func := l_subs_list(i).RULE_FUNCTION;
363 l_rule_data := l_subs_list(i).RULE_DATA;
364
365 if ((l_phase is null OR l_phase > p_phase) AND
366 ((l_rule_data = 'MESSAGE' AND l_java_gen) OR
367 (UPPER(substr(l_rule_func, 0, length(java_sub))) = UPPER(java_sub)))) then
368 l_java_defer := true;
369 exit;
370 end if;
371
372 end loop;
373 end if;
374
375 if(l_java_defer) then
376 if (wf_log_pkg.level_statement >= fnd_log.g_current_runtime_level) then
377 wf_log_pkg.string(wf_log_pkg.level_statement,
378 'wf.plsql.WF_EVENT.isDeferToJava.Subscription',
379 'found subsequent Java sub or java generate');
380 end if;
381 return true;
382 else
383 if (wf_log_pkg.level_procedure >= fnd_log.g_current_runtime_level) then
384 wf_log_pkg.string(wf_log_pkg.level_statement,
385 'wf.plsql.WF_EVENT.isDeferToJava.Subscription',
386 'No Java sub found or Java Generate Found');
387 end if;
388 return false;
389 end if;
390 end if;
391
392 if (wf_log_pkg.level_procedure >= fnd_log.g_current_runtime_level) then
393 wf_log_pkg.string(wf_log_pkg.level_procedure,
394 'wf.plsql.WF_EVENT.isDeferToJava.end',
395 'Checked for Java subscription/generate');
396 end if;
397
398 return false;
399 exception
400 when others then
401 wf_core.context('Wf_Event', 'isDeferToJava', p_event_name);
402 raise;
403 end isDeferToJava;
404
405 --------------------------------------------------------------------------
406 /*
407 ** isSaveToJavaError (PRIVATE)
408 * returns true : if current subscription is Java and source type is ERROR
409 * save to Java Error
410 * returns false: otherwise
411 */
412 FUNCTION isSaveToJavaError(p_event_name in varchar2,
413 p_rule_func in varchar2)
414 return boolean is
415
416 begin
417 if (wf_log_pkg.level_procedure >= fnd_log.g_current_runtime_level) then
418 wf_log_pkg.string(wf_log_pkg.level_procedure,
419 'wf.plsql.WF_EVENT.isSaveToJavaError.begin',
420 'Checking Java Error subscription for ' || p_event_name);
421 end if;
422
423 if (p_rule_func is not null AND
424 UPPER(substr(p_rule_func, 0, length(java_sub))) = UPPER(java_sub)) then
425 -- this is a Java subscription. Return true
426 if (wf_log_pkg.level_procedure >= fnd_log.g_current_runtime_level) then
427 wf_log_pkg.string(wf_log_pkg.level_statement,
428 'wf.plsql.WF_EVENT.isSaveToJavaError.Subscription',
429 'found a Java subscription');
430 end if;
431 return true;
432 end if;
433 return false;
434 end isSaveToJavaError;
435 /*
436 ** GetSkippedSub - utility function to get the subscription has skip onerror
437 ** type
438 */
439 function GetSkippedSub(p_event in wf_event_t)
440 return RAW is
441 l_skip_sub_str VARCHAR2(300);
442 begin
443 l_skip_sub_str := p_event.GETVALUEFORPARAMETER('SKIP_ERROR_SUB');
444 if (l_skip_sub_str is not null) then
445 return hextoraw(l_skip_sub_str);
446 end if;
447 return null;
448 end GetSkippedSub;
449
450 ------------------------------------------------------------------------
451 /*
452 ** dispatch_internal (PRIVATE)
453 */
454 FUNCTION dispatch_internal(p_source_type in varchar2,
455 p_rule_data in varchar2,
456 p_rule_func in varchar2,
457 p_sub_guid in raw,
458 p_source_agent_guid in raw,
459 p_phase in number,
460 p_priority in number,
461 p_event in out nocopy wf_event_t,
462 p_on_error in varchar2)
463 return varchar2
464 is
465 res varchar2(20);
466 cmd varchar2(1000);
467 stat varchar2(10);
468 myfunc varchar2(240);
469 saved boolean := FALSE;
470 eguid raw(16);
471 defagent wf_agent_t;
472 subphase number;
473 genmsg boolean := FALSE;
474 max_threshold_reached boolean := FALSE;
475 defer_to_java boolean := FALSE;
476 save_to_java_error boolean := FALSE;
477 l_skip_sub raw(16);
478 trig_savepoint exception;
479 pragma exception_init(trig_savepoint, -04092);
480 empty_lob_locator exception;
481 pragma exception_init (empty_lob_locator, -22275);
482 msg clob;
483 -- Bug2786192
484 l_rule_func VARCHAR2(240);
485 executed boolean;
486 begin
487 -- Bug 11850350. If database is in PATCH EDITION then
488 -- do not process the event at all. Just return
489 if (wf_core.database_current_edition <> wf_core.database_default_edition) and
490 (p_event.send_date is null or p_event.send_date <= sysdate) then
491 if (wf_log_pkg.level_procedure >= fnd_log.g_current_runtime_level) then
492 wf_log_pkg.string(wf_log_pkg.level_statement,
493 'wf.plsql.WF_EVENT.dispatch_internal',
494 'Database not in RUN edition - discarding event');
495 end if;
496 return 'SUCCESS';
497 end if;
498 -- Verify if the subscription is eligible for execution.
499 if ((wf_event.local_system_status = 'ENABLED' OR
500 wf_event.local_system_status = p_source_type)
501 OR
502 (wf_event.local_system_status <> 'DISABLED' AND
503 p_source_type = 'ERROR'))
504 AND
505 (p_phase >= wf_event.phase_minthreshold) then
506
507 --Bug 2519183
508 --If we are in the deferred processing of an
509 --event we will set back the minthreshold so that its
510 --possible to raise active events within this subscription.
511 --This is after all processed subscriptions have been
512 --discarded hence its fine to set the phase_minthreshold
513 --to zero.
514
515 if ((wf_event.phase_minthreshold > 0) AND
516 (p_event.from_agent is NOT NULL)) then
517 --Bug 3451981
518 --In the case of EXTERNAL events the from_agent will
519 --not be WF_DEFERRED , in this case no further event
520 --executions are possible with any lower phases
521 --(though logically there is No DEFERRED within DEFERRED
522 --and correspondingly here phase of > 100 or not works the
523 --same way so u can always workaround with higher phases
524 --but not good on design)
525 --So we can possibly check if it is 'EXTERNAL'
526 --and as we know from the check of min_threshold
527 --that we are deferprocessing lets re-set it.
528 if ((p_event.from_agent.getName = 'WF_DEFERRED') OR (p_source_type = 'EXTERNAL')) then
529 wf_event.phase_minthreshold := 0;
530 end if ;
531 end if;
532
533 --
534 -- mjc Check if reached the phase threshold and should defer
535 -- If we have encountered a deferred subscription, we will
536 -- get the hell out of Dodge City (aka exiting the loop)
537 -- We should not defer any messages being processed from
538 -- the deferred queue.
539 --
540 -- YOHUANG Bug 4227307
541 -- Error Subscription should never be deferred.
542 if (wf_event.phase_maxthreshold is not null) AND
543 (p_phase >= wf_event.phase_maxthreshold) AND
544 (p_source_type <> 'ERROR')
545 then
546 if (wf_log_pkg.level_procedure >= fnd_log.g_current_runtime_level) then
547 wf_log_pkg.string(wf_log_pkg.level_statement,
548 'wf.plsql.WF_EVENT.dispatch_internal.Subscription',
549 'max threshold reached');
550 end if;
551 max_threshold_reached := true;
552 end if;
553
554 -- check if event needs to be deferred to WF_JAVA_DEFERRED queue
555 if (p_source_type <> 'ERROR') then
556 defer_to_java := isDeferToJava(max_threshold_reached,
557 p_event.getEventName(),
558 p_source_type, p_rule_func,
559 p_rule_data,p_phase);
560 else
561 save_to_java_error := isSaveToJavaError(p_event.getEventName(),
562 p_rule_func);
563 end if;
564
565 if(defer_to_java OR max_threshold_reached ) then
566 if (wf_log_pkg.level_procedure >= fnd_log.g_current_runtime_level) then
567 wf_log_pkg.string(wf_log_pkg.level_statement,
568 'wf.plsql.WF_EVENT.dispatch_internal.Subscription',
569 'detected as deferred');
570 end if;
571 --
572 -- mjc Set action priority now, if we defer, this can be used
573 -- as the priority of the dequeue off the deferred queue
574 --
575 p_event.priority := p_priority;
576
577 -- Set the Deferred Subscription into the event
578 -- We will use this to figure out which phase we will start
579 -- off with during deferred processing
580 p_event.error_subscription := p_sub_guid;
581
582 -- set #CURRENT_PHASE <<sstomar : bug 5870400 >>
583 -- When Last Subscription GUID exist in Event payload but that Subscription
584 -- is not Active/Enabled now. So in such case, Agent Processor doesn't know
585 -- what phase value it should set for Dispatcher to start subscription processing
586 -- (i.e. from which subscription).
587 -- So in such case, Value of #CURRENT_PHASE will be used as starting phase.
588 p_event.AddParameterToList('#CURRENT_PHASE', p_phase);
589
590 if(defer_to_java) then
591 if (wf_log_pkg.level_procedure >= fnd_log.g_current_runtime_level) then
592 wf_log_pkg.string(wf_log_pkg.level_statement,
593 'wf.plsql.WF_EVENT.dispatch_internal.Subscription',
594 'deferring to WF_JAVA_DEFERRED');
595 end if;
596 wf_event.DeferEventToJava(p_source_type, p_event);
597 else
598 if (wf_log_pkg.level_procedure >= fnd_log.g_current_runtime_level) then
599 wf_log_pkg.string(wf_log_pkg.level_statement,
600 'wf.plsql.WF_EVENT.dispatch_internal.Subscription',
601 'deferring to WF_DEFERRED');
602 end if;
603 wf_event.deferevent(p_source_type, p_event);
604 end if;
605 res := 'DEFER';
606
607 elsif (save_to_java_error) then
608 if (wf_log_pkg.level_procedure >= fnd_log.g_current_runtime_level) then
609 wf_log_pkg.string(wf_log_pkg.level_statement,
610 'wf.plsql.WF_EVENT.dispatch_internal.Subscription',
611 'save to java error queue');
612 end if;
613 p_event.error_subscription := p_sub_guid;
614 wf_event.saveErrorToJavaQueue(p_event);
615 res := 'DEFER';
616 else
617 -- Generate Method is irrelavant to subscription.
618 -- Exception happened in Generate Method should be thrown
619 -- up.
620 --
621 -- mjc Check if we are required to Generate Message
622 -- Use dbms_lob.istemporary to see if any clob
623 --
624 begin
625 if (NOT genmsg) AND
626 (p_rule_data = 'MESSAGE') AND
627 (p_source_type = 'LOCAL') then
628 if (wf_log_pkg.level_statement >= fnd_log.g_current_runtime_level) then
629 wf_log_pkg.string(wf_log_pkg.level_statement,
630 'wf.plsql.WF_EVENT.dispatch_internal.Rule_Data',
631 'Rule Data is MESSAGE and Source is LOCAL');
632 end if;
633 -- if dbms_lob.istemporary(p_event.GetEventData()) = 0 then
634 -- Bug Fix for 4286207
635 begin
636 if (p_event.GetEventData() is null) or
637 (p_event.GetEventData() is not null and dbms_lob.getlength(p_event.GetEventData()) = 0) then
638 if (wf_log_pkg.level_statement >= fnd_log.g_current_runtime_level) then
639 wf_log_pkg.string(wf_log_pkg.level_statement,
640 'wf.plsql.WF_EVENT.dispatch_internal.generate',
641 'Need to Generate Message');
642 end if;
643 wf_event.setMessage(p_event);
644 genmsg := TRUE;
645 end if;
646 exception
647 when empty_lob_locator then
648 -- The lob locator is invalid, probably pointing to a empty_clob();
649 if (wf_log_pkg.level_statement >= fnd_log.g_current_runtime_level) then
650 wf_log_pkg.string(wf_log_pkg.level_statement,
651 'wf.plsql.WF_EVENT.dispatch_internal.generate',
652 'Invalid Lob Locator Passed, Generate the Message');
653 end if;
654 wf_event.setMessage(p_event);
655 genmsg := TRUE;
656 end;
657 end if;
658 exception
659 when others then
660 rollback to wf_dispatch_savepoint;
661 p_event.setErrorSubscription(p_sub_guid);
662 wf_event.wf_exception_source := 'RULE';
663 raise;
664 end;
665
666 --If we came here now we can start processing the
667 --subscription
668 --Set the savepoint here for the SKIP mode and not for error
669 --subscriptions
670 if (p_on_error = 'SKIP' and p_source_type <> 'ERROR') then
671 -- trig_savepoint shall not happen otherwise
672 -- the event level savepoint can't be created.
673 savepoint wf_dispatch_internal;
674 end if;
675
676 -- If we are in the process of only executing the skipped
677 -- subscription, we should remove this parameter because
678 -- otherwise there will be indefinite loop in case of
679 -- nested raise.
680 l_skip_sub := GetSkippedSub(p_event);
681
682 if (l_skip_sub is not null AND
683 p_source_type = 'LOCAL') then
684 p_event.AddParameterToList('SKIP_ERROR_SUB', null);
685 end if;
686
687 --
688 -- If there's a rule function defined, run it. Otherwise
689 -- just execute the default dispatch functionality
690 --
691 begin
692
693 if (wf_log_pkg.level_statement >= fnd_log.g_current_runtime_level) then
694 wf_log_pkg.string2(wf_log_pkg.level_statement,
695 'wf.plsql.wf_event.dispatch_internal.rulefunc_callout',
696 'Start executing rule function - '||p_rule_func, true);
697 end if;
698
699 if (p_rule_func is not null) then
700 WF_BES_DYN_FUNCS.RuleFunction(p_rule_func,
701 p_sub_guid,
702 p_event,
703 res,
704 executed);
705 if (not executed) then
706 -- p_rule_func came from WF_EVENT_SUBSCRIPTIONS.Rule_Function or
707 -- WF_EVENT_SUBSCRIPTIONS.Java_Rule_Func
708 myfunc := p_rule_func;
709 -- BINDVAR_SCAN_IGNORE
710 cmd := 'begin :v1 := '||myfunc||'(:v2, :v3); end;';
711 execute immediate cmd using in out res,
712 in p_sub_guid,
713 in out p_event;
714 end if;
715 end if;
716
717 if (wf_log_pkg.level_statement >= fnd_log.g_current_runtime_level) then
718 wf_log_pkg.string2(wf_log_pkg.level_statement,
719 'wf.plsql.wf_event.dispatch_internal.rulefunc_callout',
720 'End executing rule function - '||p_rule_func, false);
721 end if;
722
723 exception
724 when others then
725 if (p_on_error = 'SKIP') then
726 -- Unexpected Exception is treated the same as ERROR
727 -- if the subscription is marked as SKIP
728 res := 'ERROR';
729 else
730 rollback to wf_dispatch_savepoint;
731 p_event.setErrorSubscription(p_sub_guid);
732 p_event.addParameterToList('ERROR_TYPE', 'UNEXPECTED');
733 wf_event.wf_exception_source := 'RULE';
734 WF_CORE.Token('ENAME', p_event.event_name);
735 WF_CORE.Token('EKEY', p_event.event_key);
736 WF_CORE.Token('RULE', myfunc);
737 WF_CORE.Token('SQLCODE', to_char(sqlcode));
738 WF_CORE.Token('SQLERRM', sqlerrm);
739 WF_CORE.Raise('WFE_DISPATCH_RULE_ERR');
740 end if;
741
742 end;
743
744 if (wf_log_pkg.level_statement >= fnd_log.g_current_runtime_level) then
745 -- BINDVAR_SCAN_IGNORE[3]
746 wf_log_pkg.string(wf_log_pkg.level_statement,
747 'wf.plsql.WF_EVENT.dispatch_internal.rule_function',
748 'Executed Rule Function '||myfunc||' and returned '||res);
749 end if;
750
751 end if; -- End of "defer_to_java OR max_threshold_reached"
752 else
753 -- Bug 4227307
754 -- Handle the subscriptions that are not eligible for execution.
755 if (wf_log_pkg.level_statement >= fnd_log.g_current_runtime_level) then
756 wf_log_pkg.string(wf_log_pkg.level_statement,
757 'wf.plsql.wf_event.dispatch_internal.subs_ignore',
758 'Subscription not executed. Sub Phase='||p_phase||
759 ', Min threshold='||wf_event.phase_minthreshold);
760 end if;
761 return 'SUCCESS';
762 end if;
763
764 if (res = 'DEFER' OR res = 'SUCCESS') then
765 return res;
766 end if;
767
768 p_event.addParameterToList('ERROR_TYPE', res);
769 p_event.setErrorSubscription(p_sub_guid);
770
771 if (p_source_type = 'ERROR') then
772 -- If subscription returns error when listener listens on error agent.
773 -- Bug 4207885: Set the exception source to Rule when
774 -- Raising exceptions.
775 wf_event.wf_exception_source := 'RULE';
776 wf_core.token('ENAME', p_event.event_name);
777 wf_core.token('EKEY', p_event.event_key);
778 wf_core.token('SQLERRM', null);
779 wf_core.token('SQLCODE', null);
780 wf_core.raise('WFE_DISPATCH_RULE_ERR');
781 end if;
782
783 if (res = 'ERROR') then
784
785 if (WF_EVENT.g_message_grouping = 'TRANSACTIONAL') then
786 raise dispatch_error;
787 end if;
788
789 begin
790 if (p_on_error = 'SKIP' and p_source_type <> 'ERROR') then
791 rollback to wf_dispatch_internal;
792 p_event.AddParameterToList('SKIP_ERROR_SUB', rawtohex(p_sub_guid));
793 res := 'SKIP_ERROR';
794 else
795 rollback to wf_dispatch_savepoint;
796 end if;
797 exception
798 when NO_SAVEPOINT then
799 -- Bug 1840819
800 -- Catch the no savepoint exception incase commit has happened.
801 -- In this case, the subsequent subscriptions can't be executed
802 -- because is savepoint no longer valid.
803 wf_core.token('EVENT',p_event.getEventName());
804 p_event.setErrorMessage(wf_core.substitute('WFERR',
805 'WFE_COMMIT_IN_DISPATCH'));
806 res := 'TRANSACTION_COMMITED';
807 end;
808 end if;
809
810
811 wf_event.saveErrorToQueue(p_event);
812 p_event.AddParameterToList('SKIP_ERROR_SUB', null);
813 return (res);
814
815 exception
816 when others then
817 wf_core.context('Wf_Event', 'dispatch_internal');
818 raise;
819 end;
820 ---------------------------------------------------------------------------
821 /*
822 ** newAgent - <described in WFEVENTS.pls>
823 */
824 FUNCTION newAgent(p_agent_guid in raw) return wf_agent_t
825 is
826 agt_name varchar2(30);
827 sys_name varchar2(30);
828
829 -- wf bes cache implementation
830 l_agent_obj wf_agent_obj;
831 begin
832 if (p_agent_guid is null) then
833 return null;
834 end if;
835
836 l_agent_obj := wf_bes_cache.GetAgentByGUID(p_agent_guid);
837
838 if (l_agent_obj is not null) then
839 return wf_agent_t(l_agent_obj.NAME, l_agent_obj.SYSTEM_NAME);
840 else
841 wf_core.raise('WFE_AGENT_NOTEXIST');
842 end if;
843 exception
844 when others then
845 wf_core.context('Wf_Event', 'newAgent', p_agent_guid);
846 raise;
847 end;
848 ---------------------------------------------------------------------------
849 /*
850 ** test - <Described in WFEVENTS.pls>
851 */
852 FUNCTION test(p_event_name in varchar2) return varchar2
853 is
854 event_guid raw(16);
855 result varchar2(10) := 'NONE';
856
857 -- bes caching implementation
858 l_event_obj wf_event_obj;
859 l_subs_list wf_event_subs_tab;
860
861 begin
862
863 l_event_obj := wf_bes_cache.GetEventByName(p_event_name);
864
865 -- if event is not found or no subscriptions to the event, return NONE
866 result := 'NONE';
867 if (l_event_obj is not null) then
868 l_subs_list := wf_bes_cache.GetSubscriptions(p_event_name, 'LOCAL', null);
869
870 if (l_subs_list is not null) then
871 result := 'KEY';
872 for i in 1..l_subs_list.COUNT loop
873 if (l_subs_list(i).RULE_DATA = 'MESSAGE') then
874 result := 'MESSAGE';
875 exit;
876 end if;
877 end loop;
878 end if;
879 end if;
880 return result;
881
882 exception
883 when others then
884 wf_core.context('Wf_Event', 'Test', p_event_name);
885 raise;
886 end;
887 ---------------------------------------------------------------------------
888 /*
889 ** send - <Described in WFEVENTS.pls>
890 */
891 PROCEDURE send(p_event in out nocopy wf_event_t) is
892 outguid WF_AGENTS.GUID%TYPE;
893 toagtname WF_AGENTS.NAME%TYPE;
894 toagtsys WF_SYSTEMS.NAME%TYPE;
895 outagtname WF_AGENTS.NAME%TYPE;
896 outagtsys WF_SYSTEMS.NAME%TYPE;
897 l_to_type WF_AGENTS.TYPE%TYPE;
898 -- l_mem_agt_name WF_AGENTS.NAME%TYPE;
899 l_to_queue_handler WF_AGENTS.QUEUE_HANDLER%TYPE;
900
901 -- wf bes cache implementation
902 l_to_agt_obj wf_agent_obj;
903 l_out_agt_obj wf_agent_obj;
904 begin
905 --
906 -- if from_agent is null, pick one from the local system that uses
907 -- the same queue handler (i.e.: same event type)
908 --
909 -- Note: someday, when we support agent groups, we'd loop through
910 -- the group members and derive a list of proper out agents.
911 --
912 if (p_event.GetToAgent() is null AND p_event.GetFromAgent() is null) then
913 -- Either source or destination must be defined.
914 -- Raise Error.
915 wf_core.context('Wf_Event', 'Send', p_event.getEventName());
916 wf_core.raise('Either source or destination must be defined.'); -- wfsql.msg
917 end if;
918
919 if p_event.GetToAgent() is not null then
920 toagtname := p_event.getToAgent().getName();
921 toagtsys := p_event.getToAgent().getSystem();
922 end if;
923
924 if p_event.GetFromAgent() is not null then
925 outagtname := p_event.getFromAgent().getName();
926 outagtsys := p_event.getFromAgent().getSystem();
927 end if;
928
929 if (wf_log_pkg.level_statement >= fnd_log.g_current_runtime_level) then
930 wf_log_pkg.string(wf_log_pkg.level_statement,
931 'wf.plsql.WF_EVENT.Send.info',
932 'To Agt: '||toagtname||' To Agt Sys:'||toagtsys||
933 'Out Agt: '||outagtname||' Out Agt Sys:'||outagtsys);
934 end if;
935
936 -- enqueue() requires that FromAgent not null.
937 -- pick one from the local system that uses the same queue handler (i.e.: same event type)
938 -- as toAgent uses.
939 -- If the toAgent is an agent group, we assume that agent group
940 -- only contain one type of agents.
941 if (p_event.getFromAgent() is null OR
942 p_event.getFromAgent().getName() is null OR
943 p_event.getFromAgent().getSystem() is null) then
944
945 l_to_agt_obj := wf_bes_cache.GetAgentByName(toagtname, toagtsys);
946 if (l_to_agt_obj is not null and l_to_agt_obj.STATUS = 'ENABLED') then
947 l_to_type := l_to_agt_obj.TYPE;
948 l_to_queue_handler := l_to_agt_obj.QUEUE_HANDLER;
949 else
950 raise no_data_found;
951 end if;
952
953 IF (l_to_type = 'GROUP') THEN
954 l_to_queue_handler := NULL;
955 for r_group_members in agent_group_members(toagtname, toagtsys) loop
956 l_to_queue_handler := r_group_members.queue_handler;
957 exit;
958 end loop;
959 if (l_to_queue_handler = null) then
960 raise no_data_found;
961 end if;
962 END IF;
963
964 l_out_agt_obj := wf_bes_cache.GetAgentByQH(l_to_queue_handler, 'OUT');
965
966 if (l_out_agt_obj is not null and l_out_agt_obj.STATUS = 'ENABLED') then
967 outguid := l_out_agt_obj.GUID;
968 outagtname := l_out_agt_obj.NAME;
969 else
970 raise no_data_found;
971 end if;
972
973 p_event.setFromAgent(wf_event.newAgent(outguid));
974 end if;
975
976 if (p_event.getSendDate() is NULL) then
977 p_event.setSendDate(sysdate);
978 end if;
979
980 if (wf_log_pkg.level_statement >= fnd_log.g_current_runtime_level) then
981 wf_log_pkg.string(wf_log_pkg.level_statement,
982 'wf.plsql.WF_EVENT.send.enqueue',
983 'Sending from '||outagtname||' to '||toagtname);
984 end if;
985
986 wf_event.enqueue(p_event);
987 exception
988 when no_data_found then
989 wf_core.context('Wf_Event', 'Send', p_event.getEventName());
990 wf_core.token('AGENT', toagtname);
991 wf_core.raise('WFE_AGENT_NOMATCH');
992 when others then
993 wf_core.context('Wf_Event', 'Send', p_event.getEventName());
994 raise;
995 end;
996 ---------------------------------------------------------------------------
997 /*
998 ** Given out agent and to agent info,
999 ** Figure out the recipient address.
1000 ** PRIVATE: Only called by Set_Recipient_List.
1001 ** Assumption: There will be no group under group, so the to agent
1002 ** passed here must have type AGENT.
1003 */
1004 FUNCTION Get_Recipient(p_out_agent_name in varchar2,
1005 p_out_system_name in varchar2,
1006 p_to_agent_name in varchar2,
1007 p_to_system_name in varchar2,
1008 p_out_queue_handler in varchar2)
1009 return sys.aq$_agent is
1010 l_to_address WF_AGENTS.ADDRESS%TYPE;
1011 l_to_protocol WF_AGENTS.PROTOCOL%TYPE;
1012 l_to_queue_name WF_AGENTS.QUEUE_NAME%TYPE;
1013 l_to_protocol_number NUMBER := 0; -- Hard code as SQLNET
1014
1015 -- wf bes cache implementation
1016 l_to_agt_obj wf_agent_obj;
1017 BEGIN
1018
1019 -- MJC: We need to make sure the recipient address is in the correct
1020 -- format otherwise dequeue will not work.
1021 --
1022 -- Rule 1: Local consumer dequeues from same queue as enqueued
1023 -- --> Address must be null
1024 -- Rule 2: Propagating to local queue
1025 -- --> Address must be <schema>.<queue_name>
1026 -- Rule 3: Propagating to local database
1027 -- --> Address must be <schema>.<queue_name>@dblink
1028
1029 -- YOHUANG: Different Sql queries for different case to
1030 -- improve performance.
1031
1032 l_to_agt_obj := wf_bes_cache.GetAgentByName(p_to_agent_name, p_to_system_name);
1033 if (l_to_agt_obj is not null and l_to_agt_obj.STATUS = 'ENABLED') then
1034 l_to_protocol := l_to_agt_obj.PROTOCOL;
1035 l_to_queue_name := l_to_agt_obj.QUEUE_NAME;
1036 else
1037 return null;
1038 end if;
1039
1040 if (p_to_agent_name = p_out_agent_name and
1041 p_to_system_name = p_out_system_name) then
1042 l_to_address := null;
1043 elsif (p_to_agent_name <> p_out_agent_name and
1044 p_to_system_name = p_out_system_name) then
1045 l_to_address := l_to_queue_name;
1046 -- Bug 7671184 - If message is intended for a remote system use
1047 -- the address of To Agent as To Address for msg propagation
1048 elsif (p_to_system_name <> p_out_system_name) then
1049 l_to_address := l_to_agt_obj.ADDRESS;
1050 end if;
1051
1052 if (wf_log_pkg.level_statement >= fnd_log.g_current_runtime_level) then
1053 wf_log_pkg.string(wf_log_pkg.level_statement,
1054 'wf.plsql.WF_EVENT.Get_Recipient',
1055 'Recipient is name: ' || p_to_agent_name ||
1056 ' address: ' || l_to_address || ' protocol: ' ||l_to_protocol);
1057 end if;
1058
1059 -- Here is where we will add additional protocol mappings as AQ
1060 -- supports new protocols. This bit will form a hardcoded mapping
1061 -- from protocol names as used in the event manager and the
1062 -- protocol numbers used by AQ.
1063
1064 if((l_to_protocol is null) or (l_to_protocol not in ('SQLNET'))) then
1065 wf_core.context('WF_EVENT', 'Get_Recipient', 'Bad Protocol',
1066 l_to_protocol, l_to_queue_name);
1067 end if;
1068
1069 return sys.aq$_agent(p_to_agent_name,
1070 l_to_address,
1071 l_to_protocol_number);
1072 exception
1073 WHEN no_data_found THEN
1074 -- It means that to agent and out agent are not of same type
1075 RETURN null;
1076 end Get_Recipient;
1077
1078 /*
1079 ** If the ToAgent of event is not null(send), set the recipient list
1080 ** address.
1081 ** Only be called if the event.getToAgent() is not null.
1082 */
1083 PROCEDURE Set_Recipient_List(p_event in wf_event_t,
1084 p_out_agent_name in varchar2,
1085 p_out_system_name in varchar2,
1086 x_message_properties in out nocopy dbms_aq.message_properties_t) IS
1087 l_to_type WF_AGENTS.TYPE%TYPE;
1088 l_to_agent_name WF_AGENTS.NAME%TYPE;
1089 l_to_system_name WF_SYSTEMS.NAME%TYPE;
1090 l_out_queue_handler WF_AGENTS.QUEUE_HANDLER%TYPE;
1091 l_recipient_agent sys.aq$_agent;
1092 --Bug 2676549
1093 i number := 0;
1094
1095 -- bes cache implementation
1096 l_to_agt_obj wf_agent_obj;
1097 l_out_agt_obj wf_agent_obj;
1098 BEGIN
1099
1100 -- Ignore if to agent is not set or the out agent is DEFERRED.
1101 if ((p_event.getToAgent() is null) or (p_out_agent_name = 'WF_DEFERRED')) then
1102 return;
1103 end if;
1104
1105 -- if there is a to queue, we need to set the recipient list address
1106 l_to_agent_name := p_event.getToAgent().getName();
1107 l_to_system_name := p_event.getToAgent().getSystem();
1108
1109 if (wf_log_pkg.level_statement >= fnd_log.g_current_runtime_level) then
1110 wf_log_pkg.string(wf_log_pkg.level_statement,
1111 'wf.plsql.WF_EVENT.setRecieptList',
1112 'Setting Recipient List: ' || l_to_agent_name);
1113 end if;
1114
1115 l_to_agt_obj := wf_bes_cache.GetAgentByName(l_to_agent_name, l_to_system_name);
1116 if (l_to_agt_obj is not null and l_to_agt_obj.STATUS = 'ENABLED') then
1117 l_to_type := l_to_agt_obj.TYPE;
1118 else
1119 raise no_data_found;
1120 end if;
1121
1122 l_out_agt_obj := wf_bes_cache.GetAgentByName(p_out_agent_name, p_out_system_name);
1123 if (l_out_agt_obj is not null and l_out_agt_obj.STATUS = 'ENABLED') then
1124 l_out_queue_handler := l_out_agt_obj.QUEUE_HANDLER;
1125 else
1126 raise no_data_found;
1127 end if;
1128
1129 if (l_to_type = 'GROUP') then
1130 --Get the agent / agent group from the cursor
1131 for to_agent in agent_group_members(l_to_agent_name,l_to_system_name) loop
1132 l_recipient_agent := Get_Recipient(p_out_agent_name,
1133 p_out_system_name,
1134 to_agent.agt_name,
1135 l_to_system_name,
1136 l_out_queue_handler);
1137 if (l_recipient_agent IS NOT NULL) then
1138 i:= i + 1;
1139 x_message_properties.recipient_list(i) := l_recipient_agent;
1140 end if;
1141 end loop;
1142 if (i = 0) then
1143 -- There is no qualified agents under this agent group
1144 raise no_data_found;
1145 end if;
1146 else
1147 l_recipient_agent := Get_Recipient(p_out_agent_name,
1148 p_out_system_name,
1149 l_to_agent_name,
1150 l_to_system_name,
1151 l_out_queue_handler);
1152 if (l_recipient_agent IS NOT NULL) then
1153 x_message_properties.recipient_list(1) := l_recipient_agent;
1154 else
1155 -- No qualified agent
1156 raise no_data_found;
1157 end if;
1158 end if ;
1159
1160 END Set_Recipient_List;
1161
1162
1163
1164 /*
1165 ** raise - <Described in WFEVENTS.pls>
1166 */
1167 PROCEDURE raise(p_event_name in varchar2,
1168 p_event_key in varchar2,
1169 p_event_data in clob,
1170 p_parameters in wf_parameter_list_t,
1171 p_send_date in date) is
1172
1173
1174 l_parameters wf_parameter_list_t;
1175
1176 begin
1177 --If parameter list is null then raise the event
1178 --with a dummy parameter list as raise3 requires
1179 --the parameterlist to be input.Else use the input
1180 --parameter list.
1181 if (p_parameters is NOT NULL) then
1182 l_parameters := p_parameters;
1183 else
1184 l_parameters := wf_parameter_list_t();
1185 end if;
1186 --Raise the event
1187 wf_event.raise3(p_event_name,
1188 p_event_key,
1189 p_event_data,
1190 l_parameters,
1191 p_send_date);
1192 exception
1193 when others then
1194 raise;
1195 end;
1196 ---------------------------------------------------------------------------
1197 /*
1198 ** listen - <Described in WFEVENTS.pls>
1199 */
1200 PROCEDURE listen(p_agent_name in varchar2,
1201 p_wait in binary_integer,
1202 p_correlation in varchar2,
1203 p_deq_condition in varchar2) is
1204
1205 l_msg_count NUMBER := 0;
1206 l_err_count NUMBER := 0;
1207 begin
1208
1209 listen(p_agent_name,
1210 p_wait,
1211 p_correlation,
1212 p_deq_condition,
1213 l_msg_count,
1214 l_err_count);
1215
1216 end;
1217 /*
1218 ** listen - <Described in WFEVENTS.pls>
1219 */
1220 PROCEDURE listen(p_agent_name in varchar2,
1221 p_wait in binary_integer,
1222 p_correlation in varchar2,
1223 p_deq_condition in varchar2,
1224 p_message_count in out nocopy number,
1225 p_max_error_count in out nocopy number) is
1226
1227 from_agt_name varchar2(30);
1228 from_agt_sys varchar2(30);
1229 st varchar2(10) := 'LOCAL';
1230 dir varchar2(10);
1231 qh varchar2(240);
1232 stat varchar2(10);
1233 agt raw(16);
1234 sagt raw(16);
1235 evt wf_event_t;
1236 evt_name VARCHAR2(240);
1237 evt_errmsg VARCHAR2(4000);
1238 -- Local Variable, reset everytime the method is called.
1239 l_lsn_msg_count NUMBER := 0;
1240 l_error_count NUMBER := 0;
1241
1242 l_queue_name varchar2(80);
1243 q_name VARCHAR2(80);
1244 l_enqueue_enabled VARCHAR2(30);
1245 l_dequeue_enabled VARCHAR2(30);
1246 l_queueTable VARCHAR2(30);
1247
1248 -- bes caching implementation
1249 l_agent_obj wf_agent_obj;
1250
1251 begin
1252
1253 -- return an error if listen is invoked on WF_JAVA_DEFERRED or
1254 -- WF_JAVA_ERROR agents
1255 if (p_agent_name = 'WF_JAVA_DEFERRED') OR
1256 (p_agent_name = 'WF_JAVA_ERROR') then
1257 return;
1258 end if;
1259
1260 -- Validate the msg count and error count parameters
1261 if (p_message_count is null or p_message_count < 0) then
1262 p_message_count := 0;
1263 end if;
1264
1265 if (p_max_error_count is null or p_max_error_count < 0) then
1266 p_max_error_count := 0;
1267 end if;
1268
1269 if ((p_correlation is not NULL) and (p_deq_condition is not NULL)) then
1270 WF_CORE.Context('WF_EVENT', 'Listen', p_agent_name, p_correlation,
1271 p_deq_condition);
1272 WF_CORE.Raise('WFE_CORRID_VS_CONDITION');
1273
1274 end if;
1275
1276 -- lookup agent info --
1277 --<rwunderl:2749563> Tuned and separated sql statement for better performance
1278 --<rwunderl:2792298> restricting Listen() to local system.
1279 if (WF_EVENT.g_local_system_guid is NULL) then
1280 g_local_system_guid := hextoraw(WF_CORE.Translate('WF_SYSTEM_GUID'));
1281 end if;
1282
1283 -- get the agent information for the local system
1284 l_agent_obj := wf_bes_cache.GetAgentByName(p_agent_name, null);
1285 if (l_agent_obj is not null) then
1286 agt := l_agent_obj.GUID;
1287 dir := upper(l_agent_obj.DIRECTION);
1288 else
1289 raise no_data_found;
1290 end if;
1291
1292 -- Bug 2307433, 3271311, Use StartAgent as single Source of truth
1293 -- StartAgent becomes the single source to start a particular agent
1294 -- and can be called without worrying about fixed name queues.
1295 StartAgent(p_agent_name);
1296
1297 -- set default parameters for queue navigation if not previously set
1298 if (g_navResetThreshold is null) then
1299 wf_event.setNavigationParams(p_agent_name, 0);
1300 end if;
1301
1302 if (WF_EVENT.g_message_grouping = 'TRANSACTIONAL') then
1303 if ((p_correlation is NULL) and (p_deq_condition is NULL)) then
1304 --This is a transactional queue, we will go ahead and call
1305 --the proper api.
1306 WF_EVENT.Listen_GRP(p_agent_name, p_wait);
1307 return;
1308
1309 else
1310 --This is a transactional queue, but since there was a correlation id
1311 --passed, we cannot call Listen_GRP, so we will raise an error to the
1312 --caller to resolve.
1313 wf_core.context('Wf_Event', 'Listen', p_agent_name);
1314 wf_core.token('AGENT', p_agent_name);
1315 wf_core.token('API', 'WF_EVENT.Listen_GRP');
1316 wf_core.raise('WFE_TRXN_QUEUE');
1317
1318 end if;
1319 end if;
1320
1321 -- set source type --
1322 if (p_agent_name = 'WF_ERROR') then
1323 st := 'ERROR';
1324 elsif (dir = 'IN') then
1325 st := 'EXTERNAL';
1326 end if;
1327
1328 -- check system status
1329 -- stat := wf_core.translate('WF_SYSTEM_STATUS');
1330 -- Set the account name - only need this for WF_DEFERRED
1331 wf_event.SetAccountName;
1332
1333 if (wf_event.local_system_status = 'DISABLED' OR
1334 wf_core.database_current_edition <> wf_core.database_default_edition) then
1335 return;
1336 end if;
1337
1338 if (wf_event.local_system_status in ('LOCAL','EXTERNAL')) then
1339 if (st = wf_event.local_system_status
1340 OR st = 'ERROR'
1341 OR p_agent_name = 'WF_DEFERRED') then
1342 if (wf_log_pkg.level_statement >= fnd_log.g_current_runtime_level) then
1343 wf_log_pkg.string(wf_log_pkg.level_statement,
1344 'wf.plsql.WF_EVENT.listen.Check1',
1345 'Source type is equal to system status '||
1346 'or ERROR or Deferred Processing');
1347 end if;
1348 else
1349 if (wf_log_pkg.level_statement >= fnd_log.g_current_runtime_level) then
1350 wf_log_pkg.string(wf_log_pkg.level_statement,
1351 'wf.plsql.WF_EVENT.listen.Check2',
1352 'Source type not valid for current system status');
1353 end if;
1354 return;
1355 end if;
1356 end if;
1357
1358 -- bug 7828862 Cache apps context before dispatching events
1359 wfa_sec.Cache_Ctx();
1360
1361 -- We need to explicitly make sure that if someones Queue Handler
1362 -- blows up we rollback the transaction, just in case they don't
1363 begin
1364 savepoint bes_before_dequeue_qh;
1365 wf_event.dequeue(agt, evt, qh, p_wait, p_correlation, p_deq_condition);
1366
1367 exception
1368 when others then
1369 wf_event.wf_exception_source := 'QH';
1370 rollback to bes_before_dequeue_qh;
1371 raise;
1372 end;
1373
1374 -- Add support MAX_LSN_MSG_COUNT and MAX_ERROR_COUNT
1375 -- to mimic JAVA GSC Framework implementation
1376 -- Listen will return back to caller if either MAX NUMBER
1377 -- of messages are read or max number of errors happened.
1378 while (evt is not null) loop
1379
1380 l_lsn_msg_count := l_lsn_msg_count + 1;
1381 if (st <> 'ERROR') then
1382 if (evt.getFromAgent() is null) then
1383 sagt := NULL;
1384 else
1385 from_agt_name := evt.getFromAgent().getName();
1386 from_agt_sys := evt.getFromAgent().getSystem();
1387
1388 if (wf_log_pkg.level_statement >= fnd_log.g_current_runtime_level) then
1389 wf_log_pkg.string(wf_log_pkg.level_statement,
1390 'wf.plsql.WF_EVENT.listen',
1391 'Event '||evt.getEventName()||
1392 ', hailing from '||from_agt_name||'@'||from_agt_sys||
1393 ' was dequeued from '||p_agent_name);
1394 end if;
1395 -- get the from agent guid
1396 GetSourceAgentGUID(agent_name => from_agt_name,
1397 agent_system => from_agt_sys,
1398 agent_guid => sagt);
1399 end if;
1400 else
1401 sagt := NULL;
1402
1403 -- Bug 2032654
1404 -- 1. Determine if the event name is null
1405 -- 2. If the event name is NULL, it should be defaulted to UNEXPECTED_ERROR.
1406 -- 3. The text Event Name is NULL is appended to the error message.
1407 evt_name := evt.getEventName;
1408
1409 IF evt_name IS NULL THEN
1410 evt.setEventName('UNEXPECTED_ERROR');
1411 evt.setEventKey('UNEXPERR');
1412 evt_errmsg := evt.getErrorMessage || wf_core.newline ||
1413 wf_core.translate('WF_EVTNAME_NULL');
1414 evt.setErrorMessage(wf_core.translate('WF_EVTNAME_NULL'));
1415 END IF;
1416 end if;
1417
1418 -- Check if we are doing deferred processing
1419 -- Bug 2210085 - starting a new block to capture exceptions thrown
1420 -- by GetDeferEventCtx
1421 begin
1422 if p_agent_name = 'WF_DEFERRED' then
1423 if (wf_log_pkg.level_statement >= fnd_log.g_current_runtime_level) then
1424 wf_log_pkg.string(wf_log_pkg.level_statement,
1425 'wf.plsql.WF_EVENT.listen.Deferred',
1426 'Processing Deferred Event');
1427 end if;
1428
1429 wf_event.GetDeferEventCtx(st,from_agt_name,from_agt_sys,evt);
1430 -- dispatcher should process all subscriptions
1431 wf_event.phase_maxthreshold := null;
1432 end if;
1433
1434 begin
1435 -- Dispatcher will throw exception in the following unexpected errors
1436 -- Defer Event Failed
1437 -- Generate Message Failed
1438 -- Rule Function Failed
1439 -- Unable to Save to Error Queue
1440 -- Unable to rollback to savepoint.
1441 -- Listen will swallow all of these exceptions unless the unexpected
1442 -- exception happened when processing error queue
1443 wf_event.dispatch(st, sagt, evt);
1444
1445 -- We only count consecutive unexpected errors
1446 l_error_count := 0;
1447 commit;
1448
1449 -- 7828862 Restore apps context from cached values
1450 wfa_sec.Restore_Ctx();
1451 exception
1452 when others then
1453 -- 7828862 Restore apps context from cached values
1454 wfa_sec.Restore_Ctx();
1455
1456 if (wf_event.wf_exception_source = 'RULE') then
1457 if (st = 'ERROR') then
1458 if (wf_log_pkg.level_error >= fnd_log.g_current_runtime_level) then
1459 wf_log_pkg.string(wf_log_pkg.level_error,
1460 'wf.plsql.WF_EVENT.listen.dispatch_error',
1461 'Rule Function with Source Error Exception');
1462 end if;
1463 raise;
1464 else
1465 if (wf_log_pkg.level_error >= fnd_log.g_current_runtime_level) then
1466 wf_log_pkg.string(wf_log_pkg.level_error,
1467 'wf.plsql.WF_EVENT.listen.dispatch_error',
1468 'Rule Function Error');
1469 end if;
1470 wf_event.setErrorInfo(evt, 'ERROR');
1471 wf_event.saveErrorToQueue(evt);
1472 commit;
1473 l_error_count := l_error_count + 1;
1474 end if;
1475 else
1476 if (wf_log_pkg.level_error >= fnd_log.g_current_runtime_level) then
1477 wf_log_pkg.string(wf_log_pkg.level_error,
1478 'wf.plsql.WF_EVENT.listen.dispatch_error',
1479 'Non Rule Function Error');
1480 end if;
1481 -- Bug 4207885: Set the exception source to be WF.
1482 wf_event.wf_exception_source := 'WF';
1483 commit;
1484 raise;
1485 end if;
1486 end;
1487 -- Bug 2210085
1488 exception
1489 when others then
1490 -- 7828862 Restore apps context from cached values
1491 wfa_sec.Restore_Ctx();
1492
1493 -- Bug 2608037
1494 -- If the execution of rule function had failed and if the
1495 -- agent is the error queue then there is no point in enqueueing
1496 -- the event again into the error queue.
1497 -- In this case we just rollback the dequeue and raise the
1498 -- exception to the user.
1499 if (( wf_event.wf_exception_source = 'RULE') and (st = 'ERROR')) then
1500 if (wf_log_pkg.level_error >= fnd_log.g_current_runtime_level) then
1501 wf_log_pkg.string(wf_log_pkg.level_error,
1502 'wf.plsql.WF_EVENT.listen.dispatch_error',
1503 'Error executing Rule Function with Source Type Error');
1504 end if;
1505 rollback to bes_before_dequeue_qh;
1506
1507 -- Error WFE_DISPATCH_RULE_ERR already has sufficient info on the error.
1508 -- Just raise it
1509 if (wf_core.error_name = 'WFE_DISPATCH_RULE_ERR') then
1510 raise;
1511 else
1512 wf_core.token('ENAME', evt.event_name);
1513 wf_core.token('EKEY', evt.event_key);
1514 wf_core.token('SQLERRM', sqlerrm);
1515 wf_core.token('SQLCODE', sqlcode);
1516 wf_core.raise('WFE_UNHANDLED_ERROR');
1517 end if;
1518 elsif (wf_event.wf_exception_source = 'WF') then
1519 -- Bug 4207885: Add the handler of exception with source WF
1520 if (wf_log_pkg.level_error >= fnd_log.g_current_runtime_level) then
1521 wf_log_pkg.string(wf_log_pkg.level_error,
1522 'wf.plsql.WF_EVENT.listen.dispatch_error',
1523 'Unexpected Function Error');
1524 end if;
1525 wf_core.token('ENAME', evt.event_name);
1526 wf_core.token('EKEY', evt.event_key);
1527 wf_core.token('SQLERRM', sqlerrm);
1528 wf_core.token('SQLCODE', sqlcode);
1529 wf_core.raise('WFE_UNHANDLED_ERROR');
1530 else
1531 if (wf_log_pkg.level_error >= fnd_log.g_current_runtime_level) then
1532 wf_log_pkg.string(wf_log_pkg.level_error,
1533 'wf.plsql.WF_EVENT.listen.error',
1534 'GetDeferEventCtx Error');
1535 end if;
1536 wf_event.setErrorInfo(evt,'ERROR');
1537 wf_event.saveErrorToQueue(evt);
1538 commit;
1539 l_error_count := l_error_count + 1;
1540 end if;
1541 end;
1542
1543 -- check system status
1544 stat := wf_core.translate('WF_SYSTEM_STATUS');
1545 if ((stat <> 'ENABLED') AND (st <> stat)) then
1546 exit;
1547 end if;
1548
1549 evt := null;
1550 wf_event.InitPhaseMinThreshold;
1551 wf_event.SetDispatchMode('SYNC');
1552
1553 if (p_message_count > 0 AND l_lsn_msg_count >= p_message_count ) then
1554 if (wf_log_pkg.level_statement >= fnd_log.g_current_runtime_level) then
1555 wf_log_pkg.string(wf_log_pkg.level_statement,
1556 'wf.plsql.WF_EVENT.listen.maxMsgCount',
1557 'Read the specified maximum number of messages');
1558 end if;
1559 exit;
1560 end if;
1561
1562 if (p_max_error_count > 0 AND l_error_count >= p_max_error_count ) then
1563 if (wf_log_pkg.level_error >= fnd_log.g_current_runtime_level) then
1564 wf_log_pkg.string(wf_log_pkg.level_error,
1565 'wf.plsql.WF_EVENT.listen.maxErrCount',
1566 'Encountered the specified maximum number of errors');
1567 end if;
1568 exit;
1569 end if;
1570
1571 -- We need to explicitly make sure that if someones Queue Handler
1572 -- blows up we rollback the transaction, just in case they don't
1573 begin
1574 savepoint bes_before_dequeue_qh;
1575 wf_event.dequeue(agt, evt, qh, p_wait, p_correlation, p_deq_condition);
1576 exception
1577 when others then
1578 wf_event.wf_exception_source := 'QH';
1579 rollback to bes_before_dequeue_qh;
1580 raise;
1581 end;
1582 end loop;
1583
1584 -- return back the actual read message count
1585 p_message_count := l_lsn_msg_count ;
1586 -- return back the actual error message count
1587 -- Normally l_lsn_msg_count >= l_error_count;
1588 p_max_error_count := l_error_count;
1589
1590 exception
1591 when no_data_found then
1592 -- 7828862 Restore apps context from cached values
1593 wfa_sec.Restore_Ctx();
1594 if (wf_event.wf_exception_source = 'WF'
1595 OR wf_event.wf_exception_source = 'QH') then
1596 raise;
1597 else
1598 wf_core.context('Wf_Event', 'Listen', p_agent_name);
1599 wf_core.raise('WFE_AGENT_NOTEXIST');
1600 end if;
1601 when others then
1602 wf_core.context('Wf_Event', 'Listen', p_agent_name);
1603 -- 7828862 Restore apps context from cached values
1604 wfa_sec.Restore_Ctx();
1605 raise;
1606 end Listen;
1607 ---------------------------------------------------------------------------
1608 /*
1609 ** listen_concurrent - <Described in WFEVENTS.pls>
1610 */
1611 --Bug 2505487
1612 --Included the AQ wait parameter for the listen_concurrent
1613
1614 PROCEDURE listen_concurrent(errbuf out nocopy varchar2,
1615 retcode out nocopy varchar2,
1616 p_agent_name in varchar2,
1617 p_correlation in varchar2,
1618 p_deq_condition in varchar2,
1619 p_wait in binary_integer) is
1620 errname varchar2(30);
1621 errmsg varchar2(2000);
1622 errstack varchar2(4000);
1623 l_p_wait binary_integer;
1624 l_correlation varchar2(128);
1625
1626 begin
1627 --Bug 2505487
1628 --Any -ve number for the parameter p_wait in the forms
1629 --is accepted as wait forever.
1630 if (p_wait < 0) then
1631 l_p_wait := dbms_aq.forever ;
1632 else
1633 l_p_wait := p_wait;
1634 end if;
1635
1636 --<rwunderl:2751674>
1637 if (UPPER(p_correlation) = 'NULL') then
1638 l_correlation := NULL;
1639
1640 else
1641 l_correlation := p_correlation;
1642
1643 end if;
1644 --</rwunderl:2751674>
1645
1646 --Bug 2649327
1647 --The deq condition is not used at present for dequeuing
1648 -- Hence setting it to NULL.
1649 wf_event.listen(p_agent_name => p_agent_name,
1650 p_wait => l_p_wait,
1651 p_correlation => l_correlation,
1652 p_deq_condition=>NULL);
1653
1654 -- Return 0 for successful completion --
1655 errbuf := '';
1656 retcode := '0';
1657 exception
1658 when others then
1659 wf_core.get_error(errname, errmsg, errstack);
1660 if (errmsg is not null) then
1661 errbuf := errmsg;
1662 else
1663 errbuf := sqlerrm;
1664 end if;
1665
1666 -- Return 2 for error --
1667 retcode := '2';
1668 end;
1669
1670 ---------------------------------------------------------------------------
1671 /*
1672 ** listen_grp - <Described in WFEVENTS.pls>
1673 */
1674 PROCEDURE listen_grp(p_agent_name in varchar2,
1675 p_wait in binary_integer) is
1676
1677 from_agt_name varchar2(30);
1678 from_agt_sys varchar2(30);
1679 st varchar2(10) := 'EXTERNAL';
1680 qh varchar2(240);
1681 stat varchar2(10);
1682 agt raw(16);
1683 sagt raw(16);
1684 evt wf_event_t;
1685 err_evt wf_event_t;
1686 evt_errmsg VARCHAR2(4000);
1687 l_queueTable VARCHAR2(30); --<rwunderl:2749563/>
1688 end_of_transaction exception;
1689 pragma exception_init (end_of_transaction, -25235);
1690
1691 -- bes caching implementation
1692 l_agent_obj wf_agent_obj;
1693 begin
1694
1695 -- Confirm that p_agent_name includes a transactional queue.
1696 --<rwunderl:2749563> Tuned and separated sql statement for better performance
1697 --<rwunderl:2792298> restricting Listen() to local system.
1698 if (WF_EVENT.g_local_system_guid is NULL) then
1699 g_local_system_guid := hextoraw(WF_CORE.Translate('WF_SYSTEM_GUID'));
1700 end if;
1701
1702 GetAgentDetails(p_agent_name);
1703
1704 -- get agent details for local system
1705 l_agent_obj := wf_bes_cache.GetAgentByName(p_agent_name, null);
1706 if (l_agent_obj is null) then
1707 wf_core.context('Wf_Event', 'Listen_GRP', p_agent_name);
1708 wf_core.raise('WFE_AGENT_NOTEXIST');
1709 end if;
1710 qh := l_agent_obj.queue_handler;
1711 agt := l_agent_obj.guid;
1712
1713
1714 if (WF_EVENT.g_message_grouping <> 'TRANSACTIONAL') then
1715 --This is not a transactional queue.
1716 WF_CORE.Context('Wf_Event', 'Listen_GRP', p_agent_name);
1717 WF_CORE.Token('AGENT', p_agent_name);
1718 WF_CORE.Token('API', 'WF_EVENT.Listen');
1719 WF_CORE.Raise('WFE_NONTRXN_QUEUE');
1720 end if;
1721
1722 --Verifying that the system is not disabled.
1723 if (wf_event.local_system_status = 'DISABLED' OR
1724 wf_core.database_current_edition <> wf_core.database_default_edition) then
1725 return;
1726 end if;
1727
1728 /*
1729 ** We need to explicitly make sure that if someones Queue Handler
1730 ** blows up we rollback the transaction, just in case they don't
1731 */
1732 loop --Outer loop to process all transactions.
1733 WF_CORE.Clear; --Clear any tokens that were set from the previous
1734 --transaction dequeue.
1735
1736 begin --We will begin processing a transaction (message group).
1737 savepoint trxn_start;
1738
1739 if (wf_log_pkg.level_statement >= fnd_log.g_current_runtime_level) then
1740 wf_log_pkg.string(wf_log_pkg.level_statement,
1741 'wf.plsql.WF_EVENT.Listen_GRP.processing',
1742 'Begin processing transaction');
1743 end if;
1744
1745 begin
1746
1747 -- Dequeue the first message in the transaction
1748 savepoint bes_before_dequeue_qh;
1749 wf_event.dequeue(agt, evt, qh,p_wait);
1750
1751 exception
1752 when end_of_transaction then
1753 if (wf_log_pkg.level_event >= fnd_log.g_current_runtime_level) then
1754 wf_log_pkg.string(wf_log_pkg.level_event,
1755 'wf.plsql.WF_EVENT.Listen_GRP.complete',
1756 'End of the transaction');
1757 end if;
1758
1759 -- reset navigation
1760 wf_event.resetNavigationParams;
1761 commit;
1762
1763 when others then
1764 wf_event.wf_exception_source := 'QH';
1765 rollback to bes_before_dequeue_qh;
1766 raise;
1767
1768 end;
1769
1770 while (evt is not null) loop
1771
1772 if (evt.getFromAgent() is null) then
1773 sagt := NULL;
1774 else
1775 from_agt_name := evt.getFromAgent().getName();
1776 from_agt_sys := evt.getFromAgent().getSystem();
1777
1778 if (wf_log_pkg.level_statement >= fnd_log.g_current_runtime_level) then
1779 wf_log_pkg.string(wf_log_pkg.level_statement,
1780 'wf.plsql.WF_EVENT.Listen_GRP.event_dequeued',
1781 'Event '||evt.getEventName()||', hailing from '||from_agt_name||'@'||
1782 from_agt_sys|| ' was dequeued from '|| p_agent_name);
1783 end if;
1784
1785 -- get the from agent guid
1786 GetSourceAgentGUID(agent_name => from_agt_name,
1787 agent_system => from_agt_sys,
1788 agent_guid => sagt);
1789 end if;
1790
1791 /* Bug 2032654
1792 1. Determine if the event name is null
1793 2. If the event name is NULL, it should be defaulted to
1794 UNEXPECTED_ERROR.
1795 3. The text Event Name is NULL is appended to the error
1796 message. */
1797
1798
1799 if (evt.getEventName) is NULL then
1800 evt.setEventName('UNEXPECTED_ERROR');
1801 evt.setEventKey('UNEXPERR');
1802 evt_errmsg := evt.getErrorMessage || wf_core.newline ||
1803 wf_core.translate('WF_EVTNAME_NULL');
1804 evt.setErrorMessage(wf_core.translate('WF_EVTNAME_NULL'));
1805 END IF;
1806
1807
1808 -- Begin Dispatching the event message.
1809
1810 begin
1811 wf_event.dispatch(st, sagt, evt);
1812
1813 exception
1814 when others then
1815 if (wf_log_pkg.level_error >= fnd_log.g_current_runtime_level) then
1816 wf_log_pkg.string(wf_log_pkg.level_error,
1817 'wf.plsql.WF_EVENT.Listen_GRP.dispatch_error',
1818 'Dispatch Error when dispatching Event '||evt.getEventName);
1819 end if;
1820 raise dispatch_error;
1821
1822 end;
1823
1824 -- check system status --
1825 stat := wf_core.translate('WF_SYSTEM_STATUS');
1826 if ((stat <> 'ENABLED') AND (st <> stat)) then
1827 exit;
1828 end if;
1829
1830 evt := null;
1831 wf_event.InitPhaseMinThreshold;
1832 wf_event.SetDispatchMode('SYNC');
1833
1834 begin
1835 savepoint bes_before_dequeue_qh;
1836 wf_event.dequeue(agt, evt, qh,p_wait);
1837
1838 exception
1839 when end_of_transaction then
1840 if (wf_log_pkg.level_event >= fnd_log.g_current_runtime_level) then
1841 wf_log_pkg.string(wf_log_pkg.level_event,
1842 'wf.plsql.WF_EVENT.Listen_GRP.complete',
1843 'End of the transaction');
1844 end if;
1845
1846 -- reset navigation
1847 wf_event.resetNavigationParams;
1848 commit;
1849
1850 when others then
1851 wf_event.wf_exception_source := 'QH';
1852 rollback to bes_before_dequeue_qh;
1853 raise;
1854
1855 end;
1856
1857 end loop;
1858
1859
1860
1861 exception
1862 when dispatch_error then
1863 --Dequeue the rest of the transaction
1864 begin
1865 loop
1866 wf_event.dequeue(agt, err_evt, qh,p_wait);
1867
1868 end loop;
1869
1870 exception
1871 when end_of_transaction then
1872 if (wf_log_pkg.level_event >= fnd_log.g_current_runtime_level) then
1873 wf_log_pkg.string(wf_log_pkg.level_event,
1874 'wf.plsql.WF_EVENT.Listen_GRP.complete',
1875 'End of the transaction after dispatch error');
1876 end if;
1877
1878 -- reset navigation
1879 wf_event.resetNavigationParams;
1880
1881 end;
1882
1883 --Rollback the whole transaction, which will update the retry count
1884 --on each message.
1885 rollback to trxn_start;
1886
1887 --We will save the current message to the Error Queue.
1888 if ((evt.getValueForParameter('ERROR_NAME')) is NULL) then
1889 wf_event.setErrorInfo(evt, 'ERROR');
1890
1891 end if;
1892
1893 evt.addParameterToList('DEQUEUE_MODE', 'TRANSACTIONAL');
1894 wf_event.saveErrorToQueue(evt);
1895
1896
1897 when others then
1898 raise;
1899
1900 end;
1901
1902 -- if QH is using setNavigationParams/getQueueNavigation, condition is
1903 -- g_processedMessagesCount = 0 and g_currentNavigation either
1904 -- FIRST_MESSAGE or NEXT_TRANSACTION,
1905 -- otherwise, condition is wf_event.navigation = dbms_aq.first_message
1906 if (g_navResetThreshold is not null and g_processedMessagesCount = 0
1907 and (g_currentNavigation in (dbms_aq.FIRST_MESSAGE, dbms_aq.NEXT_TRANSACTION)))
1908 OR
1909 (g_navResetThreshold is null and wf_event.navigation = dbms_aq.first_message)
1910 then
1911
1912 exit; --Outer Loop.
1913 --The queue handler must have reached the last message and
1914 --reset the navigation back to the beginning.
1915
1916 end if;
1917
1918 end loop; --Outer loop to process all transactions in the queue.
1919 exception
1920 when no_data_found then
1921 if (wf_event.wf_exception_source = 'WF'
1922 OR wf_event.wf_exception_source = 'QH') then
1923 raise;
1924 else
1925 wf_core.context('Wf_Event', 'Listen_GRP', p_agent_name);
1926 wf_core.raise('WFE_AGENT_NOTEXIST');
1927 end if;
1928 when others then
1929 wf_core.context('Wf_Event', 'Listen_GRP', p_agent_name);
1930 raise;
1931 end;
1932
1933 ---------------------------------------------------------------------------
1934 /*
1935 ** listen__grp_concurrent - <Described in WFEVENTS.pls>
1936 */
1937 PROCEDURE listen_grp_concurrent(errbuf out nocopy varchar2,
1938 retcode out nocopy varchar2,
1939 p_agent_name in varchar2) is
1940 errname varchar2(30);
1941 errmsg varchar2(2000);
1942 errstack varchar2(4000);
1943 begin
1944 wf_event.listen_grp(p_agent_name);
1945
1946 -- Return 0 for successful completion --
1947 errbuf := '';
1948 retcode := '0';
1949 exception
1950 when others then
1951 wf_core.get_error(errname, errmsg, errstack);
1952 if (errmsg is not null) then
1953 errbuf := errmsg;
1954 else
1955 errbuf := sqlerrm;
1956 end if;
1957
1958 -- Return 2 for error --
1959 retcode := '2';
1960 end;
1961
1962 ---------------------------------------------------------------------------
1963 /*
1964 ** dispatch - <Described in WFEVENTS.pls>
1965 */
1966 PROCEDURE dispatch(p_source_type in varchar2,
1967 p_source_agent_guid in raw,
1968 p_event in out nocopy wf_event_t)
1969 is
1970 res varchar2(20);
1971 cmd varchar2(1000);
1972 stat varchar2(10);
1973 myfunc varchar2(240);
1974 ename varchar2(240);
1975 saved boolean := FALSE;
1976 subs_found boolean :=FALSE;
1977 eguid raw(16);
1978 l_skip_sub raw(16);
1979 event_count NUMBER;
1980 l_rule_func varchar2(300);
1981 l_source_type wf_event_subscriptions.source_type%type;
1982 l_phase wf_event_subscriptions.phase%type;
1983 l_rule_data wf_event_subscriptions.rule_data%type;
1984 l_priority wf_event_subscriptions.priority%type;
1985 l_on_error wf_event_subscriptions.on_error_code%type;
1986 --Bug 2437354
1987 trig_savepoint exception;
1988 pragma exception_init(trig_savepoint, -04092);
1989
1990 -- bes caching implementation
1991 l_event_name varchar2(240);
1992 l_event_obj wf_event_obj;
1993 l_subs_list wf_event_subs_tab;
1994 l_sub wf_event_subs_obj;
1995 begin
1996 l_event_name := p_event.Event_Name;
1997
1998 -- Deleting any previous Event parameter indexes.
1999 WF_EVENT.evt_param_index.DELETE;
2000
2001 if (wf_log_pkg.level_procedure >= fnd_log.g_current_runtime_level) then
2002 wf_log_pkg.string(wf_log_pkg.level_procedure,
2003 'wf.plsql.WF_EVENT.dispatch.Begin',
2004 'Dispatching event '||l_event_name);
2005 end if;
2006
2007 l_event_obj := wf_bes_cache.GetEventByName(l_event_name);
2008 if (l_event_obj is null) then
2009 if (wf_log_pkg.level_statement >= fnd_log.g_current_runtime_level) then
2010 wf_log_pkg.string(wf_log_pkg.level_statement,
2011 'wf.plsql.WF_EVENT.dispatch.no_event',
2012 'Event is either disabled or product not licensed '||
2013 'or event not registered');
2014 end if;
2015 end if;
2016
2017 wf_event.wf_exception_source := 'NONE';
2018
2019 --
2020 -- mjc If Source Type is LOCAL and Phase Threshold is less than zero,
2021 -- the raise is to be deferred. Then we immediately return to
2022 -- calling subprogram
2023 --
2024 -- The wf_event.deferevent is called within a new block
2025 -- Make sure only defer event when event exists.
2026 begin
2027 if (p_source_type = 'LOCAL' AND
2028 (wf_event.phase_maxthreshold < 0 OR p_event.send_date > sysdate) AND
2029 l_event_obj is not null) then
2030
2031 if(isDeferToJava(true, l_event_name, p_source_type,
2032 null, null, null)) then
2033 if (wf_log_pkg.level_statement >= fnd_log.g_current_runtime_level) then
2034 wf_log_pkg.string(wf_log_pkg.level_statement,
2035 'wf.plsql.WF_EVENT.dispatch.Defer',
2036 'Detected as deferred raise. Deferring to ' ||
2037 'WF_JAVA_DEFERRED');
2038 end if;
2039 wf_event.DeferEventToJava(p_source_type, p_event);
2040 else
2041 if (wf_log_pkg.level_statement >= fnd_log.g_current_runtime_level) then
2042 wf_log_pkg.string(wf_log_pkg.level_statement,
2043 'wf.plsql.WF_EVENT.dispatch.Defer',
2044 'Detected as deferred raise. Deferring to ' ||
2045 'WF_DEFERRED');
2046 end if;
2047 wf_event.deferevent(p_source_type, p_event);
2048 end if;
2049 return;
2050 end if;
2051 exception
2052 when others then
2053 wf_event.setErrorInfo(p_event, 'ERROR');
2054 wf_event.saveErrorToQueue(p_event);
2055 wf_core.context('Wf_Event', 'Dispatch', l_event_name);
2056 raise;
2057 end;
2058
2059 --
2060 -- mjc We have 4 things we need to check for when we are dipatching:
2061 -- 1. Are there any subscriptions for the actual event.
2062 -- 2. Are there any subscriptions to an event group the event belongs to.
2063 -- 3. Are there any subscriptions to the any event.
2064 -- 4. If no subscriptions found in 1,2,3 then check for the unexpected event.
2065 --
2066
2067 -- YOHUANG
2068 -- TODO
2069 -- Since we know whether this event exist or not, if the event doesn't exist
2070 -- We should execute those expense query such as active_subs, we should instead
2071 -- directly execute active_event_subs for ANY event.
2072 /*
2073 ** Events, Event Groups, Any Event
2074 */
2075 --The savepoint is set if the event has not been deferred
2076 begin
2077 savepoint wf_dispatch_savepoint;
2078 exception
2079 when trig_savepoint then
2080 --If the event has not been deferred, defer the event now.
2081 begin
2082 wf_event.deferevent(p_source_type,p_event);
2083 return;
2084 exception
2085 --Incase deferreing of event fails, save the error to queue.
2086 --Should we save the error to queue since it is WF error?
2087 when others then
2088 wf_event.setErrorInfo(p_event, 'ERROR');
2089 wf_event.saveErrorToQueue(p_event);
2090 wf_core.context('Wf_Event', 'Dispatch', l_event_name);
2091 raise;
2092 end;
2093 end;
2094
2095 -- Subscriptions dispatch block
2096 begin
2097 -- Only the skipped subscription should be executed when
2098 -- WFERROR DEFAULT_EVENT_ERROR re-raise the event again.
2099 l_skip_sub := GetSkippedSub(p_event);
2100
2101 if (l_skip_sub is not null AND p_source_type = 'LOCAL') then
2102
2103 l_sub := wf_bes_cache.GetSubscriptionByGUID(l_event_name, l_skip_sub);
2104 if (l_sub is not null) then
2105 res := wf_event.dispatch_internal(p_source_type => l_sub.SOURCE_TYPE,
2106 p_rule_data => l_sub.RULE_DATA,
2107 p_rule_func => trim(l_sub.RULE_FUNCTION),
2108 p_sub_guid => l_skip_sub,
2109 p_source_agent_guid => l_sub.SOURCE_AGENT_GUID,
2110 p_phase => l_sub.PHASE,
2111 p_priority => l_sub.PRIORITY,
2112 p_event => p_event,
2113 p_on_error => l_sub.ON_ERROR_CODE);
2114 end if;
2115 -- Since this is the only sub to be executed, no matter
2116 -- what result it reports, we stop here.
2117 return;
2118 end if;
2119
2120 -- get and dispatch subscriptions to the even only if the event is
2121 -- valid, product is licensed etc. else directly dispatch Any event
2122 if (l_event_obj is not null) then
2123 -- all subscriptions to the event and Any event in the order of phase
2124 l_subs_list := wf_bes_cache.GetSubscriptions(p_event_name => l_event_name,
2125 p_source_type => dispatch.p_source_type,
2126 p_source_agent => dispatch.p_source_agent_guid);
2127 -- dispatching all matching subscriptions for the event
2128 if (l_subs_list is not null) then
2129
2130 for i in 1..l_subs_list.COUNT loop
2131 if (wf_log_pkg.level_statement >= fnd_log.g_current_runtime_level) then
2132 wf_log_pkg.string(wf_log_pkg.level_statement,
2133 'wf.plsql.WF_EVENT.dispatch.Subscriptions',
2134 'Dispatching '||l_subs_list(i).SOURCE_TYPE||' subscription '||
2135 'with Phase '||l_subs_list(i).PHASE);
2136 end if;
2137
2138 eguid := l_subs_list(i).GUID;
2139 subs_found := TRUE;
2140
2141 res := wf_event.dispatch_internal(p_source_type => l_subs_list(i).SOURCE_TYPE,
2142 p_rule_data => l_subs_list(i).RULE_DATA,
2143 p_rule_func => trim(l_subs_list(i).RULE_FUNCTION),
2144 p_sub_guid => l_subs_list(i).GUID,
2145 p_source_agent_guid => p_source_agent_guid,
2146 p_phase => l_subs_list(i).PHASE,
2147 p_priority => l_subs_list(i).PRIORITY,
2148 p_event => p_event,
2149 p_on_error => l_subs_list(i).ON_ERROR_CODE);
2150
2151 if res in ('ERROR', 'DEFER', 'TRANSACTION_COMMITED') then
2152 exit;
2153 end if;
2154 end loop;
2155 end if;
2156
2157 -- Event object is null, dispatch only Any event subscriptions
2158 else
2159
2160 -- dispatch subscriptions to Any event. this call does not execute the
2161 -- cursor with union all
2162 l_subs_list := wf_bes_cache.GetSubscriptions(p_event_name => 'oracle.apps.wf.event.any',
2163 p_source_type => dispatch.p_source_type,
2164 p_source_agent => dispatch.p_source_agent_guid);
2165 -- dispatching all matching subscriptions for Any event
2166 if (l_subs_list is not null) then
2167
2168 for i in 1..l_subs_list.COUNT loop
2169 if (wf_log_pkg.level_statement >= fnd_log.g_current_runtime_level) then
2170 wf_log_pkg.string(wf_log_pkg.level_statement,
2171 'wf.plsql.WF_EVENT.dispatch.Any',
2172 'Dispatching '||l_subs_list(i).SOURCE_TYPE||' subscription '||
2173 'with Phase '||l_subs_list(i).PHASE);
2174 end if;
2175
2176 eguid := l_subs_list(i).GUID;
2177 subs_found := TRUE;
2178
2179 res := wf_event.dispatch_internal(p_source_type => l_subs_list(i).SOURCE_TYPE,
2180 p_rule_data => l_subs_list(i).RULE_DATA,
2181 p_rule_func => trim(l_subs_list(i).RULE_FUNCTION),
2182 p_sub_guid => l_subs_list(i).GUID,
2183 p_source_agent_guid => p_source_agent_guid,
2184 p_phase => l_subs_list(i).PHASE,
2185 p_priority => l_subs_list(i).PRIORITY,
2186 p_event => p_event,
2187 p_on_error => l_subs_list(i).ON_ERROR_CODE);
2188
2189 if res in ('ERROR', 'DEFER', 'TRANSACTION_COMMITED') then
2190 exit;
2191 end if;
2192 end loop;
2193 end if;
2194 end if;
2195
2196 -- If no subscriptions dispatched, dispatch subscriptions for Unexpected event.
2197 -- Unexpected event is dispatched only for non-workflow events
2198 if ((not subs_found) and (l_event_name not like 'oracle.apps.wf%')) then
2199
2200 l_subs_list := wf_bes_cache.GetSubscriptions(p_event_name => 'oracle.apps.wf.event.unexpected',
2201 p_source_type => dispatch.p_source_type,
2202 p_source_agent => dispatch.p_source_agent_guid);
2203 if (l_subs_list is not null) then
2204
2205 for i in 1..l_subs_list.COUNT loop
2206 if (wf_log_pkg.level_statement >= fnd_log.g_current_runtime_level) then
2207 wf_log_pkg.string(wf_log_pkg.level_statement,
2208 'wf.plsql.WF_EVENT.dispatch.Unexpected',
2209 'Dispatching '||l_subs_list(i).SOURCE_TYPE||' subscription '||
2210 'with Phase '||l_subs_list(i).PHASE);
2211 end if;
2212
2213 eguid := l_subs_list(i).GUID;
2214 res := wf_event.dispatch_internal(p_source_type => l_subs_list(i).SOURCE_TYPE,
2215 p_rule_data => l_subs_list(i).RULE_DATA,
2216 p_rule_func => trim(l_subs_list(i).RULE_FUNCTION),
2217 p_sub_guid => l_subs_list(i).GUID,
2218 p_source_agent_guid => p_source_agent_guid,
2219 p_phase => l_subs_list(i).PHASE,
2220 p_priority => l_subs_list(i).PRIORITY,
2221 p_event => p_event,
2222 p_on_error => l_subs_list(i).ON_ERROR_CODE);
2223
2224 if res in ('ERROR', 'DEFER', 'TRANSACTION_COMMITED') then
2225 exit;
2226 end if;
2227 end loop;
2228 end if;
2229 end if;
2230 exception
2231 when others then
2232 -- Unexpected Error happened in dispatch_internal
2233 if (WF_EVENT.g_message_grouping = 'TRANSACTIONAL') then
2234 WF_CORE.Context('Wf_Event', 'Dispatch', l_event_name);
2235 else
2236 rollback to wf_dispatch_savepoint;
2237 p_event.setErrorSubscription(eguid);
2238 if (wf_event.wf_exception_source <> 'RULE') then
2239 wf_event.wf_exception_source := 'WF';
2240 wf_event.setErrorInfo(p_event, 'UNEXPECTED');
2241 -- Unexpected Exception should be thrown up instead of
2242 -- being enqueued to error queue.
2243 -- wf_event.saveErrorToQueue(p_event);
2244 wf_core.context('Wf_Event', 'Dispatch', l_event_name);
2245 end if;
2246 end if;
2247 raise;
2248 end;
2249 end dispatch;
2250
2251
2252 ---------------------------------------------------------------------------
2253 /*
2254 ** enqueue - <Described in WFEVENTS.pls>
2255 */
2256 PROCEDURE enqueue(p_event in wf_event_t,
2257 p_out_agent_override in wf_agent_t)
2258 is
2259 cmd varchar2(1000);
2260 qh varchar2(240);
2261 agtname varchar2(30);
2262 sysname varchar2(30);
2263
2264 -- bes caching implementation
2265 l_agent_obj wf_agent_obj;
2266 p_executed boolean;
2267 begin
2268 /*
2269 ** mjc If an override agent is defined, we should
2270 ** use that agents queue handler
2271 */
2272 if p_out_agent_override is null then
2273 agtname := p_event.From_Agent.Name;
2274 sysname := p_event.From_Agent.System;
2275 else
2276 agtname := p_out_agent_override.GetName();
2277 sysname := p_out_agent_override.GetSystem();
2278 end if;
2279
2280 l_agent_obj := wf_bes_cache.GetAgentByName(agtname, sysname);
2281 if (l_agent_obj is not null) then
2282 qh := l_agent_obj.QUEUE_HANDLER;
2283 end if;
2284
2285 -- Call the static calls implementation first
2286 p_executed := false;
2287
2288 if (wf_log_pkg.level_statement >= fnd_log.g_current_runtime_level) then
2289 wf_log_pkg.string2(wf_log_pkg.level_statement,
2290 'wf.plsql.wf_event.enqueue.qhandler_callout',
2291 'Start executing queue handler - '||qh, true);
2292 end if;
2293
2294 WF_AGT_DYN_FUNCS.StaticEnqueue(qh, p_event, p_out_agent_override, p_executed);
2295
2296 if (not p_executed) then
2297 -- qh is from WF_AGENTS.QUEUE_HANDLER
2298 -- BINDVAR_SCAN_IGNORE
2299 cmd := 'begin '||qh||'.enqueue(:v1, :v2); end;';
2300 execute immediate cmd using in p_event,
2301 in p_out_agent_override;
2302 end if;
2303
2304 if (wf_log_pkg.level_statement >= fnd_log.g_current_runtime_level) then
2305 wf_log_pkg.string2(wf_log_pkg.level_statement,
2306 'wf.plsql.wf_event.enqueue.qhandler_callout',
2307 'End executing queue handler - '||qh, false);
2308 end if;
2309 exception
2310 when others then
2311 wf_core.context('Wf_Event', 'Enqueue', p_event.getEventName(), qh);
2312 wf_core.token('FUNCTION_NAME', qh||'.enqueue()');
2313 --wf_core.raise('WF_EXT_FUNCTION');
2314 raise;
2315 end;
2316 ---------------------------------------------------------------------------
2317 /*
2318 ** dequeue - <Described in WFEVENTS.pls>
2319 */
2320 PROCEDURE dequeue(p_agent_guid in raw,
2321 p_event out nocopy wf_event_t,
2322 p_queue_handler in out nocopy varchar2,
2323 p_wait in binary_integer,
2324 p_correlation in varchar2,
2325 p_deq_condition in varchar2)
2326 is
2327 qh varchar2(240);
2328 cmd varchar2(1000);
2329 evt_errmsg varchar2(2000);
2330
2331 -- bes caching implementation
2332 l_agent_obj wf_agent_obj;
2333 p_executed boolean;
2334 begin
2335 if (p_queue_handler is null) then
2336 -- get queue details from cache for given agent GUID
2337 l_agent_obj := wf_bes_cache.GetAgentByGUID(p_agent_guid);
2338 if (l_agent_obj is not null) then
2339 qh := l_agent_obj.QUEUE_HANDLER;
2340 end if;
2341 else
2342 -- ### add verification in the future
2343 qh := p_queue_handler;
2344 end if;
2345
2346 -- Set globals so the queue handlers can reference them.
2347 WF_EVENT.g_correlation := p_correlation;
2348 WF_EVENT.g_deq_condition := p_deq_condition;
2349
2350 -- Call the static calls implementation first
2351 p_executed := false;
2352
2353 if (wf_log_pkg.level_statement >= fnd_log.g_current_runtime_level) then
2354 wf_log_pkg.string2(wf_log_pkg.level_statement,
2355 'wf.plsql.wf_event.dequeue.qhandler_callout',
2356 'Start executing queue handler - '||qh, true);
2357 end if;
2358
2359 WF_AGT_DYN_FUNCS.StaticDequeue(qh, p_agent_guid, p_event, p_wait, p_executed);
2360
2361 if (not p_executed) then
2362 -- p_queue_handler is normally null, or control by us
2363 -- BINDVAR_SCAN_IGNORE
2364 cmd := 'begin '||qh||'.dequeue(:v1, :v2); end;';
2365 execute immediate cmd using in p_agent_guid,
2366 out p_event;
2367 end if;
2368
2369 if (wf_log_pkg.level_statement >= fnd_log.g_current_runtime_level) then
2370 wf_log_pkg.string2(wf_log_pkg.level_statement,
2371 'wf.plsql.wf_event.dequeue.qhandler_callout',
2372 'End executing queue handler - '||qh, false);
2373 end if;
2374
2375 p_queue_handler := qh;
2376 exception
2377 when others then
2378 wf_core.context('Wf_Event', 'Dequeue', p_agent_guid);
2379 wf_core.token('FUNCTION_NAME', qh||'.dequeue()');
2380 --wf_core.raise('WF_EXT_FUNCTION');
2381 raise;
2382 end;
2383 ---------------------------------------------------------------------------
2384 /*
2385 ** AddParameterToList - <described in WFEVENTS.pls>
2386 */
2387 -- YOHUANG 3571176
2388 -- Share the same logic as WF_EVENT_T.AddParameterToList
2389 -- If there is any change of logic in this method, the change
2390 -- should be propagated over to WF_EVENT_T.
2391 PROCEDURE AddParameterToList(p_name in varchar2,
2392 p_value in varchar2,
2393 p_parameterlist in out nocopy wf_parameter_list_t)
2394 is
2395 j number;
2396 found boolean := FALSE;
2397 begin
2398 if (p_ParameterList is null) then
2399 --
2400 -- Initialize Parameter List and set value
2401 --
2402 p_ParameterList := wf_parameter_list_t(null);
2403 p_ParameterList(1) := wf_parameter_t(p_Name, p_Value);
2404 else
2405 --
2406 -- parameter list exists, add parameter to list
2407 --
2408 j := 1;
2409 while (NOT found AND j <= p_parameterlist.COUNT ) LOOP
2410 -- YOHUANG 3566991, make sure myList(j) is not null
2411 -- to avoid 36025 ora error
2412 IF (p_parameterlist(j) IS NOT NULL) THEN
2413 if (p_parameterlist(j).getName() = p_name) then
2414 found := TRUE;
2415 p_parameterlist(j).setValue(p_Value);
2416 END if;
2417 END IF;
2418 j := j+1;
2419 end loop;
2420
2421 -- otherwise, add new parameter to list --
2422
2423 if (NOT found) then
2424 p_ParameterList.EXTEND;
2425 j := p_ParameterList.COUNT;
2426 p_ParameterList(j) := wf_parameter_t(p_name, p_Value);
2427 end if;
2428 end if;
2429 end AddParameterToList;
2430 ---------------------------------------------------------------------------
2431 /*
2432 ** AddParameterToListPos - <described in WFEVENTS.pls>
2433 */
2434 PROCEDURE AddParameterToListPos(p_name in varchar2,
2435 p_value in varchar2,
2436 p_position out nocopy integer,
2437 p_parameterlist in out nocopy wf_parameter_list_t)
2438 is
2439 j integer;
2440
2441 begin
2442 if (p_ParameterList is null) then
2443 --
2444 -- Initialize Parameter List and set value
2445 --
2446 p_ParameterList := wf_parameter_list_t(null);
2447 p_position := 1;
2448 p_ParameterList(1) := wf_parameter_t(p_Name, p_Value);
2449 else
2450 --
2451 -- parameter list exists, add parameter to list
2452 --
2453 p_ParameterList.EXTEND;
2454 j := p_ParameterList.COUNT;
2455 p_position := j;
2456 p_ParameterList(j) := wf_parameter_t(p_Name, p_Value);
2457 end if;
2458
2459 end AddParameterToListPos;
2460 ---------------------------------------------------------------------------
2461 /*
2462 ** GetValueForParameter - <described in WFEVENTS.pls>
2463 */
2464 FUNCTION getValueForParameter(p_Name in varchar2,
2465 p_ParameterList in wf_parameter_list_t )
2466 return varchar2 is
2467 myList wf_parameter_list_t;
2468 pos number := 1;
2469 begin
2470 myList := p_ParameterList;
2471 if (myList is null) then
2472 return NULL;
2473 end if;
2474
2475 pos := myList.LAST;
2476 --while(pos <= myList.COUNT) loop
2477 while(pos is not null) loop
2478 if (myList(pos).getName() = p_Name) then
2479
2480 if (wf_log_pkg.level_statement >= fnd_log.g_current_runtime_level) then
2481 wf_log_pkg.string(wf_log_pkg.level_statement,
2482 'wf.plsql.WF_EVENT.getValueForParam.get',
2483 'Name:'||p_Name||' Value:'||myList(pos).getValue());
2484 end if;
2485
2486 return myList(pos).getValue();
2487 end if;
2488 --pos := pos + 1;
2489 pos := myList.PRIOR(pos);
2490 end loop;
2491 return NULL;
2492 end getValueForParameter;
2493 ---------------------------------------------------------------------------
2494 /*
2495 ** GetValueForParameterPos - Gets value for position from wf_parameter_list_t
2496 */
2497 FUNCTION getValueForParameterPos(p_position in integer,
2498 p_parameterlist in wf_parameter_list_t)
2499 return varchar2 is
2500 myList wf_parameter_list_t;
2501 begin
2502 myList := p_ParameterList;
2503 if (myList is null) then
2504 return NULL;
2505 end if;
2506
2507 return myList(p_position).getValue();
2508
2509 end getValueForParameterPos;
2510 ---------------------------------------------------------------------------
2511 /*
2512 ** SetDispatchMode - <described in WFEVENTS.pls>
2513 */
2514 PROCEDURE SetDispatchMode (p_mode in varchar2)
2515 is
2516 begin
2517 if p_mode = 'ASYNC' then
2518 wf_event.phase_maxthreshold := -1;
2519 else
2520 wf_event.phase_maxthreshold := 100;
2521 end if;
2522 exception
2523 when others then
2524 wf_core.context('Wf_Event', 'SetDispatchMode', p_mode);
2525 raise;
2526 end SetDispatchMode;
2527 ---------------------------------------------------------------------------
2528 /*
2529 ** InitPhaseMinThreshold <described in WFEVENTS.pls>
2530 */
2531 PROCEDURE InitPhaseMinThreshold
2532 is
2533 begin
2534 wf_event.phase_minthreshold := 0;
2535 end InitPhaseMinThreshold;
2536 ---------------------------------------------------------------------------
2537 /*
2538 ** DeferEvent - <described in WFEVENTS.pls>
2539 */
2540 PROCEDURE DeferEvent(p_source_type in varchar2,
2541 p_event in out nocopy wf_event_t)
2542 is
2543 defagent wf_agent_t;
2544
2545 begin
2546
2547 if (wf_log_pkg.level_procedure >= fnd_log.g_current_runtime_level) then
2548 wf_log_pkg.string(wf_log_pkg.level_procedure,
2549 'wf.plsql.WF_EVENT.DeferEvent.Begin',
2550 'Deferring Event: '||p_event.getEventName());
2551 end if;
2552 --
2553 -- Get the Local System Name and set the deferred agent
2554 --
2555
2556 defagent := wf_agent_t('WF_DEFERRED',wf_event.local_system_name);
2557
2558 --
2559 -- If the defer is for a local event, set the
2560 -- Deferred Agent/System into the message for
2561 -- reference when we process the event
2562 --
2563 if p_source_type = 'LOCAL' then
2564 if (wf_log_pkg.level_statement >= fnd_log.g_current_runtime_level) then
2565 wf_log_pkg.string(wf_log_pkg.level_statement,
2566 'wf.plsql.WF_EVENT.DeferEvent.Local',
2567 'Detected as Local, setting From Agent:'||
2568 'WF_DEFERRED@'||wf_event.local_system_name);
2569 end if;
2570 p_event.From_Agent := defagent;
2571 end if;
2572
2573 --
2574 -- Enqueue onto the deferred agent
2575 --
2576 if (wf_log_pkg.level_statement >= fnd_log.g_current_runtime_level) then
2577 wf_log_pkg.string(wf_log_pkg.level_statement,
2578 'wf.plsql.WF_EVENT.DeferEvent.done',
2579 'Enqueuing on Deferred Queue');
2580 end if;
2581
2582 wf_event.enqueue(p_event,defagent);
2583
2584 exception
2585 when others then
2586 wf_core.context('Wf_Event', 'DeferEvent', p_event.getEventName(),
2587 p_event.getEventKey());
2588 raise;
2589 end DeferEvent;
2590 ---------------------------------------------------------------------------
2591 /*
2592 ** DeferEventToJava - <described in WFEVENTS.pls>
2593 */
2594 PROCEDURE DeferEventToJava(p_source_type in varchar2,
2595 p_event in out nocopy wf_event_t)
2596 is
2597 defagent wf_agent_t;
2598
2599 begin
2600 if (wf_log_pkg.level_procedure >= fnd_log.g_current_runtime_level) then
2601 wf_log_pkg.string(wf_log_pkg.level_procedure,
2602 'wf.plsql.WF_EVENT.DeferEventToJava.Begin',
2603 'Deferring Event: '|| p_event.getEventName());
2604 end if;
2605 --
2606 -- Get the Local System Name and set the deferred agent
2607 --
2608 defagent := wf_agent_t('WF_JAVA_DEFERRED', wf_event.local_system_name);
2609
2610 --
2611 -- If the defer is for a local event, set the
2612 -- Deferred Agent/System into the message for
2613 -- reference when we process the event
2614 --
2615 if p_source_type = 'LOCAL' then
2616 if (wf_log_pkg.level_statement >= fnd_log.g_current_runtime_level) then
2617 wf_log_pkg.string(wf_log_pkg.level_statement,
2618 'wf.plsql.WF_EVENT.DeferEventToJava.Local',
2619 'Detected as Local, setting From Agent:'||
2620 'WF_JAVA_DEFERRED@'|| wf_event.local_system_name);
2621
2622 end if;
2623 p_event.From_Agent := defagent;
2624 end if;
2625
2626 --
2627 -- Enqueue onto the deferred agent
2628 --
2629
2630 --
2631 -- NOTE: Since we know that we need to defer to WF_JAVA_DEFERRED, we will
2632 -- directly invoke enqueue on the PL/SQL queue handler
2633 --
2634 wf_event_ojmstext_qh.enqueue(p_event, defagent);
2635
2636 if (wf_log_pkg.level_statement >= fnd_log.g_current_runtime_level) then
2637 wf_log_pkg.string(wf_log_pkg.level_statement,
2638 'wf.plsql.WF_EVENT.DeferEventToJava.done',
2639 'Enqueuing on Java Deferred Queue');
2640 end if;
2641
2642 exception
2643 when others then
2644 wf_core.context('Wf_Event', 'DeferEventToJava', p_event.getEventName(),
2645 p_event.getEventKey());
2646 raise;
2647 end DeferEventToJava;
2648 ---------------------------------------------------------------------------
2649 /*
2650 ** GetDeferEventCtx - <described in WFEVENTS.pls>
2651 */
2652 PROCEDURE GetDeferEventCtx (p_source_type in out nocopy varchar2,
2653 p_agent_name in varchar2,
2654 p_system_name in varchar2,
2655 p_event in wf_event_t)
2656 is
2657 subguid raw(16);
2658 lphasestart number;
2659 lsrc varchar2(10);
2660
2661 -- bes caching implementation
2662 l_sub wf_event_subs_obj;
2663 l_event_name varchar2(240);
2664 begin
2665
2666 if (wf_log_pkg.level_procedure >= fnd_log.g_current_runtime_level) then
2667 wf_log_pkg.string(wf_log_pkg.level_procedure,
2668 'wf.plsql.WF_EVENT.DeferEventCtx.Begin',
2669 'Getting Defer Event Ctx');
2670 end if;
2671 --
2672 -- Determine the Start Phase, and sourec type
2673 --
2674 subguid := p_event.Error_Subscription;
2675 if (wf_log_pkg.level_statement >= fnd_log.g_current_runtime_level) then
2676 wf_log_pkg.string(wf_log_pkg.level_statement,
2677 'wf.plsql.WF_EVENT.DeferEventCtx.sub_guid',
2678 'Sub Guid is '||subguid);
2679 end if;
2680
2681 l_event_name := p_event.GetEventName();
2682 if subguid is not null then
2683 l_sub := wf_bes_cache.GetSubscriptionByGUID(l_event_name, subguid);
2684
2685 if (l_sub is not null) then
2686 lsrc := l_sub.SOURCE_TYPE;
2687 lphasestart := l_sub.PHASE;
2688 else
2689 -- << sstomar : bug 5870400>>
2690 lphasestart := p_event.GetValueForParameter('#CURRENT_PHASE');
2691
2692 if(lphasestart is null) then
2693 raise no_data_found;
2694 END if;
2695
2696 end if;
2697
2698 wf_event.phase_minthreshold := lphasestart;
2699 else
2700 wf_event.phase_minthreshold := 0; -- for deferred raise
2701 end if;
2702
2703 if (wf_log_pkg.level_statement >= fnd_log.g_current_runtime_level) then
2704 wf_log_pkg.string(wf_log_pkg.level_statement,
2705 'wf.plsql.WF_EVENT.DeferEventCtx.phase',
2706 'Start Phase is '||to_char(wf_event.phase_minthreshold));
2707 end if;
2708
2709 if lsrc is null then
2710 --
2711 -- Derive the Source Type
2712 --
2713 if ((p_agent_name = 'WF_DEFERRED') AND (p_system_name = wf_event.local_system_name)) then
2714 p_source_type := 'LOCAL';
2715 elsif ((p_system_name is null) OR (p_system_name <> wf_event.local_system_name))then
2716 p_source_type := 'EXTERNAL';
2717 elsif ((p_agent_name <> 'WF_DEFERRED') AND (p_system_name = wf_event.local_system_name)) then
2718 p_source_type := 'EXTERNAL';
2719 end if;
2720 else
2721 p_source_type := lsrc;
2722 end if;
2723
2724 if (wf_log_pkg.level_procedure >= fnd_log.g_current_runtime_level) then
2725 wf_log_pkg.string(wf_log_pkg.level_procedure,
2726 'wf.plsql.WF_EVENT.DeferEventCtx.End',
2727 'Source Type is '||p_source_type);
2728 end if;
2729
2730 exception
2731 /* Bug 2210085 */
2732 when no_data_found then
2733 /*
2734 wf_core.context('Wf_Event', 'GetDeferEventCtx','Sub guid is ' || subguid);
2735 wf_core.token('SGUID', subguid);
2736 wf_core.raise('WFE_SUB_DELETED');
2737 */
2738 raise;
2739
2740 when others then
2741 wf_core.context('Wf_Event', 'GetDeferEventCtx', p_event.getEventName(),
2742 p_event.getEventKey());
2743 raise;
2744 end GetDeferEventCtx;
2745 ---------------------------------------------------------------------------
2746 /*
2747 ** SetAccountName - <described in WFEVENTS.pls>
2748 */
2749 PROCEDURE SetAccountName
2750 is
2751 begin
2752 -- get the account name - only need this for WF_DEFERRED
2753 select sys_context('USERENV', 'CURRENT_SCHEMA')
2754 into wf_event.account_name
2755 from sys.dual;
2756 exception
2757 when others then
2758 wf_core.context('Wf_Event', 'SetAccountName');
2759 raise;
2760 end SetAccountName;
2761 ---------------------------------------------------------------------------
2762 --
2763 -- Bug# 2211719 - New API raise2 for calls that donot understand
2764 -- Oracle data types`
2765 /*
2766 ** raise2 - <Described in WFEVENTS.pls>
2767 */
2768
2769 PROCEDURE raise2(p_event_name in varchar2,
2770 p_event_key in varchar2,
2771 p_event_data in clob,
2772 p_parameter_name1 in varchar2,
2773 p_parameter_value1 in varchar2,
2774 p_parameter_name2 in varchar2,
2775 p_parameter_value2 in varchar2,
2776 p_parameter_name3 in varchar2,
2777 p_parameter_value3 in varchar2,
2778 p_parameter_name4 in varchar2,
2779 p_parameter_value4 in varchar2,
2780 p_parameter_name5 in varchar2,
2781 p_parameter_value5 in varchar2,
2782 p_parameter_name6 in varchar2,
2783 p_parameter_value6 in varchar2,
2784 p_parameter_name7 in varchar2,
2785 p_parameter_value7 in varchar2,
2786 p_parameter_name8 in varchar2,
2787 p_parameter_value8 in varchar2,
2788 p_parameter_name9 in varchar2,
2789 p_parameter_value9 in varchar2,
2790 p_parameter_name10 in varchar2,
2791 p_parameter_value10 in varchar2,
2792 p_parameter_name11 in varchar2,
2793 p_parameter_value11 in varchar2,
2794 p_parameter_name12 in varchar2,
2795 p_parameter_value12 in varchar2,
2796 p_parameter_name13 in varchar2,
2797 p_parameter_value13 in varchar2,
2798 p_parameter_name14 in varchar2,
2799 p_parameter_value14 in varchar2,
2800 p_parameter_name15 in varchar2,
2801 p_parameter_value15 in varchar2,
2802 p_parameter_name16 in varchar2,
2803 p_parameter_value16 in varchar2,
2804 p_parameter_name17 in varchar2,
2805 p_parameter_value17 in varchar2,
2806 p_parameter_name18 in varchar2,
2807 p_parameter_value18 in varchar2,
2808 p_parameter_name19 in varchar2,
2809 p_parameter_value19 in varchar2,
2810 p_parameter_name20 in varchar2,
2811 p_parameter_value20 in varchar2,
2812 p_send_date in date) is
2813 l_parameter_list wf_parameter_list_t := wf_parameter_list_t();
2814 i number := 1;
2815 begin
2816
2817 if (wf_log_pkg.level_procedure >= fnd_log.g_current_runtime_level) then
2818 wf_log_pkg.string(wf_log_pkg.level_procedure,
2819 'wf.plsql.WF_EVENT.raise2.Begin',
2820 'Event Name:'||p_event_name||' Event Key:'||p_event_key);
2821 end if;
2822
2823 if (p_parameter_name1 is not NULL) then
2824 l_parameter_list.extend;
2825 l_parameter_list(i) := CreateParameter(p_parameter_name1, p_parameter_value1);
2826 i := i + 1;
2827 end if;
2828
2829 if (p_parameter_name2 is not NULL) then
2830 l_parameter_list.extend;
2831 l_parameter_list(i) := CreateParameter(p_parameter_name2, p_parameter_value2);
2832 i := i + 1;
2833 end if;
2834
2835 if (p_parameter_name3 is not NULL) then
2836 l_parameter_list.extend;
2837 l_parameter_list(i) := CreateParameter(p_parameter_name3, p_parameter_value3);
2838 i := i + 1;
2839 end if;
2840
2841 if (p_parameter_name4 is not NULL) then
2842 l_parameter_list.extend;
2843 l_parameter_list(i) := CreateParameter(p_parameter_name4, p_parameter_value4);
2844 i := i + 1;
2845 end if;
2846
2847 if (p_parameter_name5 is not NULL) then
2848 l_parameter_list.extend;
2849 l_parameter_list(i) := CreateParameter(p_parameter_name5, p_parameter_value5);
2850 i := i + 1;
2851 end if;
2852
2853 if (p_parameter_name6 is not NULL) then
2854 l_parameter_list.extend;
2855 l_parameter_list(i) := CreateParameter(p_parameter_name6, p_parameter_value6);
2856 i := i + 1;
2857 end if;
2858
2859 if (p_parameter_name7 is not NULL) then
2860 l_parameter_list.extend;
2861 l_parameter_list(i) := CreateParameter(p_parameter_name7, p_parameter_value7);
2862 i := i + 1;
2863 end if;
2864
2865 if (p_parameter_name8 is not NULL) then
2866 l_parameter_list.extend;
2867 l_parameter_list(i) := CreateParameter(p_parameter_name8, p_parameter_value8);
2868 i := i + 1;
2869 end if;
2870
2871 if (p_parameter_name9 is not NULL) then
2872 l_parameter_list.extend;
2873 l_parameter_list(i) := CreateParameter(p_parameter_name9, p_parameter_value9);
2874 i := i + 1;
2875 end if;
2876
2877 if (p_parameter_name10 is not NULL) then
2878 l_parameter_list.extend;
2879 l_parameter_list(i) := CreateParameter(p_parameter_name10, p_parameter_value10);
2880 i := i + 1;
2881 end if;
2882
2883 if (p_parameter_name11 is not NULL) then
2884 l_parameter_list.extend;
2885 l_parameter_list(i) := CreateParameter(p_parameter_name11, p_parameter_value11);
2886 i := i + 1;
2887 end if;
2888
2889 if (p_parameter_name12 is not NULL) then
2890 l_parameter_list.extend;
2891 l_parameter_list(i) := CreateParameter(p_parameter_name12, p_parameter_value12);
2892 i := i + 1;
2893 end if;
2894
2895 if (p_parameter_name13 is not NULL) then
2896 l_parameter_list.extend;
2897 l_parameter_list(i) := CreateParameter(p_parameter_name13, p_parameter_value13);
2898 i := i + 1;
2899 end if;
2900
2901 if (p_parameter_name14 is not NULL) then
2902 l_parameter_list.extend;
2903 l_parameter_list(i) := CreateParameter(p_parameter_name14, p_parameter_value14);
2904 i := i + 1;
2905 end if;
2906
2907 if (p_parameter_name15 is not NULL) then
2908 l_parameter_list.extend;
2909 l_parameter_list(i) := CreateParameter(p_parameter_name15, p_parameter_value15);
2910 i := i + 1;
2911 end if;
2912
2913 if (p_parameter_name16 is not NULL) then
2914 l_parameter_list.extend;
2915 l_parameter_list(i) := CreateParameter(p_parameter_name16, p_parameter_value16);
2916 i := i + 1;
2917 end if;
2918
2919 if (p_parameter_name17 is not NULL) then
2920 l_parameter_list.extend;
2921 l_parameter_list(i) := CreateParameter(p_parameter_name17, p_parameter_value17);
2922 i := i + 1;
2923 end if;
2924
2925 if (p_parameter_name18 is not NULL) then
2926 l_parameter_list.extend;
2927 l_parameter_list(i) := CreateParameter(p_parameter_name18, p_parameter_value18);
2928 i := i + 1;
2929 end if;
2930
2931 if (p_parameter_name19 is not NULL) then
2932 l_parameter_list.extend;
2933 l_parameter_list(i) := CreateParameter(p_parameter_name19, p_parameter_value19);
2934 i := i + 1;
2935 end if;
2936
2937 if (p_parameter_name20 is not NULL) then
2938 l_parameter_list.extend;
2939 l_parameter_list(i) := CreateParameter(p_parameter_name20, p_parameter_value20);
2940 end if;
2941
2942 wf_event.raise(p_event_name, p_event_key, p_event_data, l_parameter_list, p_send_date);
2943
2944 exception
2945 when others then
2946 raise;
2947 end raise2;
2948 ---------------------------------------------------------------------------
2949 /*
2950 ** CreateParameter - <Described in WFEVENTS.pls>
2951 */
2952 FUNCTION CreateParameter( p_name in varchar2,
2953 p_value in varchar2)
2954 return wf_parameter_t
2955 is
2956 l_parameter wf_parameter_t := wf_parameter_t(null, null);
2957 begin
2958 l_parameter.SetName(p_name);
2959 l_parameter.SetValue(p_value);
2960 return l_parameter;
2961 exception
2962 when others then
2963 raise;
2964 end CreateParameter;
2965
2966 --------------------------------------------------------------------
2967 --Bug 2375902
2968 --New API raise3 which has the parameters of the event
2969 --as in out parameters and hence can be used by the calling program.
2970 --------------------------------------------------------------------
2971 PROCEDURE raise3(p_event_name in varchar2,
2972 p_event_key in varchar2,
2973 p_event_data in clob,
2974 p_parameter_list in out nocopy wf_parameter_list_t,
2975 p_send_date in date)
2976 is
2977 o_value varchar2(200);
2978 event wf_event_t;
2979 begin
2980
2981 -- Bug 9370391: tag DB session for BES module
2982 wf_core.tag_db_session(wf_core.conn_tag_bes, p_event_name);
2983
2984 if (wf_log_pkg.level_procedure >= fnd_log.g_current_runtime_level) then
2985 wf_log_pkg.string(wf_log_pkg.level_procedure,
2986 'wf.plsql.WF_EVENT.raise3.Begin',
2987 'Event Name:'||p_event_name||' Event Key:'||p_event_key ||
2988 'Maximum nested raise count:'|| wf_event.max_nested_raises||
2989 'Nested raise count: '|| wf_event.nested_raise_count);
2990 end if;
2991
2992 wf_event.nested_raise_count := wf_event.nested_raise_count + 1;
2993 if (wf_event.nested_raise_count > wf_event.max_nested_raises) then
2994 --Bug 2620834
2995 --The nested count is reset to the initial value that was set before the
2996 --recursion error occurs.
2997 --In future if we allow the user to set the nested-raises -count
2998 --we could think of restting it to that value instead of zero.
2999 wf_event.nested_raise_count := 0;
3000
3001 if (wf_log_pkg.level_error >= fnd_log.g_current_runtime_level) then
3002 wf_log_pkg.string(wf_log_pkg.level_error,
3003 'wf.plsql.WF_EVENT.raise3.recursion_error',
3004 'Recursion error raised. Nested raise count exceeded threshold');
3005 end if;
3006
3007 wf_core.context('Wf_Event', 'raise', p_event_name, p_event_key);
3008 wf_core.raise('WFE_RECURSION');
3009 end if;
3010
3011 --Create the event that is to be raised
3012 wf_event_t.initialize(event);
3013 event.Send_Date := nvl(p_send_date,sysdate);
3014 event.Event_Name := p_event_name;
3015 event.Event_Key := p_event_key;
3016 event.Parameter_List := p_parameter_list;
3017 if (p_event_data is not null) then
3018 event.event_data := p_event_data ;
3019 end if;
3020
3021 wf_event.dispatch('LOCAL', null, event);
3022
3023 --Output the parameterlist which may have been
3024 --modified
3025 p_parameter_list := event.getParameterList();
3026
3027 if (wf_event.nested_raise_count >0) then
3028 wf_event.nested_raise_count := wf_event.nested_raise_count - 1;
3029 end if;
3030
3031 event := null;
3032
3033 exception
3034 when others then
3035 raise;
3036 end raise3;
3037
3038 --------------------------------------------------------------------------------
3039 -- Sets the correlation for dequeuing.
3040 --
3041 -- NOTE: This has been done because we did not want to change the signature of
3042 -- dequeue in the queue handlers
3043 --
3044 -- p_correlation - the correlation
3045 --------------------------------------------------------------------------------
3046 PROCEDURE Set_Correlation(p_correlation in varchar2)
3047 IS
3048 BEGIN
3049 WF_EVENT.g_correlation := p_correlation;
3050 WF_EVENT.navigation := dbms_aq.first_message;
3051
3052 END Set_Correlation;
3053
3054 ---------------------------------------------------------------------------
3055 /*
3056 ** SetMaxNestedRaise - Populates Global Variable : max_nested_raises
3057 ** with the value specified in the input parameter.
3058 */
3059 PROCEDURE SetMaxNestedRaise (maxcount in number)
3060 is
3061 begin
3062 wf_event.max_nested_raises := maxcount;
3063 end;
3064 ---------------------------------------------------------------------------
3065 /*
3066 ** SetNestedRaiseCount - Populates Global Variable : nested_raises_count
3067 ** with the value specified in the input parameter.
3068 ** PRIVATE PROCEDURE
3069 */
3070 PROCEDURE SetNestedRaiseCount (nestedcount in number)
3071 is
3072 begin
3073 wf_event.nested_raise_count := nestedcount;
3074 --This private variable P_NESTED_RAISE_COUNT is updated
3075 --in sync with the setting of nested_raise_count global variable
3076 --It is used when the recursion error occurs inorder to reset the
3077 --value of wf_event.nested_raise_count.
3078 --P_NESTED_RAISE_COUNT := wf_event.nested_raise_count;
3079 end;
3080 ---------------------------------------------------------------------------
3081 /*
3082 ** GetMaxNestedRaise - Get the value of the Global Variable max_nested_raises
3083 */
3084
3085 FUNCTION GetMaxNestedRaise
3086 return number
3087 is
3088 begin
3089 return wf_event.max_nested_raises;
3090 end;
3091
3092 ---------------------------------------------------------------------------
3093 /*
3094 ** GetNestedRaiseCount - Get the value of the Global Variable
3095 ** nested_raises_count
3096 */
3097
3098 FUNCTION GetNestedRaiseCount
3099 return number
3100 is
3101 begin
3102 return wf_event.nested_raise_count;
3103 end;
3104
3105 ---------------------------------------------------------------------------
3106
3107 FUNCTION Get_MsgId
3108 return varchar2
3109 is
3110 begin
3111 return wf_event.g_msgid;
3112 end;
3113
3114 ---------------------------------------------------------------------------
3115 /*
3116 ** GetLocalSystemInfo - <described in WFEVENTS.pls>
3117 */
3118 PROCEDURE GetLocalSystemInfo(system_guid out nocopy raw,
3119 system_name out nocopy varchar2,
3120 system_status out nocopy varchar2)
3121 is
3122 begin
3123 system_guid := wf_event.local_system_guid;
3124 system_name := wf_event.local_system_name;
3125 system_status := wf_event.local_system_status;
3126 exception
3127 when others then
3128 wf_core.context('Wf_Event', 'GetLocalSystemName');
3129 end GetLocalSystemInfo;
3130 ---------------------------------------------------------------------------
3131 /*
3132 ** GetSourceAgentGUID - <described in WFEVENTS.pls>
3133 */
3134 PROCEDURE GetSourceAgentGUID(agent_name in varchar2,
3135 agent_system in varchar2,
3136 agent_guid out nocopy raw)
3137 is
3138 -- bes caching implementation
3139 l_agent_obj wf_agent_obj;
3140 begin
3141
3142 l_agent_obj := wf_bes_cache.GetAgentByName(agent_name, agent_system);
3143
3144 if (l_agent_obj is not null) then
3145 agent_guid := l_agent_obj.GUID;
3146 else
3147 if (wf_log_pkg.level_error >= fnd_log.g_current_runtime_level) then
3148 wf_log_pkg.string(wf_log_pkg.level_error,
3149 'wf.plsql.WF_EVENT.GetSourceAgentGUID.Error',
3150 'Specified source agent row does '||
3151 'not exist in database. Setting to NULL.');
3152 end if;
3153 agent_guid := null;
3154 end if;
3155 exception
3156 when others then
3157 wf_core.context('Wf_Event', 'GetSourceAgentGUID', agent_name);
3158 raise;
3159 end GetSourceAgentGUID;
3160 ---------------------------------------------------------------------------
3161 /*
3162 ** GetAgentDetails (PRIVATE) - Gets the agents details such as the queue name
3163 ** schema name and recepients
3164 */
3165 procedure GetAgentDetails(agent_name in varchar2)
3166 is
3167
3168 l_queue_name varchar2(80);
3169 l_pos number := 0;
3170 l_name varchar2(30);
3171 l_owner varchar2(30);
3172 l_queue_table varchar2(30);
3173
3174 -- bes caching implementation
3175 l_agent_obj wf_agent_obj;
3176 begin
3177 if (wf_log_pkg.level_procedure >= fnd_log.g_current_runtime_level) then
3178 wf_log_pkg.string(wf_log_pkg.level_procedure,
3179 'wf.plsql.WF_EVENT.GetAgentDetails.Begin',
3180 'Get Agent Details');
3181 end if;
3182
3183 if(agent_name is not null and agent_name <> wf_event.pv_last_agent_name) then
3184 -- for a given agent name Query wf_agents to get the agent info
3185
3186 l_agent_obj := wf_bes_cache.GetAgentByName(agent_name, null);
3187 if (l_agent_obj is not null) then
3188 l_queue_name := l_agent_obj.QUEUE_NAME;
3189 end if;
3190
3191 if (wf_log_pkg.level_statement >= fnd_log.g_current_runtime_level) then
3192 wf_log_pkg.string(wf_log_pkg.level_statement,
3193 'wf.plsql.WF_EVENT.GetAgentDetails',
3194 'l_queue_name = ' || l_queue_name);
3195 end if;
3196
3197 -- since since queue_name is a nullable col. l_queue_name could be null
3198 -- let the caller program handle the case of null queue_name
3199 if(l_queue_name is not null) then
3200 -- derive the queue name and the schema
3201
3202 l_pos := instr(l_queue_name,'.');
3203 l_name := substr(l_queue_name, l_pos + 1);
3204
3205 if (l_pos > 0) then
3206 l_owner := substr(l_queue_name, 1, l_pos - 1);
3207 else
3208 -- if queue_name does not contain schema we will look in WF_SCHEMA
3209 l_owner := wf_event.schema_name;
3210 end if;
3211
3212 if (wf_log_pkg.level_statement >= fnd_log.g_current_runtime_level) then
3213 wf_log_pkg.string(wf_log_pkg.level_statement,
3214 'wf.plsql.WF_EVENT.GetAgentDetails',
3215 'l_name = ' || l_name ||
3216 ' l_owner = ' || l_owner);
3217 end if;
3218
3219 -- retrieve recipients (MULTIPLE or SINGLE) for AQ
3220 -- 3659756 When get agent details, check if the enqueue and dequeue are enabled.
3221 select aq.queue_type, aq.QUEUE_TABLE, trim(dequeue_enabled)
3222 into WF_EVENT.g_queueType, l_queue_table, WF_EVENT.pv_last_dequeue_enabled
3223 from all_queues aq
3224 where aq.owner = l_owner
3225 and aq.name = l_name;
3226
3227 select aqt.recipients, aqt.message_grouping
3228 into WF_EVENT.pv_last_recipients, WF_EVENT.g_message_grouping
3229 from all_queue_tables aqt
3230 where aqt.queue_table = l_queue_table
3231 and aqt.owner = l_owner;
3232
3233 -- update package variables
3234 wf_event.pv_last_agent_name := agent_name;
3235 -- YOHUANG, l_queue_name shouldn't have owner information
3236 wf_event.pv_last_queue_name := l_name; --l_queue_name;
3237 wf_event.pv_last_schema_name := l_owner;
3238 else
3239 raise no_data_found;
3240 end if;
3241 end if;
3242 if (wf_log_pkg.level_procedure >= fnd_log.g_current_runtime_level) then
3243 wf_log_pkg.string(wf_log_pkg.level_procedure,
3244 'wf.plsql.WF_EVENT.GetAgentDetails.END',
3245 'Get Agent Details');
3246 end if;
3247 exception
3248 when no_data_found then
3249 -- let the caller handle it
3250 raise;
3251 when others then
3252 -- let the caller handle it
3253 raise;
3254 end GetAgentDetails;
3255 ---------------------------------------------------------------------------
3256 /*
3257 ** StartAgent - <described in WFEVENTS.pls>
3258 ** Though We cache the agent details, we still check if the agent and
3259 ** fixed name queues are started or not every time when listen() or
3260 ** listen_to_agent is called, just be conservative
3261 ** Bug 3659756
3262 ** Assume the fixed name queues are always started (if not, the component listener
3263 ** will error out and sys admin will fix it)
3264 ** Only start the agent that is being listened.
3265 ** Only start the agent once per session if agent name is not changed in the same session.
3266 */
3267 procedure StartAgent(agent_name in varchar2)
3268 is
3269 -- l_enqueue_enabled VARCHAR2(30);
3270 -- l_dequeue_enabled VARCHAR2(30);
3271
3272 --Bug 2307433
3273 --Cursor for obtaining the names of the
3274 --deferred and error queue.
3275 --Bug 3271311, add the WF_JAVA queues for start.
3276 --Bug 3659756, no longer start fixed name queues.
3277 /**
3278 CURSOR q_disabled (schema varchar2) is
3279 SELECT name
3280 FROM all_queues
3281 WHERE name in ('WF_DEFERRED', 'WF_ERROR', 'WF_JAVA_DEFERRED','WF_JAVA_ERROR')
3282 AND owner =schema
3283 AND ((trim(enqueue_enabled) = 'NO') OR (trim(dequeue_enabled) = 'NO'));
3284 */
3285
3286 begin
3287 if (wf_log_pkg.level_procedure >= fnd_log.g_current_runtime_level) then
3288 wf_log_pkg.string(wf_log_pkg.level_procedure,
3289 'wf.plsql.WF_EVENT.StartAgent.Begin',
3290 'Starting Agents');
3291 end if;
3292 --Bug 2307433
3293 --Enable the deferred and error queues for
3294 --enqueue and dequeue incase they are disabled
3295 --In any cases, the WF_DEFERRED, WF_ERROR, WF_JAVA_ERROR and WF_JAVA_DEFERRED
3296 --must be started.
3297 --schema := wf_core.translate('WF_SCHEMA');
3298 --Bug 3659756, no longer start fixed name queues.
3299 /*
3300 for q_name in q_disabled (wf_event.schema_name) loop
3301 DBMS_AQADM.START_QUEUE(wf_event.schema_name||'.'||q_name.name);
3302 end loop;
3303 */
3304 -- The agent details must be retrieved even for seeded queue.
3305 GetAgentDetails(agent_name);
3306
3307 if (wf_log_pkg.level_statement >= fnd_log.g_current_runtime_level) then
3308 wf_log_pkg.string(wf_log_pkg.level_statement,
3309 'wf.plsql.WF_EVENT.StartAgent',
3310 'dequeue_enabled = ' || WF_EVENT.pv_last_dequeue_enabled);
3311 end if;
3312
3313 if (WF_EVENT.pv_last_dequeue_enabled = 'NO') then
3314 -- If the user has disabled the queue for enqueue don't override it.
3315 -- So we only enable the dequeue if dequeue is not enabled and we don't change
3316 -- the current setting of enqueue.
3317
3318 if (wf_log_pkg.level_statement >= fnd_log.g_current_runtime_level) then
3319 wf_log_pkg.string(wf_log_pkg.level_statement,
3320 'wf.plsql.WF_EVENT.StartAgent',
3321 'starting queue = ' || wf_event.pv_last_schema_name
3322 || '.' || wf_event.pv_last_agent_name);
3323 end if;
3324
3325 DBMS_AQADM.START_QUEUE(wf_event.pv_last_schema_name || '.' || wf_event.pv_last_queue_name, FALSE);
3326
3327 WF_EVENT.pv_last_dequeue_enabled := 'YES';
3328 end if;
3329
3330 if (wf_log_pkg.level_procedure >= fnd_log.g_current_runtime_level) then
3331 wf_log_pkg.string(wf_log_pkg.level_procedure,
3332 'wf.plsql.WF_EVENT.StartAgent.End',
3333 'Starting Agents');
3334 end if;
3335 exception
3336 when no_data_found then
3337 wf_core.context('Wf_Event', 'StartAgent', agent_name);
3338 wf_core.raise('WFE_AGENT_NOTEXIST');
3339 when others then
3340 wf_core.context('Wf_Event', 'StartAgent', agent_name);
3341 raise;
3342 end StartAgent;
3343 ---------------------------------------------------------------------------
3344 /*
3345 ** Peek_Agent - <Described in WFEVENTS.pls>
3346 */
3347 FUNCTION Peek_Agent (p_agent_name IN VARCHAR2)
3348 RETURN VARCHAR2
3349 AS
3350 -- NOTE: This must be done in PL/SQL because in 8i DBMS_AQ.LISTEN is not
3351 -- supported in Java
3352
3353 l_agent sys.aq$_agent;
3354 l_agent_list dbms_aq.aq$_agent_list_t;
3355
3356 LISTEN_EXCEPTION exception;
3357
3358 pragma exception_init(LISTEN_EXCEPTION, -25254);
3359 BEGIN
3360
3361 if p_agent_name is null then
3362 return 'N';
3363 end if;
3364
3365 -- Perf bug 2987857
3366 -- If p_agent_name is same as pkg var, then details are not required
3367 -- to be retrieved again
3368 -- YOHUANG, move the cache validation logic into getAgentDetails
3369
3370 -- Retrieve queue name for the agent
3371 -- Only local agents should be checked for - bug 2902048
3372 -- GetAgentDetails becomes the single source to start a particular agent
3373 -- and can be called without worrying about fixed name queues
3374 GetAgentDetails(p_agent_name);
3375
3376 -- bug 2897326, agent_list is initialized differently for
3377 -- multi or single consumer queue
3378
3379 IF wf_event.pv_last_recipients = 'MULTIPLE' THEN
3380 l_agent_list(1) := sys.aq$_agent(wf_event.pv_last_agent_name,
3381 wf_event.pv_last_schema_name || '.' || wf_event.pv_last_queue_name, null);
3382 ELSE
3383 l_agent_list(1) := sys.aq$_agent(null,
3384 wf_event.pv_last_schema_name || '.' || wf_event.pv_last_queue_name, null);
3385 END IF;
3386
3387 -- "Listen" for messages on this queue
3388 BEGIN
3389 DBMS_AQ.Listen(agent_list => l_agent_list,
3390 wait => 0,
3391 agent => l_agent);
3392 EXCEPTION
3393 WHEN LISTEN_EXCEPTION THEN
3394 RETURN 'N';
3395 END;
3396
3397 RETURN 'Y';
3398 END Peek_Agent ;
3399
3400 -- GetParamListFromString
3401 -- Takes a space delimited NAME=VALUE pairs of Subscription Parameters
3402 -- string and returns a WF_PARAMETER_LIST_T
3403 -- IN
3404 -- p_parameters A string with space delimited name=value pairs
3405 function GetParamListFromString(p_parameters in varchar2)
3406 return wf_parameter_list_t
3407 is
3408 l_parameters varchar2(5000);
3409 l_start pls_integer := 0;
3410 l_end pls_integer := 0;
3411 l_endposition number;
3412 l_namevalue varchar2(4000);
3413 l_value varchar2(4000);
3414 l_name varchar2(4000);
3415 l_equalpos number;
3416 l_param_list wf_parameter_list_t;
3417 begin
3418 l_parameters := p_parameters;
3419
3420 if (l_parameters is not null) then
3421 l_parameters := replace(l_parameters, wf_core.newline,' ');
3422 l_parameters := replace(l_parameters, wf_core.tab,' ');
3423 l_parameters := replace(l_parameters, wf_core.cr,'');
3424 l_parameters := l_parameters||' ';
3425
3426 l_start:= 1;
3427 l_end := length(l_parameters);
3428
3429 while (l_start < l_end) loop
3430 l_endposition := instr(l_parameters, ' ', l_start, 1);
3431 l_namevalue := rtrim(ltrim(substr(l_parameters, l_start, l_endposition-l_start)));
3432
3433 l_equalpos := instr(l_namevalue, '=', 1, 1);
3434 l_name := substr(l_namevalue,1,l_equalpos-1);
3435 l_value := substr(l_namevalue,l_equalpos+1,length(l_namevalue));
3436
3437 wf_event.AddParameterToList(l_name, l_value, l_param_list);
3438 l_start := l_endposition+1;
3439 end loop;
3440 end if;
3441 return l_param_list;
3442 exception
3443 when others then
3444 wf_core.Context('WF_EVENT', 'GetParamListFromString');
3445 raise;
3446 end GetParamListFromString;
3447
3448 /* PRIVATE
3449 *
3450 * gets the agent's message_grouping, returns TRUE if TRANSACTIONAL, FALSE
3451 * otherwise.
3452 */
3453 function isValidToGroupMessages(p_agentName in varchar2) return boolean
3454 is
3455 l_msgGrouping varchar2(30);
3456 begin
3457 if (p_agentName is not null) then
3458
3459 if(p_agentName <> wf_event.pv_last_agent_name) then
3460 GetAgentDetails(p_agentName);
3461 end if;
3462
3463 return (WF_EVENT.g_message_grouping = 'TRANSACTIONAL');
3464 else
3465 return false;
3466 end if;
3467 exception
3468 when OTHERS then
3469 return false;
3470 end;
3471
3472 -- for logging purposes
3473 function getNavigationParams return varchar2 is
3474 l_ret varchar2(1000):= 'navigation(';
3475 begin
3476 if (g_currentNavigation is null) then
3477 l_ret:= l_ret|| 'null), ';
3478 elsif g_currentNavigation= dbms_aq.NEXT_MESSAGE then
3479 l_ret:= l_ret|| 'NEXT_MESSAGE), ';
3480 elsif g_currentNavigation= dbms_aq.FIRST_MESSAGE then
3481 l_ret:= l_ret|| 'FIRST_MESSAGE), ';
3482 elsif g_currentNavigation= dbms_aq.NEXT_TRANSACTION then
3483 l_ret:= l_ret|| 'NEXT_TRANSACTION), ';
3484 else
3485 l_ret:= l_ret|| g_currentNavigation||'), ';
3486 end if;
3487
3488 l_ret := l_ret|| ' threshold(';
3489 if (g_navResetThreshold is null) then
3490 l_ret:= l_ret|| 'null), ';
3491 else
3492 l_ret:= l_ret|| g_navResetThreshold||'), ';
3493 end if;
3494
3495 l_ret := l_ret|| ' messageCount(';
3496 if (g_processedMessagesCount is null) then
3497 l_ret:= l_ret|| 'null), ';
3498 else
3499 l_ret:= l_ret|| g_processedMessagesCount||'), ';
3500 end if;
3501
3502 l_ret := l_ret|| ' message grouping(';
3503 if (g_groupDequeuing) then
3504 l_ret:= l_ret|| 'TRUE)';
3505 else
3506 l_ret:= l_ret|| 'FALSE)';
3507 end if;
3508
3509 return l_ret;
3510 end getNavigationParams;
3511
3512 -- PUBLIC - see description in package spec
3513 procedure setNavigationParams(p_agentName in varchar2
3514 , p_navigationThreshold in number)
3515 is
3516 l_api varchar2(100) := g_packName||'setNavigationParams';
3517 begin
3518 if (wf_log_pkg.level_procedure >= fnd_log.g_current_runtime_level) then
3519 wf_log_pkg.string(wf_log_pkg.level_procedure, l_api,
3520 'BEGIN agent('||p_agentName||'), navigationThreshold(' ||
3521 p_navigationThreshold||')');
3522 end if;
3523
3524 -- if not parameters are passed, we assume it is a call from exception block,
3525 -- so we keep previous values IF ANY, except for g_processedMessagesCount
3526 if (p_agentName is not null) then
3527 -- 0 or positive are valid only
3528 if (p_navigationThreshold>0) then
3529 g_navResetThreshold := p_navigationThreshold;
3530 else
3531 g_navResetThreshold:=0; -- default behavior, no max threshold
3532 end if;
3533
3534 g_groupDequeuing := isValidToGroupMessages(p_agentName);
3535 g_currentNavigation :=null;
3536 end if;
3537
3538 g_processedMessagesCount :=0;
3539
3540 if (wf_log_pkg.level_procedure >= fnd_log.g_current_runtime_level) then
3541 wf_log_pkg.string(wf_log_pkg.level_procedure, l_api,
3542 'END '||getNavigationParams);
3543 end if;
3544 end;
3545
3546 -- PUBLIC - see description in package spec
3547 function getQueueNavigation return BINARY_INTEGER is
3548 l_ret BINARY_INTEGER;
3549 l_api varchar2(100) := g_packName||'getQueueNavigation';
3550 begin
3551 if (wf_log_pkg.level_procedure >= fnd_log.g_current_runtime_level) then
3552 wf_log_pkg.string(wf_log_pkg.level_procedure, l_api,
3553 'BEGIN '||getNavigationParams);
3554 end if;
3555 if (g_navResetThreshold is null) then -- agent navigation not initialized
3556 -- since we don't know what is the component parameter, we assume default
3557 -- behavior
3558 g_navResetThreshold :=0;
3559 end if;
3560
3561 -- TRANSACTIONAL dequeuing, no threshold logic
3562 if ( g_groupDequeuing ) then
3563
3564 -- first call (g_processedMessagesCount = 0).
3565 -- If navigation params are not initialized, return FIRST_MESSAGE
3566 -- else return NEXT_MESSAGE
3567 if ( g_processedMessagesCount = 0 ) then
3568 if (g_currentNavigation is null) then
3569 l_ret := dbms_aq.FIRST_MESSAGE;
3570 else
3571 l_ret := dbms_aq.NEXT_TRANSACTION;
3572 end if;
3573 else
3574 l_ret := dbms_aq.NEXT_MESSAGE;
3575 end if;
3576 else -- no TRANSACTIONAL navigation, threshold logic applies
3577
3578 -- If first call (g_processedMessagesCount = 0), or if threshold is
3579 -- reached, return FIRST_MESSAGE,
3580 -- else return NEXT_MESSAGE
3581 if ( g_processedMessagesCount = 0 ) or
3582 (g_navResetThreshold >0 and
3583 g_ProcessedMessagesCount >= g_navResetThreshold)
3584 then
3585 g_processedMessagesCount := 0; -- reset counter, if threshold is reached
3586 l_ret := dbms_aq.FIRST_MESSAGE;
3587 else
3588 l_ret := dbms_aq.NEXT_MESSAGE;
3589 end if;
3590 end if;
3591
3592 g_processedMessagesCount := g_processedMessagesCount + 1;
3593 g_currentNavigation := l_ret;
3594
3595 if (wf_log_pkg.level_procedure >= fnd_log.g_current_runtime_level) then
3596 wf_log_pkg.string(wf_log_pkg.level_procedure, l_api
3597 ,'END return='||getNavigationParams);
3598 end if;
3599
3600 return l_ret;
3601 end;
3602
3603 procedure resetNavigationParams
3604 is
3605 begin
3606 -- pass no parameters, just reset message counter
3607 setNavigationParams;
3608 end;
3609
3610 /*
3611 ** Submits the concurrent request for FNDWFLIC CP.
3612 ** -- It being used to submit CP reuqest from PATCH edition.
3613 */
3614 procedure submit_cp_request
3615 is
3616
3617 l_count number := 0;
3618 l_request_id number;
3619 l_returncode boolean;
3620 l_user_id fnd_user.user_id%TYPE;
3621 l_user_name fnd_user.user_name%TYPE;
3622 l_resp_appl_id fnd_responsibility.application_id%TYPE;
3623 l_resp_key fnd_responsibility.responsibility_key%TYPE;
3624 l_resp_id fnd_responsibility.responsibility_id%TYPE;
3625 l_appl_short_name fnd_application.application_short_name%TYPE;
3626
3627 PRAGMA AUTONOMOUS_TRANSACTION;
3628
3629 begin
3630
3631 select count(1)
3632 into l_count
3633 from fnd_concurrent_requests
3634 where concurrent_program_id in
3635 (select concurrent_program_id
3636 from fnd_concurrent_programs
3637 where concurrent_program_name = 'FNDWFLIC')
3638 and phase_code = 'P' -- Pending
3639 and status_code = 'I' -- Normal
3640 and edition_name = ad_zd.get_edition
3641 and rownum < 2;
3642
3643 -- Bug 16676888: submit CP request for FNDWFLIC only if there is no
3644 -- request submitted already from patch edition
3645 if(l_count = 0) then
3646
3647 l_appl_short_name := 'SYSADMIN';
3648 l_user_name := 'SYSADMIN';
3649 l_resp_key := 'SYSTEM_ADMINISTRATOR';
3650
3651 begin
3652
3653 SELECT u.user_id
3654 INTO l_user_id
3655 FROM fnd_user u
3656 WHERE u.user_name = l_user_name;
3657
3658 SELECT r.application_id, r.responsibility_id
3659 INTO l_resp_appl_id, l_resp_id
3660 FROM fnd_application a, fnd_responsibility r
3661 WHERE r.application_id = a.application_id
3662 AND a.application_short_name = l_appl_short_name
3663 AND r.responsibility_key = l_resp_key;
3664
3665 exception
3666 when no_data_found then
3667 l_user_id := 0;
3668 l_resp_id := 20420;
3669 l_resp_appl_id := 1;
3670 end;
3671
3672 --Set the SYSADMIN context
3673 fnd_global.apps_initialize(
3674 user_id => l_user_id,
3675 resp_id => l_resp_id,
3676 resp_appl_id => l_resp_appl_id);
3677
3678 --Set database trigger mode to TRUE
3679 l_returncode := fnd_request.set_mode (TRUE);
3680
3681 l_request_id := fnd_request.submit_request(
3682 application => 'FND',
3683 program => 'FNDWFLIC',
3684 description => 'Submitted Concurrent request within
3685 FND_PROD_LIC_TGR trigger from PATCH edition',
3686 start_time => NULL,
3687 sub_request => FALSE);
3688 end if;
3689 commit;
3690
3691 end submit_cp_request;
3692
3693 ---------------------------------------------------------------------------
3694 /*
3695 ** SetSystemGlobals - Populates System Global Variables
3696 */
3697 begin
3698 wf_event.local_system_guid := hextoraw(wf_core.translate('WF_SYSTEM_GUID'));
3699
3700 wf_event.local_system_status := wf_core.translate('WF_SYSTEM_STATUS');
3701
3702 select name into wf_event.local_system_name
3703 from wf_systems
3704 where guid = wf_event.local_system_guid;
3705 ---------------------------------------------------------------------------
3706 wf_event.schema_name := wf_core.translate('WF_SCHEMA');
3707
3708 wf_event.pv_last_agent_name := ' ';
3709 wf_event.pv_last_queue_name := ' ';
3710 wf_event.pv_last_schema_name := ' ';
3711 wf_event.pv_last_recipients := ' ';
3712 wf_event.pv_last_dequeue_enabled := ' ';
3713
3714 end WF_EVENT;