1 package body FND_CONCURRENT as
2 /* $Header: AFCPUTLB.pls 120.18 2010/08/13 20:42:11 pferguso ship $ */
3 --
4 -- Package
5 -- FND_CONCURRENT
6 -- Purpose
7 -- Concurrent processing related utilities
8 -- History
9 -- XX/XX/93 Ram Bhoopalam Created
10 --
11 --
12 -- PRIVATE VARIABLES
13 --
14 oraerrmesg varchar2(240) := NULL;
15 P_ICMCID number := 0;
16 P_CRM boolean := FALSE;
17
18 PHASE_LOOKUP_TYPE constant varchar2(16) := 'CP_PHASE_CODE';
19 STATUS_LOOKUP_TYPE constant varchar2(16) := 'CP_STATUS_CODE';
20
21 TYpe ConcProcessLocks Is Table of
22 Fnd_Concurrent_Processes.Lk_Handle%TYPE
23 Index By Binary_Integer;
24
25 CmLkHandles ConcProcessLocks;
26
27
28 -- Exception info.
29
30 --
31 -- PRIVATE FUNCTIONS
32 -- --
33
34 function get_handle(cpid IN number default 0,
35 apid IN number default 0,
36 cqid IN number default 0,
37 lkhn IN OUT NOCOPY varchar2) return boolean is
38 result number;
39 icm_cid varchar2(20);
40 begin
41
42 if ( apid = 0 AND cqid = 1 ) then
43 Select Max(Concurrent_Process_ID)
44 Into icm_cid
45 From Fnd_Concurrent_Processes
46 Where Process_Status_Code = 'A'
47 And (Queue_Application_ID = 0 And
48 Concurrent_Queue_ID = 1);
49
50 if (Sql%NotFound) then
51 P_ICMCID := 0;
52 raise no_data_found;
53 end if;
54
55 if ( icm_cid <> P_ICMCID ) then
56 P_ICMCID := icm_cid;
57 raise no_data_found;
58 end if;
59 end if;
60
61 lkhn := CmLkHandles(cpid);
62 return TRUE;
63
64 exception
65 when no_data_found then
66 FND_DCP.get_lk_handle(apid, cqid, cpid, lkhn, result);
67 if ( result = 1 ) then
68 CmLKHandles(cpid) := lkhn;
69 return TRUE;
70 else
71 return FALSE;
72 end if;
73
74 when others then
75 oraerrmesg := substr(SQLERRM, 1, 80);
76 Fnd_Message.Set_Name('FND', 'CP-Generic oracle error');
77 Fnd_Message.Set_Token('ERROR', oraerrmesg, FALSE);
78 Fnd_Message.Set_Token('ROUTINE', 'FND_CONCURRENT.Get_Handle', FALSE);
79 return FALSE;
80 end get_handle;
81
82 -- procedure is internal to this package.
83 -- returns developer phase and status values for a given phase and status
84 -- codes.
85
86 procedure get_dev_phase_status(phase_code IN varchar2,
87 status_code IN varchar2,
88 dev_phase OUT NOCOPY varchar2,
89 dev_status OUT NOCOPY varchar2) is
90 begin
91 IF (phase_code = 'R') THEN
92 Dev_Phase := 'RUNNING';
93 ELSIF (phase_code = 'P') THEN
94 Dev_Phase := 'PENDING';
95 ELSIF (phase_code = 'C') THEN
96 Dev_Phase := 'COMPLETE';
97 ELSIF (phase_code = 'I') THEN
98 Dev_Phase := 'INACTIVE';
99 END IF;
100
101 IF (status_code = 'R') THEN
102 Dev_Status := 'NORMAL';
103 ELSIF (status_code = 'T') THEN
104 Dev_Status := 'TERMINATING';
105 ELSIF (status_code = 'A') THEN
106 Dev_Status := 'WAITING';
107 ELSIF (status_code = 'B') THEN
108 Dev_Status := 'RESUMING';
109
110 ELSIF (status_code = 'I') THEN
111 Dev_Status := 'NORMAL'; -- Pending normal
112 ELSIF (status_code = 'Q') THEN
113 Dev_Status := 'STANDBY'; -- Pending, due to incompatabilities
114 ELSIF (status_code = 'F' or status_code = 'P') THEN
115 Dev_Status := 'SCHEDULED'; --
116 ELSIF (status_code = 'W') THEN
117 Dev_Status := 'PAUSED'; --
118
119 ELSIF (status_code = 'H') THEN
120 Dev_Status := 'ON_HOLD'; -- Request Pending and on hold
121 ELSIF (status_code = 'S') THEN
122 Dev_Status := 'SUSPENDED'; --
123 ELSIF (status_code = 'U') THEN
124 Dev_Status := 'DISABLED'; -- Program has been disabled
125 ELSIF (status_code = 'M') THEN
126 Dev_Status := 'NO_MANAGER'; -- No defined manager can run it
127
128 ELSIF (status_code = 'C') THEN
129 Dev_Status := 'NORMAL'; -- Completed normally
130 ELSIF (status_code = 'G') THEN
131 Dev_Status := 'WARNING'; -- Completed with warning
132 ELSIF (status_code = 'E') THEN
133 Dev_Status := 'ERROR'; -- Completed with error
134 ELSIF (status_code = 'X') THEN
135 Dev_Status := 'TERMINATED'; -- Was terminated by user
136 ELSIF (status_code = 'D') THEN
137 --Bug8795072
138 --Dev_Status := 'DELETED'; -- Was deleted when pending
139 Dev_Status := 'CANCELLED'; -- Was deleted when pending
140 END IF;
141 end;
142
143 function get_svc_state(p_enabled IN varchar2,
144 p_ctrl_code IN varchar2,
145 p_run_procs IN varchar2,
146 p_max_procs IN varchar2) return varchar2 is
147
148 begin
149 if (p_enabled = 'N') then
150 return 'DISABLED';
151 elsif (p_ctrl_code IS NULL and p_run_procs > 0) then
152 return 'ACTIVE';
153 elsif ((p_ctrl_code IN ('E', 'X', 'N') or
154 p_ctrl_code IS NULL) and
155 p_run_procs = 0 and p_max_procs = 0) then
156 return 'INACTIVE';
157 elsif (p_ctrl_code = 'P') then
158 return 'SUSPENDED';
159 else
160 return 'TRANSIT';
161 end if;
162 end;
163
164
165 --
166 -- PUBLIC FUNCTIONS
167 --
168 --
169 -- Name
170 -- GET_REQUEST_STATUS
171 -- Purpose
172 -- returns the status of concurrent request and completion message
173 -- if the request has completed. Returns both user ( translatable )
174 -- and developer ( could you be used to compare/check and base their
175 -- program logic ) version for phase and status values.
176 -- Arguments ( input )
177 -- request_id - Request id for which status has to be checked
178 -- - If Application and prorgram information is passed,
179 -- - most recent request id for this program is returned
180 -- - along with the status and phase.
181 -- appl_shortname - Application to which the program belongs
182 -- program - Program name ( appl and program information used
183 -- - only if request id is not provided )
184 -- Arguments ( output )
185 -- phase - Request phase ( from meaning in fnd_lookups )
186 -- status - Request status( for display purposes )
187 -- dev_phase - Request phase as a constant string so that it
188 -- - can be used for comparisons )
189 -- dev_status - Request status as a constatnt string
190 -- message - Completion message if request has completed
191 --
192 function get_request_status(request_id IN OUT NOCOPY number,
193 appl_shortname IN varchar2 default NULL,
194 program IN varchar2 default NULL,
195 phase OUT NOCOPY varchar2,
196 status OUT NOCOPY varchar2,
197 dev_phase OUT NOCOPY varchar2,
198 dev_status OUT NOCOPY varchar2,
199 message OUT NOCOPY varchar2) return boolean is
200
201 Prog_Appl_ID number;
202 Program_ID number;
203 phase_code char;
204 status_code char;
205 req_phase char;
206 req_status char;
207 phasem varchar2(80);
208 statusm varchar2(80);
209 comptext varchar2(255);
210 Reqid_for_message varchar2(15);
211
212 Req_ID number := Request_ID;
213 program_validate_error exception;
214 fcr_access_error exception;
215 status_fetch_error exception;
216
217 begin
218 --
219 -- Check if request id is provided. If request id is not provided
220 -- then get the most recent request id for the program name given
221 --
222 dev_status := NULL;
223 dev_phase := NULL;
224 status := NULL;
225 phase := NULL;
226
227
228 if (Request_ID is null) then
229 if (Program is null or Appl_ShortName is null) then
230 Fnd_Message.Set_Name('FND', 'CONC-Req information required');
231 return FALSE;
232 end if;
233 begin
234 Select Concurrent_Program_ID, P.Application_ID
235 Into Program_ID, Prog_Appl_ID
236 From Fnd_Concurrent_Programs P,
237 Fnd_Application A
238 Where Concurrent_Program_Name = Program
239 And P.Application_ID = A.Application_ID
240 And A.Application_Short_Name = Appl_ShortName;
241 --
242 -- If no rows returned, return message "CONC-Invalid Appl/Prog combo"
243 --
244 exception
245 when no_data_found THEN
246 Fnd_Message.Set_Name('FND', 'CONC-Invalid Appl/Prog combo');
247 return FALSE;
248 when others then
249 raise; -- program_validate_error
250 end;
251 --
252 -- Check for the most recently submitted request for this program
253 --
254 begin
255 Select Max(Request_ID)
256 Into Req_ID
257 From Fnd_Concurrent_Requests
258 Where Program_Application_ID = Prog_Appl_ID
259 And Concurrent_Program_ID = Program_ID;
260 --
261 -- If No rows returned, then return message saying there are no
262 -- requests for this program "CONC-No req for appl/prog"
263 --
264 exception
265 when no_data_found then
266 Fnd_Message.Set_Name('FND', 'CONC-No req for appl/prog');
267 Fnd_Message.Set_Token('APPL', Appl_ShortName, FALSE);
268 Fnd_Message.Set_Token('PROGRAM', Program, FALSE);
269 return FALSE;
270 when others then
271 raise; -- fcr_access_error
272 end;
273
274 Request_ID := Req_ID;
275
276 end if;
277
278 --
279 -- Get Request Phase, Status and Completion Text
280 --
281 begin
282
283
284
285 Select Phase_Code, Status_Code, Completion_Text,
286 Phase.Lookup_Code, Status.Lookup_Code,
287 Phase.Meaning, Status.Meaning
288 Into req_phase, req_status, comptext,
289 phase_code, status_code,
290 phasem, statusm
291 From Fnd_Concurrent_Requests R,
292 Fnd_Concurrent_programs P,
293 Fnd_Lookups Phase,
294 Fnd_Lookups Status
295 Where
296 Phase.Lookup_Type = PHASE_LOOKUP_TYPE
297 AND Phase.Lookup_Code = Decode(Status.Lookup_Code,
298 'H', 'I',
299 'S', 'I',
300 'U', 'I',
301 'M', 'I',
302 R.Phase_Code) AND
303 Status.Lookup_Type = STATUS_LOOKUP_TYPE AND
304 Status.Lookup_Code =
305 Decode(R.Phase_Code,
306 'P', Decode(R.Hold_Flag, 'Y', 'H',
307 Decode(P.Enabled_Flag, 'N', 'U',
308 Decode(Sign(R.Requested_Start_Date - SYSDATE),1,'P',
309 R.Status_Code))),
310 'R', Decode(R.Hold_Flag, 'Y', 'S',
311 Decode(R.Status_Code, 'Q', 'B',
312 'I', 'B',
313 R.Status_Code)),
314 R.Status_Code)
315 And (R.Concurrent_Program_Id = P.Concurrent_program_ID AND
316 R.Program_Application_ID= P.Application_ID )
317 And Request_Id = Req_ID;
318 --
319 -- If no rows, return message...
320 --
321 exception
322 when no_data_found then
323 Reqid_for_message := Req_ID;
324 Fnd_Message.Set_Name('FND', 'CONC-Request missing');
325 Fnd_Message.Set_Token('ROUTINE',
326 'FND_CONCURRENT.GET_REQUEST_STATUS', FALSE);
327 Fnd_Message.Set_Token('REQUEST', Reqid_for_message, FALSE);
328 return FALSE;
329 when others then
330 raise; -- status_fetch_error
331 end;
332 --
333 -- Copy phase, status and completion text to out varaibles and
334 -- fill in developer names for phase and status
335 --
336 Phase := phasem;
337 Status := statusm;
338 message := comptext;
339
340 get_dev_phase_status(phase_code, status_code, dev_phase, dev_status);
341
342 return TRUE;
343 exception
344 -- when program_validate_error then
345 -- null;
346 -- when fcr_access_error then
347 -- null;
348 -- when status_fetch_error then
349 -- null;
350 when others then
351 oraerrmesg := substr(SQLERRM, 1, 80);
352 Fnd_Message.Set_Name('FND', 'CP-Generic oracle error');
353 Fnd_Message.Set_Token('ERROR', oraerrmesg, FALSE);
354 Fnd_Message.Set_Token('ROUTINE',
355 'FND_CONCURRENT.GET_REQUEST_STATUS', FALSE);
356 return FALSE;
357 end get_request_status;
358
359
360 --
361 -- Name
362 -- WAIT_FOR_REQUEST
363 -- Purpose
364 -- Waits for the request completion, returns phase/status and
365 -- completion text to the caller. Calls sleep between db checks.
366 -- Arguments (input)
367 -- request_id - Request ID to wait on
368 -- interval - time b/w checks. Number of seconds to sleep
369 -- - (default 60 seconds)
370 -- max_wait - Max amount of time to wait (in seconds)
371 -- - for request's completion
372 -- Arguments (output)
373 -- User version of phase and status
374 -- Developer version of phase and status
375 -- Completion text if any
376 -- phase - Request phase ( from meaning in fnd_lookups )
377 -- status - Request status( for display purposes )
378 -- dev_phase - Request phase as a constant string so that it
379 -- - can be used for comparisons )
380 -- dev_status - Request status as a constatnt string
381 -- message - Completion message if request has completed
382 --
383 function wait_for_request(request_id IN number default NULL,
384 interval IN number default 60,
385 max_wait IN number default 0,
386 phase OUT NOCOPY varchar2,
387 status OUT NOCOPY varchar2,
388 dev_phase OUT NOCOPY varchar2,
389 dev_status OUT NOCOPY varchar2,
390 message OUT NOCOPY varchar2) return boolean is
391 Call_Status boolean;
392 Time_Out boolean := FALSE;
393 pipename varchar2(60);
394 req_phase varchar2(15);
395 STime number(30);
396 ETime number(30);
397 Rid number := request_id;
398 i number;
399 begin
400 if (Rid is null) then
401 Fnd_Message.Set_Name('FND', 'CONC-Req information required');
402 return FALSE;
403 end if;
404
405 if ( max_wait > 0 ) then
406 Time_Out := TRUE;
407 Select To_Number(((To_Char(Sysdate, 'J') - 1 ) * 86400) +
408 To_Char(Sysdate, 'SSSSS'))
409 Into STime From Sys.Dual;
410 end if;
411
412 LOOP
413 call_status := FND_CONCURRENT.get_request_status(Rid, '', '',
414 phase, status, req_phase, dev_status, message);
415 if ( call_status = FALSE OR req_phase = 'COMPLETE' ) then
416 dev_phase := req_phase;
417 return (call_status);
418 end if;
419
420 if ( Time_Out ) then
421 Select To_Number(((To_Char(Sysdate, 'J') - 1 ) * 86400) +
422 To_Char(Sysdate, 'SSSSS'))
423 Into ETime From Sys.Dual;
424
425 if ( (ETime - STime) >= max_wait ) then
426 dev_phase := req_phase;
427 return (call_status);
428 end if;
429 end if;
430 dbms_lock.sleep(interval);
431 END LOOP;
432
433 exception
434 when others then
435 oraerrmesg := substr(SQLERRM, 1, 80);
436 Fnd_Message.Set_Name('FND', 'CP-Generic oracle error');
437 Fnd_Message.Set_Token('ERROR', oraerrmesg, FALSE);
438 Fnd_Message.Set_Token('ROUTINE',
439 'FND_CONCURRENT.WAIT_FOR_REQUEST', FALSE);
440 return FALSE;
441 end wait_for_request;
442
443 --
444 -- Name
445 -- FND_CONCURRENT_GET_MANAGER_STATUS
446 -- Purpose
447 -- Returns the target ( number that should be active at this instant )
448 -- and active number of processes for a given manager.
449 -- along with the current PMON method currently in use
450 -- Arguments (input)
451 -- applid - Application ID of application under which the
452 -- - manager is registered
453 -- managerid - Concurrent manager ID ( queue id )
454 -- (output)
455 -- target - Number of manager processes that should be active
456 -- - for the current workshift in effect
457 -- active - actual number of processes that are active
458 -- pmon_method - RDBMS/OS
459 -- message - message if any
460 --
461
462 procedure get_manager_status(applid IN number default 0,
463 managerid IN number default 1,
464 targetp OUT NOCOPY number,
465 activep OUT NOCOPY number,
466 pmon_method OUT NOCOPY varchar2,
467 callstat OUT NOCOPY number) is
468 lkh FND_CONCURRENT_PROCESSES.Lk_Handle%TYPE;
469 result number; -- result code from DBMS_LOCK.Request_Lock
470 alive number; -- is process alive? 1=TRUE 0=FALSE
471 i number := 0;
472 errflag boolean := FALSE;
473 gothandle boolean;
474 mtype number;
475 CartType varchar2(10);
476 cur_session_id number;
477
478 Cursor C1 IS
479 Select Concurrent_Process_Id, Session_Id
480 From Fnd_Concurrent_Processes
481 Where Process_Status_Code in ( 'A', 'C', 'T' )
482 And (Queue_Application_ID = applid and
483 Concurrent_Queue_ID = managerid );
484 begin
485 callstat := 0;
486 pmon_method := 'LOCK';
487
488
489 /* If a service and uses AQCART, use RDBMS PMON method */
490 /* If a service and does not use AQCART, return values */
491 /* from FCQ */
492 select manager_type,
493 Running_processes, MAX_PROCESSES, Cartridge_Handle
494 into mtype, ActiveP, TargetP, CartType
495 from Fnd_Concurrent_Queues Q, Fnd_Cp_Services S
496 Where S.Service_ID = Q.Manager_Type
497 And (Q.Application_ID = applid
498 And Q.Concurrent_Queue_ID = managerid);
499
500 if (mtype>999) then
501 if (CartType = 'AQCART') then
502 select count(*)
503 into ActiveP
504 from gv$session GV, fnd_concurrent_processes P
505 where
506 GV.Inst_id = P.Instance_number
507 And GV.audsid = p.session_id
508 And (Process_Status_Code not in ('S','K','U'))
509 And ( Queue_Application_ID = applid AND
510 Concurrent_Queue_ID = managerid );
511
512 pmon_method := 'RDBMS';
513 end if;
514
515 return;
516 end if;
517
518 --
519 -- Lock PMON method
520 --
521 ActiveP := 0;
522 TargetP := 0;
523
524 /* By convention we want FNDSM's to show exactly the same data as
525 the ICM so we have added the mtype = 6 condition to trigger the
526 icm status detection */
527
528 if (( applid = 0 AND managerid = 1 ) OR (mtype = 6)) then
529 TargetP := 1;
530 gothandle := get_handle(0, 0, 1, lkh);
531 if ( gothandle ) then
532 /*---------------------------------------------------------+
533 | Bug 2093806: Use FND_DCP.Check_Process_Status_By_Handle |
534 +---------------------------------------------------------*/
535 FND_DCP.check_process_status_by_handle(lkh, result, alive);
536 if (alive = 1) then
537 ActiveP := 1;
538 elsif ((alive = 0) and ( result <> 0 )) then
539 /*-------------------------------------------------------+
540 | Message set by FND_DCP.Check_Process_Status_By_Handle |
541 | available for retreival. |
542 +-------------------------------------------------------*/
543 callstat := result;
544 end if;
545 return;
546 else
547 callstat := 1;
548 return;
549 end if;
550 end if;
551
552 Select Max_Processes Into TargetP From Fnd_Concurrent_Queues
553 Where Concurrent_Queue_ID = ManagerID
554 And Application_ID = ApplID;
555
556
557 /* Bug 3443136: Since this API may be called from within a concurrent
558 program running in this session, select the current session id and
559 compare it with the session id of each manager process.
560 If they are they same, do not call check_process_status_by_handle,
561 as this will cause this session to lose its lock.
562 */
563 SELECT userenv('SESSIONID') INTO cur_session_id FROM dual;
564
565
566 For C1REC in C1 Loop
567
568 if C1REC.SESSION_ID = cur_session_id then
569 /* This session is obviously alive ... */
570 i := i + 1;
571 else
572 gothandle := get_handle(C1REC.CONCURRENT_PROCESS_ID,
573 applid, managerid, lkh);
574 if ( gothandle ) then
575 /*---------------------------------------------------------+
576 | Bug 2093806: Use FND_DCP.Check_Process_Status_By_Handle |
577 +---------------------------------------------------------*/
578 FND_DCP.check_process_status_by_handle(lkh, result, alive);
579 if (alive = 1) then
580 i := i + 1;
581 elsif ((alive = 0) and ( result <> 0 )) then
582 /*-------------------------------------------------------+
583 | Message set by FND_DCP.Check_Process_Status_By_Handle |
584 | available for retrieval. |
585 +-------------------------------------------------------*/
586 callstat := result;
587 end if;
588 else
589 callstat := 1;
590 return;
591 end if;
592 end if;
593 End Loop;
594
595 ActiveP := i;
596 return;
597
598 exception
599 when no_data_found then
600 ActiveP := i;
601 return;
602
603 when others then
604 TargetP := 0;
605 ActiveP := 0;
606 callstat := 1;
607 oraerrmesg := substr(SQLERRM, 1, 80);
608 Fnd_Message.Set_Name('FND', 'CP-Generic oracle error');
609 Fnd_Message.Set_Token('ERROR', oraerrmesg, FALSE);
610 Fnd_Message.Set_Token('ROUTINE',
611 'FND_CONCURRENT.GET_MANAGER_STATUS', FALSE);
612 return;
613 end get_manager_status;
614
615 -- Name
616 -- FND_CONCURRENT.SET_STATUS_AUTONUMOUS
617 -- Purpose
618 -- Updates given request status and completion text in an autonomous
619 -- transaction. This is function is called in set_completion_status
620 -- function. (Internal use only).
621 --
622 -- Arguments (input)
623 -- Request_ID- Request Id for which it needs update status.
624 -- Stutus - 'NORMAL','WARNING', or 'ERROR'
625 -- message - Optional message
626 --
627 -- Returns:
628 -- If there is any sql error then returns sql error other-wise null string
629
630 function DO_SET_STATUS_AUTONOMOUS(request_id IN number,
631 status IN varchar2,
632 message IN varchar2,
633 interim IN boolean default FALSE)
634 return varchar2 is
635 ret_str varchar2(80) := null;
636 l_request_id number;
637 l_status varchar2(10);
638 begin
639 if ( fnd_adg_support.is_standby )
640 then
641 $if fnd_adg_compile_directive.enable_rpc
642 $then
643
644 l_request_id := do_set_status_autonomous.request_id;
645 l_status := do_set_status_autonomous.status;
646
647 if ( interim ) then
648 if(upper(status) = 'W') then
649 update fnd_concurrent_requests_remote
650 set interim_status_code = 'W',
651 req_information = substrb(message,1,240)
652 where request_id = l_request_id;
653 else
654 update fnd_concurrent_requests_remote
655 set interim_status_code = l_status,
656 completion_text = substrb(message, 1, 240)
657 where request_id = l_request_id;
658 end if;
659
660 else
661 update fnd_concurrent_requests_remote
662 set phase_code = 'C',
663 status_code = l_status,
664 completion_text = substrb(message, 1, 240)
665 where request_id = l_request_id;
666
667 end if;
668
669 $else
670 null;
671 $end
672 else
673
674 if ( interim ) then
675 if(upper(status) = 'W') then
676 update fnd_concurrent_requests
677 set interim_status_code = 'W',
678 req_information = substrb(message,1,240)
679 where request_id = do_set_status_autonomous.request_id;
680 --debug('updated req_information for request_id '|| do_set_status_autonomous.request_id);
681 else
682 update fnd_concurrent_requests
683 set interim_status_code = do_set_status_autonomous.status,
684 completion_text = substrb(message, 1, 240)
685 where request_id = do_set_status_autonomous.request_id;
686 --debug('updated completion_text for request_id '|| do_set_status_autonomous.request_id);
687 end if;
688
689 else
690 update fnd_concurrent_requests
691 set phase_code = 'C',
692 status_code = do_set_status_autonomous.status,
693 completion_text = substrb(message, 1, 240)
694 where request_id = do_set_status_autonomous.request_id;
695
696 end if;
697
698 end if;
699
700 commit;
701
702 return ret_str;
703
704 exception
705 when others then
706 rollback;
707 ret_str := substrb(SQLERRM, 1, 80);
708 return ret_str;
709 end;
710
711 function DO_AUTO_SET_STATUS_AUTONOMOUS(request_id IN number,
712 status IN varchar2,
713 message IN varchar2,
714 interim IN boolean default FALSE)
715 return varchar2 is
716 PRAGMA AUTONOMOUS_TRANSACTION;
717 begin
718 return DO_SET_STATUS_AUTONOMOUS(request_id,status,message,interim);
719 end;
720
721 function SET_STATUS_AUTONOMOUS(request_id IN number,
722 status IN varchar2,
723 message IN varchar2,
724 interim IN boolean default FALSE)
725 return varchar2 is
726 begin
727
728 if ( fnd_adg_support.is_standby )
729 then
730 return DO_SET_STATUS_AUTONOMOUS(request_id,status,message,interim);
731 end if;
732
733 return DO_AUTO_SET_STATUS_AUTONOMOUS(request_id,status,message,interim);
734
735 end;
736
737
738
739
740 --
741 -- Name
742 -- FND_CONCURRENT.SET_COMPLETION_STATUS
743 -- Purpose
744 -- Called from a concurrent request to set its completion
745 -- status and message.
746 --
747 -- Arguments (input)
748 -- status - 'NORMAL', 'WARNING', or 'ERROR'
749 -- message - Optional message
750 --
751 -- Returns:
752 -- TRUE on success. FALSE on error.
753 --
754
755 function set_completion_status (status IN varchar2,
756 message IN varchar2) return boolean is
757 scode varchar2(1);
758 ret_str varchar2(80) := null;
759 req_id number;
760 begin
761 if (upper(status) = 'NORMAL') then
762 scode := 'C';
763 elsif (upper(status) = 'WARNING') then
764 scode := 'G';
765 elsif (upper(status) = 'ERROR') then
766 scode := 'E';
767
768 else
769 fnd_message.set_name('FND', 'CONC-SCS BAD STATUS');
770 fnd_message.set_token('STATUS', status);
771 return FALSE;
772 end if;
773
774 if ( lengthb(message) > 240 ) then
775 fnd_file.put_line( fnd_file.log, message);
776 end if;
777
778 req_id := fnd_global.conc_request_id;
779
780 ret_str := set_status_autonomous(req_id, scode, message);
781
782 -- if ret_str has some string that means some error otherwise return TRUE
783 if ( nvl(lengthb(ret_str), 0 ) > 0 ) then
784 Fnd_Message.Set_Name('FND', 'CP-Generic oracle error');
785 Fnd_Message.Set_Token('ERROR', ret_str, FALSE);
786 Fnd_Message.Set_Token('ROUTINE',
787 'FND_CONCURRENT.SET_COMPLETION_STATUS', FALSE);
788 return FALSE;
789 else
790 return TRUE;
791 end if;
792
793 end set_completion_status;
794
795 --
796 -- Name
797 -- Get_Request_Print_Options
798 -- Purpose
799 -- Returns the print options for a concurrent request in the
800 -- form of a PLSQL table type Print_Options_Tbl_Typ.
801 -- This function is required when multiple printers have been
802 -- specified for the request.
803 --
804 function GET_REQUEST_PRINT_OPTIONS
805 (request_id IN number,
806 number_of_copies OUT NOCOPY number,
807 print_style OUT NOCOPY varchar2,
808 printer OUT NOCOPY varchar2,
809 save_output_flag OUT NOCOPY varchar2) return boolean is
810 begin
811 select number_of_copies, print_style, printer, save_output_flag
812 into number_of_copies, print_style, printer, save_output_flag
813 from fnd_concurrent_requests r
814 where r.request_id = get_request_print_options.request_id;
815
816 return TRUE;
817
818 exception
819 when others then
820 oraerrmesg := substr(SQLERRM, 1, 80);
821 Fnd_Message.Set_Name('FND', 'CP-Generic oracle error');
822 Fnd_Message.Set_Token('ERROR', oraerrmesg, FALSE);
823 Fnd_Message.Set_Token('ROUTINE',
824 'FND_CONCURRENT.GET_REQUEST_PRINT_OPTIONS', FALSE);
825 return FALSE;
826 end get_request_print_options;
827
828 --
829 -- Name
830 -- Get_Request_Print_Options
831 -- Purpose
832 -- Returns the print options for a concurrent request.
833 -- Parameters
834 -- request_id: The request_id for the concurrent request
835 -- print_options: pl/sql table of print_options_tbl_typ
836 -- (see spec for type details)
837 -- Returns
838 -- The total number post-processing actions for printing
839 --
840 function GET_REQUEST_PRINT_OPTIONS
841 (request_id IN number,
842 print_options OUT NOCOPY print_options_tbl_typ)
843 return number is
844 counter number := 0;
845 cursor c1 is
846 select p.number_of_copies, r.print_style,
847 p.arguments, r.save_output_flag
848 from fnd_concurrent_requests r,
849 fnd_conc_pp_actions p
850 where r.request_id = p.concurrent_request_id
851 and p.action_type = 1
852 and p.concurrent_request_id = get_request_print_options.request_id
853 order by sequence;
854 begin
855 for c1_data in c1 loop
856 counter := counter + 1;
857 print_options(counter).number_of_copies := c1_data.number_of_copies;
858 print_options(counter).print_style := c1_data.print_style;
859 print_options(counter).printer := c1_data.arguments;
860 print_options(counter).save_output_flag := c1_data.save_output_flag;
861 end loop;
862 return counter;
863
864 exception
865 when others then
866 oraerrmesg := substr(SQLERRM, 1, 80);
867 Fnd_Message.Set_Name('FND', 'CP-Generic oracle error');
868 Fnd_Message.Set_Token('ERROR', oraerrmesg, FALSE);
869 Fnd_Message.Set_Token('ROUTINE',
870 'FND_CONCURRENT.GET_REQUEST_PRINT_OPTIONS', FALSE);
871 return counter;
872 end get_request_print_options;
873
874 --
875 -- Name
876 -- Check_Lock_Contention
877 -- Purpose
878 -- Identifies the process that is holding the lock(s) on resources
879 -- that are needed by the process identified by the Queue Name or
880 -- Session ID parameter.
881 --
882 function Check_Lock_Contention
883 (Queue_Name IN varchar2 default NULL,
884 Session_ID IN number default NULL,
885 UProcess_ID OUT NOCOPY number,
886 UTerminal OUT NOCOPY varchar2,
887 UNode OUT NOCOPY varchar2,
888 UName OUT NOCOPY varchar2,
889 UProgram OUT NOCOPY varchar2) return boolean is
890 C_SessionID number := Session_ID;
891 P_ProcessID number;
892 begin
893
894 UProcess_ID := NULL;
895 UTerminal := NULL;
896 UNode := NULL;
897 UName := NULL;
898 UProgram := NULL;
899
900 -- If session id is not null skip this step else
901 -- Get session id based on queue name.
902 --
903 if (C_SessionID is NULL ) then
904 Select Session_ID
905 into C_SessionID
906 from fnd_concurrent_processes cp,
907 fnd_concurrent_queues cq
908 where process_status_code = 'A'
909 and cp.Queue_Application_ID = cq.application_ID
910 and cp.concurrent_queue_id = cq.concurrent_queue_id
911 and cq.concurrent_queue_name = Queue_Name;
912
913 if (Sql%NotFound) then
914 Fnd_Message.Set_Name('FND', 'CP-Need valid manager name');
915 return FALSE;
916 end if;
917 end if;
918
919 -- Check for resource/locks that process with session id C_SessionID
920 -- is waiting for
921 --
922
923 select SH.OSUSER,
924 SH.PROCESS,
925 SH.MACHINE,
926 SH.TERMINAL,
927 SH.PROGRAM
928 into UName, UProcess_ID, UNode, UTerminal, UProgram
929 from V$SESSION SH,
930 V$LOCK LW,
931 V$LOCK LH,
932 V$SESSION SW
933 where LH.SID = SH.SID
934 and LH.SID <> SW.SID
935 and LH.ID1 = LW.ID1
936 and LH.ID2 = LW.ID2
937 and LW.KADDR = SW.LOCKWAIT
938 and SW.LOCKWAIT is not null
939 and SW.AUDSID = C_SessionID;
940
941 return TRUE;
942
943 exception
944 when no_data_found then
945 UProcess_ID := NULL;
946 UTerminal := NULL;
947 UNode := NULL;
948 UName := NULL;
949 UProgram := NULL;
950 return TRUE;
951
952 when others then
953 oraerrmesg := substr(SQLERRM, 1, 80);
954 Fnd_Message.Set_Name('FND', 'CP-Generic oracle error');
955 Fnd_Message.Set_Token('ERROR', oraerrmesg, FALSE);
956 Fnd_Message.Set_Token('ROUTINE',
957 'FND_CONCURRENT.Check_Lock_Contention', FALSE);
958 return FALSE;
959
960 end Check_Lock_Contention;
961
962 --
963 -- Name
964 -- get_program_attributes
965 -- Purpose
966 -- Returns the print options for a concurrent program.
967 --
968 -- Short term usage - only known users are from AP
969 function GET_PROGRAM_ATTRIBUTES
970 (appl_shortname IN varchar2 default NULL,
971 program IN varchar2 default NULL,
972 printer OUT NOCOPY varchar2,
973 style OUT NOCOPY varchar2,
974 save_output OUT NOCOPY varchar2) return boolean IS
975
976 ltype varchar2(8) := 'YES_NO';
977 begin
978 select PRINTER_NAME, user_printer_style_name, l.meaning
979 into printer, style, save_output
980 from fnd_concurrent_programs p, fnd_printer_styles_VL ps,
981 fnd_lookups L, fnd_application_vl A
982 where
983 l.lookup_code = p.SAVE_OUTPUT_FLAG
984 and l.lookup_type = ltype
985 and ps.printer_style_name = p.OUTPUT_PRINT_STYLE
986 and p.application_id = a.application_id
987 and p.concurrent_program_name = program
988 and a.application_short_name = appl_shortname;
989
990 if (Sql%NotFound) then
991 Fnd_Message.Set_Name('FND', 'CONC-Invalid Appl/Prog combo');
992 return FALSE;
993 end if;
994
995 return TRUE;
996
997 exception
998 when others then
999 oraerrmesg := substr(SQLERRM, 1, 80);
1000 Fnd_Message.Set_Name('FND', 'CP-Generic oracle error');
1001 Fnd_Message.Set_Token('ERROR', oraerrmesg, FALSE);
1002 Fnd_Message.Set_Token('ROUTINE',
1003 'FND_CONCURRENT.GET_PROGRAM_ATTRIBUTES', FALSE);
1004 return FALSE;
1005 end get_program_attributes;
1006
1007 --
1008 -- Name
1009 -- FND_CONCURRENT.SET_COMPLETION_STATUS
1010 -- Purpose
1011 -- Called from a concurrent request to set its completion
1012 -- status and message.
1013 --
1014 -- Arguments (input)
1015 -- status - 'NORMAL', 'WARNING', or 'ERROR'
1016 -- message - Optional message
1017 --
1018 -- Returns:
1019 -- TRUE on success. FALSE on error.
1020 --
1021
1022 PROCEDURE init_request is
1023 csid number; -- Auditing session ID
1024 cpid number; -- Oracle process identifier
1025 cspid varchar2(30); -- client process os pid
1026 csspid varchar2(30); -- Shadow process os pid
1027 codeset varchar2(30); -- NLS_CodeSet
1028 optmode varchar2(30); -- Optimizer mode
1029 que_rcg varchar2(32);
1030 prg_rcg varchar2(32);
1031 new_rcg varchar2(32);
1032 old_rcg varchar2(32);
1033 program_name varchar2(30);
1034 plog varchar2(56);
1035 pout varchar2(56);
1036 pdir varchar2(255);
1037 etstat varchar2(4) := Null;
1038 etrace varchar2(4) := Null;
1039 rtrace char;
1040 ptrace char;
1041 emethod varchar2(1);
1042 ret_val boolean;
1043 dbg_comp varchar2(30);
1044 morg_cat varchar2(1) := null;
1045 orgid number;
1046 l_request_id number;
1047 temp varchar2(100);
1048
1049 begin
1050
1051 if (fnd_global.conc_request_id > 0) then
1052
1053 if ( fnd_adg_support.is_standby )
1054 then
1055 $if fnd_adg_compile_directive.enable_rpc
1056 $then
1057
1058 Select P.PID, P.SPID, AUDSID, PROCESS,
1059 substr(userenv('LANGUAGE'),
1060 instr( userenv('LANGUAGE'), '.') + 1)
1061 Into cpid, csspid, csid, cspid, codeset
1062 From V$Session S, V$Process P,
1063 (select distinct sid from v$mystat ) m
1064 Where P.Addr = S.Paddr
1065 and s.sid = m.sid;
1066
1067 l_request_id := fnd_global.conc_request_id;
1068
1069 update fnd_concurrent_requests_remote
1070 set ORACLE_SESSION_ID = csid,
1071 ORACLE_PROCESS_ID = csspid,
1072 OS_PROCESS_ID = cspid,
1073 NLS_CodeSet = codeset
1074 where request_id = l_request_id;
1075
1076 $else
1077 null;
1078 $end
1079 else
1080 Select P.PID, P.SPID, AUDSID, PROCESS,
1081 substr(userenv('LANGUAGE'),
1082 instr( userenv('LANGUAGE'), '.') + 1)
1083 Into cpid, csspid, csid, cspid, codeset
1084 From V$Session S, V$Process P
1085 Where P.Addr = S.Paddr
1086 and S.AUDSID = userenv('SESSIONID');
1087
1088 update fnd_concurrent_requests
1089 set ORACLE_SESSION_ID = csid,
1090 ORACLE_PROCESS_ID = csspid,
1091 OS_PROCESS_ID = cspid,
1092 NLS_CodeSet = codeset
1093 where request_id = fnd_global.conc_request_id;
1094 end if;
1095
1096 -- DOING COMMIT HERE SO THAT GUI TOOLS GET THE SESSION INFO
1097 -- DURING PROGRAM EXECUTION.
1098
1099 commit;
1100
1101 begin
1102 select P.Optimizer_Mode, P.CONCURRENT_PROGRAM_NAME,
1103 upper(P.enable_Trace), upper(R.enable_trace),
1104 Decode(upper(P.ENABLE_TIME_STATISTICS),'Y','TRUE',NULL),
1105 execution_method_code,
1106 multi_org_category, org_id, p.application_id
1107 into optmode, program_name, ptrace, rtrace, etstat, emethod,
1108 morg_cat, orgid, temp
1109 from FND_CONCURRENT_PROGRAMS P,
1110 FND_CONCURRENT_REQUESTS R
1111 WHERE P.CONCURRENT_PROGRAM_ID = R.CONCURRENT_PROGRAM_ID
1112 And P.APPLICATION_ID = R.Program_APPLICATION_ID
1113 And R.request_id = fnd_global.conc_request_id;
1114 exception
1115 when others then
1116 optmode := null;
1117 program_name := null;
1118 end;
1119
1120 select lower(application_short_name) || '/' || upper(program_name) into temp
1121 from fnd_application where application_id = temp;
1122
1123 fnd_global.tag_db_session('cp', temp);
1124
1125 mo_global.init('M');
1126 -- initialize Multi-Org Context
1127 if ( morg_cat = 'S' ) then
1128 mo_global.set_policy_context(morg_cat, orgid);
1129 elsif ( morg_cat = 'M' ) then
1130 mo_global.set_policy_context(morg_cat, null);
1131 end if;
1132
1133 Select plsql_log, plsql_out, plsql_dir
1134 Into plog, pout, pdir
1135 From Fnd_Concurrent_Processes P, Fnd_Concurrent_Requests R
1136 Where P.Concurrent_Process_ID = R.Controlling_Manager
1137 And R.Request_ID = fnd_global.conc_request_id;
1138
1139 fnd_file.put_names(plog, pout, pdir);
1140 fnd_file_private.put_names(plog, pout, pdir);
1141
1142 if ( ptrace = 'Y' OR rtrace = 'Y') then
1143 etrace := 'TRUE';
1144 end if;
1145
1146 /* bug 3657332 */
1147 if ( optmode <> 'FIRST_ROWS' ) then
1148 optmode := NULL;
1149 end if;
1150
1151 FND_CTL.FND_SESS_CTL(Null, optmode, etrace, etstat, Null, Null);
1152
1153 dbms_application_info.set_module(program_name,
1154 'Concurrent Request');
1155 begin
1156 select Q.RESOURCE_CONSUMER_GROUP
1157 into que_rcg
1158 from fnd_concurrent_requests r,
1159 fnd_concurrent_processes p,
1160 fnd_concurrent_queues q
1161 where R.request_id = fnd_global.conc_request_id
1162 and R.controlling_manager = P.concurrent_process_id
1163 and Q.CONCURRENT_QUEUE_ID= P.CONCURRENT_QUEUE_ID
1164 and Q.APPLICATION_ID = P.QUEUE_APPLICATION_ID;
1165 exception
1166 when others then
1167 que_rcg := null;
1168 end;
1169
1170 begin
1171 select p.RESOURCE_CONSUMER_GROUP
1172 into prg_rcg
1173 from fnd_concurrent_programs P,
1174 fnd_concurrent_requests R
1175 where R.request_id = fnd_global.conc_request_id
1176 and r.PROGRAM_APPLICATION_ID = P.APPLICATION_ID
1177 and R.CONCURRENT_PROGRAM_ID = P.CONCURRENT_PROGRAM_ID;
1178 exception
1179 when others then
1180 prg_rcg := null;
1181 end;
1182
1183 if prg_rcg is not null then
1184 new_rcg := prg_rcg;
1185 elsif que_rcg is not null then
1186 new_rcg := que_rcg;
1187 else
1188 new_rcg := 'DEFAULT_CONSUMER_GROUP';
1189 end if;
1190
1191 begin
1192 dbms_session.switch_current_consumer_group(new_rcg,
1193 old_rcg,false);
1194 exception when others then null;
1195 end;
1196
1197 if ( not fnd_adg_support.is_standby )
1198 then
1199 begin
1200 dbg_comp := fnd_debug_rep_util.get_program_comp(emethod);
1201
1202 -- ignore return value from fnd_debug.
1203 ret_val := fnd_debug.enable_db_rules(comp_type => dbg_comp,
1204 comp_name => program_name,
1205 comp_appl_id => null,
1206 comp_id => null,
1207 req_id => fnd_global.conc_request_id);
1208 end;
1209 end if;
1210 end if;
1211
1212 return;
1213
1214 exception
1215 when others then
1216 oraerrmesg := substr(SQLERRM, 1, 80);
1217 Fnd_Message.Set_Name('FND', 'CP-Generic oracle error');
1218 Fnd_Message.Set_Token('ERROR', oraerrmesg, FALSE);
1219 Fnd_Message.Set_Token('ROUTINE',
1220 'FND_CONCURRENT.INIT_REQUEST', FALSE);
1221 fnd_adg_support.log_unhandled_exception('fnd_concurrent.init_request',SQLERRM);
1222 return;
1223
1224 end init_request;
1225
1226
1227 --
1228 -- Name
1229 -- FND_CONCURRENT.SET_PREFERRED_RBS
1230 -- Purpose
1231 -- Called from afpirq, etc to set the Rollback Segment associated with req.
1232 --
1233 -- Arguments (input)
1234 --
1235 -- Returns:
1236
1237 Procedure SET_PREFERRED_RBS is
1238
1239 RBS varchar2(101); -- Rollback segment.
1240 sql_stmt varchar2(101);
1241
1242 begin
1243 select P.Rollback_Segment
1244 into RBS
1245 from FND_CONCURRENT_PROGRAMS P,
1246 FND_CONCURRENT_REQUESTS R
1247 WHERE R.request_id = fnd_global.conc_request_id
1248 AND R.CONCURRENT_PROGRAM_ID = P.CONCURRENT_PROGRAM_ID
1249 And R.PROGRAM_APPLICATION_ID = P.APPLICATION_ID;
1250
1251 if RBS is not Null then
1252 sql_stmt := 'Set Transaction Use Rollback Segment '|| RBS;
1253 commit;
1254 execute immediate sql_stmt;
1255 end if;
1256
1257 return;
1258
1259 exception
1260 when others then
1261 return;
1262
1263 end SET_PREFERRED_RBS;
1264
1265 --
1266 -- Name
1267 -- Fnd_Concurrent.Reset_Context
1268 -- Purpose
1269 -- To reset/re-establish context that may have been lost due to commits
1270 --
1271 -- Arguments (input)
1272 --
1273 -- Returns:
1274
1275 function Reset_Context(Request_ID IN number default NULL) return boolean is
1276
1277 g_request_id number := NULL;
1278
1279 begin
1280 --
1281 -- Use request id from global context if one exists, else
1282 -- use the one provided by the caller (security hole?)
1283 --
1284 g_request_id := fnd_global.conc_request_id;
1285
1286 if (g_request_id is null) then
1287 g_request_id := Request_Id;
1288 end if;
1289
1290 Fnd_Concurrent.Set_Preferred_RBS;
1291
1292 return TRUE;
1293
1294 exception
1295 when others then
1296 return TRUE;
1297
1298 end Reset_Context;
1299
1300 -- Name
1301 -- FND_CONCURRENT.AF_COMMIT
1302 -- Purpose
1303 -- It does the commit and set the preferred rollback segment for the
1304 -- program. Call this routine only in the concurrent program context.
1305 --
1306 -- Arguments (input)
1307 --
1308 -- Returns:
1309
1310 Procedure AF_COMMIT is
1311 Begin
1312 -- do the commit first
1313 commit;
1314
1315 -- if the context is concurrent program then set the rollback segment to
1316 -- program preferred
1317 if (fnd_global.conc_request_id > 0) then
1318 fnd_concurrent.set_preferred_rbs;
1319 end if;
1320
1321 End AF_COMMIT;
1322
1323 -- Name
1324 -- FND_CONCURRENT.AF_ROLLBACK
1325 -- Purpose
1326 -- It does the rollback and set the preferred rollback segment for the
1327 -- program. Call this routine only in the concurrent program context.
1328 --
1329 -- Arguments (input)
1330 --
1331 -- Returns:
1332
1333 Procedure AF_ROLLBACK is
1334 Begin
1335 -- do the rollback first
1336 rollback;
1337
1338 -- if the context is concurrent program then set the rollback segment to
1339 -- program preferred
1340 if (fnd_global.conc_request_id > 0) then
1341 fnd_concurrent.set_preferred_rbs;
1342 end if;
1343
1344 End AF_ROLLBACK;
1345
1346 -- Name
1347 -- FND_CONCURRENT.SHUT_DOWN_PROCS
1348 -- Purpose
1349 -- Runs the pl/sql shutdown procedures stored in FND_EXECUTABLES
1350 -- with EXECUTION_METHOD_CODE = 'Z'.
1351 --
1352 -- Errors encountered during execution of stored procedures are
1353 -- logged to FND_EVENTS
1354
1355 procedure shut_down_procs is
1356 errbuf VARCHAR2(256);
1357
1358 CURSOR c IS
1359 SELECT execution_file_name from fnd_executables
1360 where execution_method_code = 'Z';
1361 begin
1362 FOR c_rec IN c LOOP
1363 begin
1364 savepoint startpoint;
1365 EXECUTE IMMEDIATE 'begin ' || c_rec.execution_file_name || '; end;';
1366 EXCEPTION
1367 -- if error arises we want to continue executing the rest of the
1368 -- shutdowns
1369 WHEN OTHERS THEN
1370 rollback to startpoint;
1371
1372 errbuf := SQLERRM;
1373 if ( FND_LOG.LEVEL_ERROR >= FND_LOG.G_CURRENT_RUNTIME_LEVEL ) then
1374 fnd_message.set_name('FND', 'CONC-SHUTDOWN_ACTION_FAILURE');
1375 fnd_message.set_token('PROCEDURE', c_rec.execution_file_name);
1376 fnd_message.set_token('REASON', errbuf);
1377 fnd_log.message(FND_LOG.LEVEL_ERROR, 'fnd.plsql.fnd_concurrent.shut_down_procs', FALSE);
1378 end if;
1379 end;
1380 END LOOP;
1381
1382 end shut_down_procs;
1383
1384 -- Name
1385 -- FND_CONCURRENT.SET_INTERIM_STATUS
1386 -- Purpose
1387 -- sets the requests phase_code, interim_status_code and completion_text
1388 -- this is used in Java Concurrent Programs.
1389 --
1390 -- Arguments (input)
1391 -- status - 'NORMAL', 'WARNING', or 'ERROR'
1392 -- message - Optional message
1393 --
1394 -- Returns:
1395 -- TRUE on success. FALSE on error.
1396 --
1397
1398 function set_interim_status (status IN varchar2,
1399 message IN varchar2) return boolean is
1400 scode varchar2(1);
1401 lmessage varchar2(2000);
1402 req_id number;
1403 ret_str varchar2(80) := null;
1404 begin
1405
1406 -- these status codes from the afcp.h.
1407
1408
1409 if (upper(status) = 'NORMAL') then
1410 scode := 'N';
1411 elsif (upper(status) = 'WARNING') then
1412 scode := 'G';
1413 elsif (upper(status) = 'ERROR') then
1414 scode := 'E';
1415 elsif (upper(status) = 'PAUSED') then
1416 scode := 'W';
1417 else
1418 fnd_message.set_name('FND', 'CONC-SCS BAD STATUS');
1419 fnd_message.set_token('STATUS', status);
1420 return FALSE;
1421 end if;
1422
1423
1424 if ( (lengthb(message) = 0) and scode in ('G','E')) then
1425 fnd_message.set_name('FND', 'CONC-REQ RETURNED NO MESG');
1426 lmessage := fnd_message.get;
1427 elsif( (lengthb(message) = 0) and scode in ('W')) then
1428 fnd_message.set_name('FND', 'CONC_REQ REQUEST INFO');
1429 lmessage := message;
1430 else
1431 lmessage := message;
1432 end if;
1433
1434 if ( lengthb(lmessage) > 240 ) then
1435 fnd_file.put_line( fnd_file.log, lmessage);
1436 end if;
1437
1438 req_id := fnd_global.conc_request_id;
1439
1440 ret_str := set_status_autonomous(req_id, scode, lmessage, TRUE);
1441
1442 -- if ret_str has some string that means some error otherwise return TRUE
1443 if ( nvl(lengthb(ret_str), 0 ) > 0 ) then
1444 Fnd_Message.Set_Name('FND', 'CP-Generic oracle error');
1445 Fnd_Message.Set_Token('ERROR', ret_str, FALSE);
1446 Fnd_Message.Set_Token('ROUTINE',
1447 'FND_CONCURRENT.SET_INTERIM_STATUS', FALSE);
1448 return FALSE;
1449 else
1450 return TRUE;
1451 end if;
1452
1453 end set_interim_status;
1454
1455 -- Name
1456 -- FND_CONCURRENT.GET_SUB_REQUESTS
1457 -- Purpose
1458 -- gets all sub-requests for a given request id. For each sub-request it
1459 -- provides request_id, phase,status, developer phase , developer status
1460 -- completion text.
1461 --
1462 -- Arguments (input)
1463 -- request_id - Request Id for which sub-requests are required.
1464 --
1465 -- Returns:
1466 -- Table FND_CONCURRENT.REQUESTS_TAB_TYPE.
1467 --
1468
1469 function get_sub_requests( p_request_id IN number)
1470 return requests_tab_type is
1471 CURSOR C1 is
1472 Select Request_Id, Completion_Text,
1473 Phase.Lookup_Code p_lookup_code,
1474 Status.Lookup_Code s_lookup_code,
1475 Phase.Meaning p_meaning, Status.Meaning s_meaning
1476 From Fnd_Concurrent_Requests R,
1477 Fnd_Concurrent_programs P,
1478 Fnd_Lookups Phase,
1479 Fnd_Lookups Status
1480 Where
1481 Phase.Lookup_Type = PHASE_LOOKUP_TYPE
1482 AND Phase.Lookup_Code = Decode(Status.Lookup_Code,
1483 'H', 'I',
1484 'S', 'I',
1485 'U', 'I',
1486 'M', 'I',
1487 R.Phase_Code) AND
1488 Status.Lookup_Type = STATUS_LOOKUP_TYPE AND
1489 Status.Lookup_Code =
1490 Decode(R.Phase_Code,
1491 'P', Decode(R.Hold_Flag, 'Y', 'H',
1492 Decode(P.Enabled_Flag, 'N', 'U',
1493 Decode(Sign(R.Requested_Start_Date - SYSDATE),1,'P',
1494 R.Status_Code))),
1495 'R', Decode(R.Hold_Flag, 'Y', 'S',
1496 Decode(R.Status_Code, 'Q', 'B',
1497 'I', 'B',
1498 R.Status_Code)),
1499 R.Status_Code)
1500 And (R.Concurrent_Program_Id = P.Concurrent_program_ID AND
1501 R.Program_Application_ID= P.Application_ID )
1502 And Parent_Request_Id = p_request_id;
1503 sub_reqs requests_tab_type;
1504 i number := 0;
1505 phase_code varchar2(30);
1506 status_code varchar2(30);
1507 Dev_Phase varchar2(30);
1508 Dev_Status varchar2(30);
1509 begin
1510 FOR c1_rec in C1 LOOP
1511 i := i + 1;
1512 sub_reqs(i).request_id := c1_rec.request_id;
1513 sub_reqs(i).phase := c1_rec.p_meaning;
1514 sub_reqs(i).status := c1_rec.s_meaning;
1515 sub_reqs(i).message := c1_rec.completion_text;
1516 phase_code := c1_rec.p_lookup_code;
1517 status_code := c1_rec.s_lookup_code;
1518
1519 get_dev_phase_status(phase_code, status_code, dev_phase, dev_status);
1520
1521 sub_reqs(i).dev_phase := Dev_Phase;
1522 sub_reqs(i).dev_status := Dev_Status;
1523 END LOOP;
1524
1525 return sub_reqs;
1526 end get_sub_requests;
1527
1528 -- Name
1529 -- FND_CONCURRENT.CHILDREN_DONE
1530 -- Purpose
1531 -- Examines all child requests of a given request id. Returns TRUE if
1532 -- all have completed. Does not consider grandchildren or parent
1533 --
1534 -- Arguments (input)
1535 -- Parent_Request_ID- Request Id for which sub-requests are required. Null
1536 -- will be interpreted as current req_id.
1537 -- Recursive_Flag - Shall we look for grandchildren, etc.?
1538 --
1539 -- Interval - If Timeout>0, then we sleep this many seconds
1540 -- between queries (default 60)
1541 -- Max_Wait - if > 0 and children not done, we will wait up to Max_Wait
1542 -- seconds before responding FALSE
1543
1544 function CHILDREN_DONE(Parent_Request_ID IN NUMBER default NULL,
1545 Recursive_Flag in varchar2 default 'N',
1546 Interval IN number default 60,
1547 Max_Wait IN number default 0) return boolean is
1548
1549 kount number;
1550 end_of_time date;
1551 time_left number;
1552 parent_req_id number;
1553 cursor kidslist(parent_id number) is
1554 Select request_id
1555 from fnd_concurrent_requests
1556 where parent_request_id = parent_id;
1557
1558 begin
1559 Select sysdate + (greatest(Max_Wait, 0)/86400)
1560 into end_of_time
1561 from dual;
1562
1563 Select NVL(Parent_Request_ID,FND_GLOBAL.CONC_REQUEST_ID)
1564 into parent_req_id
1565 from dual;
1566
1567 if (parent_req_id = -1) then return TRUE; end if;
1568
1569 LOOP
1570 Select count(*) into kount
1571 from fnd_concurrent_requests
1572 where parent_request_id = parent_req_id
1573 and phase_code <> 'C';
1574
1575 if (kount = 0) AND (Recursive_Flag = 'Y') then -- check for kids
1576 for kidreq in kidslist(parent_req_id) loop
1577 if (NOT CHILDREN_DONE(kidreq.request_id, 'Y', 0, 0) ) then
1578 kount := 1;
1579 exit;
1580 end if;
1581 end loop;
1582 end if;
1583
1584 /* if we haven't found one then exit */
1585 if (kount = 0) then return TRUE; end if;
1586
1587 /* otherwise return false if we have run out of time */
1588 select (end_of_time - sysdate) * 86400
1589 into time_left
1590 from dual;
1591
1592 if (time_left <= Interval) then return FALSE; end if;
1593
1594 /* If we still have time, take a nap before trying again */
1595 dbms_lock.sleep(Interval);
1596 end LOOP;
1597
1598 end CHILDREN_DONE;
1599
1600 procedure register_node( name varchar2, /* Max 30 bytes */
1601 platform_id number, /* Platform ID from BugDB */
1602 forms_tier varchar2, /* 'Y'/'N' */
1603 cp_tier varchar2, /* 'Y'/'N' */
1604 web_tier varchar2, /* 'Y'/'N' */
1605 admin_tier varchar2, /* 'Y'/'N' */
1606 p_server_id varchar2, /* ID of server */
1607 p_address varchar2, /* IP address of server */
1608 p_description varchar2,
1609 p_host_name varchar2 default null,
1610 p_domain varchar2 default null, /* description of server*/
1611 db_tier varchar2 default null, /* 'Y'/'N' */
1612 p_virtual_ip varchar2 default null /* Virtual IP */ )
1613
1614 is
1615
1616 kount number;
1617
1618 begin
1619 /*
1620 * Create node. If it already exists,then we'll Update instead
1621 */
1622 select count(*)
1623 into kount
1624 from fnd_nodes
1625 where upper(node_name) = upper(name);
1626
1627 if (kount = 0) then
1628 insert into fnd_nodes
1629 (node_id, node_name,
1630 support_forms, support_cp, support_web, support_admin,
1631 platform_code, created_by, creation_date,
1632 last_updated_by, last_update_date, last_update_login,
1633 node_mode, server_id, server_address, description,
1634 host, domain,support_db, virtual_ip)
1635 select
1636 fnd_nodes_s.nextval, name,
1637 forms_tier, cp_tier, web_tier, admin_tier,
1638 platform_id, 1, SYSDATE,
1639 1, SYSDATE, 0,
1640 'O', p_server_id, p_address, p_description,
1641 p_host_name, p_domain,db_tier, p_virtual_ip
1642 from dual;
1643 else
1644 /*
1645 * Node exists already.
1646 * Allow for the case where multiple APPL_TOPs
1647 * are installed on the same node for the same
1648 * Apps system, but for different tiers. Essentially,
1649 * we're performing an 'OR' of the flags in the table
1650 * and those passed into the procedure.
1651 */
1652 update fnd_nodes set
1653 description = p_description,
1654 support_forms = decode(forms_tier, 'Y', 'Y', support_forms),
1655 support_cp = decode(cp_tier, 'Y', 'Y', support_cp),
1656 support_web = decode(web_tier, 'Y', 'Y', support_web),
1657 support_admin = decode(admin_tier, 'Y', 'Y', support_admin),
1658 platform_code = platform_id,
1659 last_update_date = SYSDATE, last_updated_by = 1,
1660 host = p_host_name,
1661 domain = p_domain,
1662 support_db = decode(db_tier,'Y','Y',support_db)
1663 where upper(node_name) = upper(name);
1664
1665 -- If server_id is not null, update fnd_nodes.server_id.
1666 -- fnd_nodes.server_id can only be null if the application server node has been
1667 -- removed.
1668 if (p_server_id is not null) then
1669 update fnd_nodes
1670 set server_id = p_server_id
1671 where upper(node_name) = upper(name);
1672 end if;
1673
1674 -- If server_address is not null, update fnd_nodes.server_address.
1675 if (p_address is not null) then
1676 update fnd_nodes
1677 set server_address = p_address
1678 where upper(node_name) = upper(name);
1679 end if;
1680
1681 -- if p_virtual_ip is not null update the fnd_node.virtual_ip
1682 if (p_virtual_ip is not null) then
1683 update fnd_nodes
1684 set virtual_ip = p_virtual_ip
1685 where upper(node_name) = upper(name);
1686 end if;
1687 end if;
1688 end register_node;
1689
1690 -- Name
1691 -- Fnd_Concurrent.Get_Service_Instances
1692 -- Purpose
1693 -- Fetch all service instances defined for a Service type
1694 -- Returns the service instance identity along with it's current
1695 -- state (Active/Disabled/Inactive/Suspended/Transit )
1696 --
1697 -- Arguments (input)
1698 -- svc_handle - Developer name for the Service type
1699 --
1700 -- Returns:
1701 -- Table Fnd_Concurrent.Service_Instance_Tab_Type. A table size of 0
1702 -- indicates absence of any service instances for the specified service
1703 -- type
1704 --
1705
1706 function Get_Service_Instances(svc_handle IN VARCHAR2)
1707 return Service_Instance_Tab_Type is
1708
1709 svc_id number;
1710 CURSOR C1 is
1711 select APPLICATION_SHORT_NAME c_appl_short_name,
1712 CONCURRENT_QUEUE_NAME c_svc_name,
1713 RUNNING_PROCESSES c_run_procs,
1714 MAX_PROCESSES c_max_procs,
1715 CONTROL_CODE c_ctrl_code,
1716 ENABLED_FLAG c_enabled
1717 from FND_CONCURRENT_QUEUES fcq,
1718 FND_CP_SERVICES fcs,
1719 FND_APPLICATION fa
1720 where
1721 fcq.MANAGER_TYPE = to_char(fcs.SERVICE_id)
1722 and fcq.application_id = fa.application_id
1723 and fcs.SERVICE_ID = svc_id;
1724 svc_inst_inf Service_Instance_Tab_Type;
1725 i number := 0;
1726 user_error varchar2(255); -- to store translated file_error
1727
1728 begin
1729
1730 -- Validate service type
1731
1732 begin
1733 select SERVICE_ID
1734 into svc_id
1735 from FND_CP_SERVICES
1736 where SERVICE_HANDLE = upper(svc_handle);
1737 exception
1738 when no_data_found then
1739 fnd_message.set_name('FND', 'CONC-SM INVALID SVC HANDLE');
1740 fnd_message.set_token('HANDLE', svc_handle);
1741 user_error := substrb(fnd_message.get, 1, 255);
1742 raise_application_error(-20100, user_error);
1743 end;
1744
1745
1746 FOR c1_rec in C1 LOOP
1747 i := i + 1;
1748 svc_inst_inf(i).Service_Handle := upper(svc_handle);
1749 svc_inst_inf(i).Application := c1_rec.c_appl_short_name;
1750 svc_inst_inf(i).Instance_Name := c1_rec.c_svc_name;
1751
1752 svc_inst_inf(i).State := get_svc_state(c1_rec.c_enabled,
1753 c1_rec.c_ctrl_code,
1754 c1_rec.c_run_procs,
1755 c1_rec.c_max_procs);
1756 END LOOP;
1757
1758 return svc_inst_inf;
1759 end Get_Service_Instances;
1760
1761 -- Name
1762 -- Fnd_Concurrent.Get_Service_Processes
1763 -- Purpose
1764 -- Fetch all service instance processes for a service instance
1765 --
1766 -- Arguments (input)
1767 -- appl_short_name - Application Short Name under which the service
1768 -- - instance is registered
1769 -- svc_instance_name - Developer name for the service instance
1770 -- proc_state - Service process state
1771 --
1772 -- Application and Service Instance Name together can be used to locate
1773 -- all processes
1774 --
1775 -- Returns (Fnd_Concurrent.Service_Process_Tab_Type)
1776 -- Fnd_Concurrent.Service_Process_Tab_Type.
1777 -- CPID (Concurrent_Process_ID) - Can be used to address/act on the
1778 -- process
1779 -- Service_Parameters - To be used to target particular
1780 -- - service instances
1781 -- A table size of 0 indicates absence of any service processes
1782 -- for the specified service instance and state
1783 --
1784
1785 function Get_Service_Processes(appl_short_name IN varchar2,
1786 svc_instance_name IN varchar2,
1787 proc_state IN varchar2)
1788 return Service_Process_Tab_Type is
1789
1790 ltype varchar2(32) := 'CP_PROCESS_STATUS_CODE';
1791
1792 CURSOR C1 is
1793 select CONCURRENT_PROCESS_ID c_cpid,
1794 MEANING c_state,
1795 fcp.NODE_NAME c_node,
1796 fcp.SERVICE_PARAMETERS c_parameters
1797 from FND_CONCURRENT_QUEUES fcq,
1798 FND_CONCURRENT_PROCESSES fcp,
1799 FND_APPLICATION fa,
1800 FND_LOOKUP_VALUES_VL flv
1801 where
1802 fcp.QUEUE_APPLICATION_ID = fcq.APPLICATION_ID
1803 and fcp.CONCURRENT_QUEUE_ID = fcq.CONCURRENT_QUEUE_ID
1804 and fcq.APPLICATION_ID = fa.APPLICATION_ID
1805 and flv.LOOKUP_TYPE = ltype
1806 and flv.LOOKUP_CODE = fcp.PROCESS_STATUS_CODE
1807 and fa.APPLICATION_SHORT_NAME = upper(appl_short_name)
1808 and fcq.CONCURRENT_QUEUE_NAME = upper(svc_instance_name)
1809 and ((proc_state is not null)
1810 or (fcp.PROCESS_STATUS_CODE not in ('S', 'K', 'U')))
1811 and exists
1812 (select 1
1813 from fnd_lookup_values flv2
1814 where flv2.LOOKUP_TYPE = ltype
1815 and flv2.LOOKUP_CODE = fcp.PROCESS_STATUS_CODE
1816 and upper(flv2.meaning) =
1817 upper(nvl(proc_state,flv2.meaning)));
1818
1819 svc_proc_inf Service_Process_Tab_Type;
1820 i number := 0;
1821 user_error varchar2(255); -- to store translated file_error
1822
1823 begin
1824
1825 -- Validate service application and name
1826 begin
1827 select 0
1828 into i
1829 from FND_CONCURRENT_QUEUES fcq,
1830 FND_APPLICATION fa
1831 where fcq.APPLICATION_ID = fa.APPLICATION_ID
1832 and APPLICATION_SHORT_NAME = upper(appl_short_name)
1833 and upper(CONCURRENT_QUEUE_NAME) = upper(svc_instance_name);
1834 exception
1835 when no_data_found then
1836 fnd_message.set_name('FND', 'CONC-SM INVALID SVC INSTANCE');
1837 fnd_message.set_token('APPLICATION', appl_short_name);
1838 fnd_message.set_token('INSTANCE', svc_instance_name);
1839 user_error := substrb(fnd_message.get, 1, 255);
1840 raise_application_error(-20100, user_error);
1841 end;
1842
1843 FOR c1_rec in C1 LOOP
1844
1845 i := i + 1;
1846 svc_proc_inf(i).CPID := c1_rec.c_cpid;
1847 svc_proc_inf(i).State := c1_rec.c_state;
1848 svc_proc_inf(i).Node := c1_rec.c_node;
1849 svc_proc_inf(i).Parameters := c1_rec.c_parameters;
1850
1851 END LOOP;
1852
1853 return svc_proc_inf;
1854 end Get_Service_Processes;
1855
1856 -- Name
1857 -- FND_CONCURRENT.MSC_MATCH_BY_SERVICE_TYPE
1858 -- Purpose
1859 -- internal function used to find matches of svc cntl requests and
1860 -- Service types. returns 1 for a match, 0 for no.
1861
1862 function MSC_MATCH_BY_SERVICE_TYPE(requestid number, mtype number)
1863 return number is
1864
1865 rarg1 number;
1866 rarg2 number;
1867 rarg3 number;
1868 kount number;
1869
1870 begin
1871 /* get request arguments. Last sane thing we do before the arbitrary
1872 ugly piece of coding where we decipher if we have a hit */
1873
1874 select argument1, argument2, argument3
1875 into rarg1, rarg2, rarg3
1876 from fnd_concurrent_requests R
1877 where requestid = R.request_id;
1878
1879 /* CASE positive : old style requests */
1880 if (rarg1 >= 0) then
1881
1882 select count(concurrent_queue_id)
1883 into kount
1884 from fnd_concurrent_queues
1885 where concurrent_queue_id = rarg1
1886 and application_id = rarg2
1887 and manager_type = mtype;
1888
1889 if ((kount > 0) or (rarg1 = 1)) then return 1;
1890 else return 0;
1891 end if;
1892
1893
1894 /* CASE -1 : By app id */
1895 elsif ((rarg1 = -1) and (
1896 /* either CM or TM and request is for mgrs (or both) */
1897 (((mtype = 1) or (mtype = 3)) and ((rarg3 = 0) or (rarg3 = 2)))
1898 or /* or service and request is for services (or both) */
1899 ((mtype > 999) and ((rarg3 = 1) or (rarg3 = 2)))
1900 )) then
1901
1902
1903 select count(concurrent_queue_id)
1904 into kount
1905 from fnd_concurrent_queues
1906 where application_id = rarg2
1907 and manager_type = mtype;
1908
1909 if (kount > 0) then return 1;
1910 else return 0;
1911 end if;
1912
1913
1914
1915 elsif (rarg1 = -1) then
1916 return 0;
1917
1918 /* CASE -2 : cp fun pak */
1919 elsif ((rarg1 = -2) and (mtype > 0) and (mtype < 6) and (mtype <> 2)) then
1920 return 1;
1921 elsif (rarg1 = -2) then
1922 return 0;
1923
1924 /* CASE -3 : By service type */
1925 elsif ((rarg1 = -3) and ((mtype = rarg2) or (rarg2 = 0))) then
1926 return 1;
1927 elsif (rarg1 = -3) then
1928 return 0;
1929
1930 /* CASE -4 : cp all */
1931 elsif ((rarg1 = -4) and (mtype < 1000)) then
1932 return 1;
1933 elsif (rarg1 = -4) then
1934 return 0;
1935
1936 else -- for expansion...we'll assume no match.
1937 return 0;
1938 end if;
1939
1940 end MSC_MATCH_BY_SERVICE_TYPE;
1941
1942 -- Name
1943 -- FND_CONCURRENT.MSC_MATCH
1944 -- Purpose
1945 -- internal function used to find matches of svc cntl requests and services
1946 -- or managers. returns 1 for a match, 0 for no.
1947
1948 function MSC_MATCH(requestid number,
1949 app_id number, que_id number, mtype number) return number is
1950
1951 rarg1 number;
1952 rarg2 number;
1953 rarg3 number;
1954
1955 begin
1956 if (que_id is null) then
1957 /* Deal with special case required for OAM */
1958 return MSC_MATCH_BY_SERVICE_TYPE(requestid, mtype);
1959 end if;
1960
1961 /* get request arguments. Last sane thing we do before the arbitrary
1962 ugly piece of coding where we decipher if we have a hit */
1963
1964 select argument1, argument2, argument3
1965 into rarg1, rarg2, rarg3
1966 from fnd_concurrent_requests R
1967 where requestid = R.request_id;
1968
1969 /* CASE positive : old style requests */
1970 if ((rarg1 >= 0) and (rarg1 = que_id) and (rarg2 = app_id)) then
1971 return 1;
1972 elsif ((rarg1 >= 0) and (rarg1 = 1) and (rarg2 = 0)) then
1973 return 1;
1974 elsif (rarg1 >= 0) then
1975 return 0;
1976
1977 /* CASE -1 : By app id */
1978 elsif ((rarg1 = -1) and (rarg2 = app_id) and (
1979 /* either CM or TM and request is for mgrs (or both) */
1980 (((mtype = 1) or (mtype = 3)) and ((rarg3 = 0) or (rarg3 = 2)))
1981 or /* or service and request is for services (or both) */
1982 ((mtype > 999) and ((rarg3 = 1) or (rarg3 = 2)))
1983 )) then return 1;
1984 elsif (rarg1 = -1) then
1985 return 0;
1986
1987 /* CASE -2 : cp fun pak */
1988 elsif ((rarg1 = -2) and (mtype > 0) and (mtype < 6) and (mtype <> 2)) then
1989 return 1;
1990 elsif (rarg1 = -2) then
1991 return 0;
1992
1993 /* CASE -3 : By service type */
1994 elsif ((rarg1 = -3) and (mtype = rarg2)) then
1995 return 1;
1996 elsif (rarg1 = -3) then
1997 return 0;
1998
1999 /* CASE -4 : cp all */
2000 elsif ((rarg1 = -4) and (mtype < 1000) ) then
2001 return 1;
2002 elsif (rarg1 = -4) then
2003 return 0;
2004
2005 else -- for expansion...we'll assume no match.
2006 return 0;
2007 end if;
2008
2009 end MSC_MATCH;
2010 -- Name
2011 -- FND_CONCURRENT.find_pending_svc_ctrl_reqs
2012 -- Purpose
2013 -- gets all pending service control requests for a given service or service
2014 -- instance. Returns number of requests found and has an out parameter
2015 -- containing a comma delimited list of matching requests.
2016 --
2017 -- Arguments (input)
2018 -- service_id - Service ID of service in which we are interested.
2019 -- (Set to null if this doesn't matter)
2020 -- service_inst_id - Service instance ID of svc in which we are interested.
2021 -- (Set to null if this doesn't matter)
2022 -- request_list - Comma delimited list of matching request ids.
2023 --
2024 -- Returns:
2025 -- Number of matching requests.
2026 --
2027
2028
2029 function find_pending_svc_ctrl_reqs(service_id in number,
2030 service_inst_id in number,
2031 req_list out NOCOPY varchar2) return number is
2032
2033 app_id number := null;
2034 kount number := 0;
2035 my_service_id number := service_id;
2036
2037 Cursor C1 IS
2038 Select request_id
2039 from fnd_concurrent_requests R, fnd_concurrent_programs P
2040 where r.phase_code = 'P'
2041 and p.application_id = r.PROGRAM_APPLICATION_ID
2042 and p.concurrent_program_id = r.concurrent_program_id
2043 and p.queue_control_flag = 'Y'
2044 and msc_match(request_id, app_id, service_inst_id, my_service_id) = 1
2045 order by request_id;
2046
2047 begin
2048 req_list := '';
2049
2050 If ((service_id is null) and (service_inst_id is null)) then
2051 /* all null case */
2052 return 0;
2053 elsif (service_id is null) then
2054 /* populate app and service id */
2055 select manager_type, application_id
2056 into my_service_id, app_id
2057 from fnd_concurrent_queues
2058 where concurrent_queue_id = service_inst_id;
2059 end if;
2060
2061 /* find results */
2062 For C1REC in C1 Loop
2063 kount := kount + 1;
2064
2065 if (kount = 0) then
2066 req_list := to_char(C1REC.request_id);
2067 else
2068 req_list := req_list || ',' || to_char(C1REC.request_id);
2069 end if;
2070 End Loop;
2071
2072 return kount;
2073 end find_pending_svc_ctrl_reqs;
2074
2075
2076 -- Name
2077 -- FND_CONCURRENT.Find_SC_Conflict
2078 -- Purpose
2079 -- Finds later conflicting service control request (if any) for another
2080 -- service control request.
2081 --
2082 -- Arguments (input)
2083 -- reqid - request id we are interested in.
2084 --
2085 -- Returns:
2086 -- Request ID of a conflicting request, or -1 if none exist.
2087
2088 Function Find_SC_Conflict(reqid in number) return number is
2089 app_id number := null;
2090 kount number := 0;
2091
2092 Cursor C1 IS
2093 Select R2.request_id
2094 from fnd_concurrent_requests R1,
2095 fnd_concurrent_requests R2,
2096 fnd_concurrent_programs P1,
2097 fnd_concurrent_programs P2,
2098 fnd_concurrent_queues Q,
2099 fnd_application A
2100 where r1.request_id = reqid
2101 and P1.APPLICATION_ID = R1.PROGRAM_APPLICATION_ID
2102 and P1.concurrent_program_id = R1.concurrent_program_id
2103 and p1.queue_control_flag = 'Y'
2104 and r2.request_id > r1.request_id
2105 and P2.APPLICATION_ID = R2.PROGRAM_APPLICATION_ID
2106 and P2.concurrent_program_id = R2.concurrent_program_id
2107 and P2.concurrent_program_id <> 2
2108 and P2.concurrent_program_id <> 6
2109 and p2.queue_control_flag = 'Y'
2110 AND a.application_id = p2.application_id
2111 AND a.application_short_name = 'FND'
2112 and msc_match(reqid,
2113 Q.application_id, Q.concurrent_queue_id, Q.manager_type) +
2114 msc_match(R2.request_id,
2115 Q.application_id, Q.concurrent_queue_id, Q.manager_type) = 2
2116 order by R2.request_id;
2117
2118 begin
2119 For C1REC in C1 Loop
2120 return C1REC.request_id;
2121 End Loop;
2122
2123 return -1;
2124 end Find_SC_Conflict;
2125
2126 -- Private Function
2127 Function private_check_for_sctl_done(goal_state varchar2,
2128 rarg1 number, rarg2 number, rarg3 number) return number is
2129
2130 kount number;
2131
2132 begin
2133 /* CASE positive : old style requests */
2134 if (rarg1 >= 0) then
2135 select count(concurrent_queue_id)
2136 into kount
2137 from fnd_concurrent_queues
2138 where concurrent_queue_id = rarg1
2139 and application_id = rarg2
2140 and ((Running_processes <> MAX_PROCESSES)
2141 or ((goal_state is not null) and
2142 ((CONTROL_CODE <> goal_state) or (CONTROL_CODE is null)))
2143 or ((goal_state is null) and (CONTROL_CODE is null)));
2144
2145
2146 /* CASE -1 : By app id */
2147 elsif (rarg1 = -1) then
2148 select count(concurrent_queue_id)
2149 into kount
2150 from fnd_concurrent_queues
2151 where application_id = rarg2
2152 and (
2153 /* either CM or TM and request is for mgrs (or both) */
2154 (((manager_type = 1) or (manager_type = 3))
2155 and ((rarg3 = 0) or (rarg3 = 2)))
2156 or /* or service and request is for services (or both) */
2157 ((manager_type > 999) and ((rarg3 = 1) or (rarg3 = 2))))
2158 and ((Running_processes <> MAX_PROCESSES)
2159 or ((goal_state is not null) and
2160 ((CONTROL_CODE <> goal_state) or (CONTROL_CODE is null)))
2161 or ((goal_state is null) and (CONTROL_CODE is null)));
2162
2163 /* CASE -2 : cp fun pak */
2164 elsif (rarg1 = -2) then
2165 select count(concurrent_queue_id)
2166 into kount
2167 from fnd_concurrent_queues
2168 where manager_type IN ('1', '3', '4', '5')
2169 and ((Running_processes <> MAX_PROCESSES)
2170 or ((goal_state is not null) and
2171 ((CONTROL_CODE <> goal_state) or (CONTROL_CODE is null)))
2172 or ((goal_state is null) and (CONTROL_CODE is null)));
2173
2174
2175 /* CASE -3 : By service type */
2176 elsif (rarg1 = -3) then
2177 select count(concurrent_queue_id)
2178 into kount
2179 from fnd_concurrent_queues
2180 where manager_type = to_char(rarg2)
2181 and ((Running_processes <> MAX_PROCESSES)
2182 or ((goal_state is not null) and
2183 ((CONTROL_CODE <> goal_state) or (CONTROL_CODE is null)))
2184 or ((goal_state is null) and (CONTROL_CODE is null)));
2185
2186 /* CASE -4 : cp all */
2187 elsif (rarg1 = -4) then
2188 select count(concurrent_queue_id)
2189 into kount
2190 from fnd_concurrent_queues
2191 where manager_type < 1000
2192 and ((Running_processes <> MAX_PROCESSES)
2193 or ((goal_state is not null) and
2194 ((CONTROL_CODE <> goal_state) or (CONTROL_CODE is null)))
2195 or ((goal_state is null) and (CONTROL_CODE is null)));
2196
2197 else -- for expansion...we'll assume not complete.
2198 kount := 1;
2199 end if;
2200
2201 if (kount > 0) then return 0;
2202 else return 1; end if;
2203
2204 end private_check_for_sctl_done;
2205
2206
2207
2208 -- Name
2209 -- FND_CONCURRENT.Function Wait_for_SCTL_Done
2210 -- Purpose
2211 -- Waits for Svc Ctrl request to finish, or another conflicting request,
2212 -- or timeout.
2213 --
2214 -- Arguments (input)
2215 -- reqid - request id we are interested in.
2216 --
2217 -- timeout - timeout in seconds;
2218 --
2219 -- Returns:
2220 -- Number -
2221 -- - 1: request not found.
2222 -- - 2: request is not a supported type.
2223 -- - 3: request has not run before timeout.
2224 -- - 4: later request conflicts with this request.
2225 -- - 5: request has run, but not complete before timeout.
2226 -- - 6: requested actions have completed.
2227 --
2228 -- Supporting routines:
2229 -- For readability the following functions are available to compare to
2230 -- result:
2231
2232 Function Wait_for_SCTL_Done(reqid in number,timeout in number)return number is
2233 mystart date;
2234 done number := -1; -- -1 = unrun, 0 = run, 2 = finished
2235 timesup number;
2236 r_app_id number;
2237 prog_id number;
2238 r_phase varchar2(1);
2239 rarg1 number;
2240 rarg2 number;
2241 rarg3 number;
2242 goal_state varchar2(1);
2243
2244 begin
2245 /* start time */
2246 select sysdate
2247 into mystart
2248 from dual;
2249
2250 /* get request info */
2251 begin
2252 select concurrent_program_id, program_application_id, phase_code,
2253 argument1, argument2, argument3, Decode(concurrent_program_id,
2254 0,null, 1,'E', 3, null, 4, 'X', 5, 'E', 7, 'P', 8, null, null)
2255 into prog_id, r_app_id, r_phase, rarg1, rarg2, rarg3, goal_state
2256 from fnd_concurrent_requests
2257 where request_id = reqid;
2258 exception
2259 when others then
2260 return SCTL_REQ_NOT_FOUND;
2261 end;
2262
2263 /* take out the trash */
2264 if ((r_app_id <> 0) OR (prog_id = 2) OR (prog_id = 6) OR (prog_id < 0) OR
2265 (prog_id > 8)) then
2266 return SCTL_REQ_NOT_SUPPD;
2267 end if;
2268
2269 LOOP
2270 /* see if we finished */
2271 if (Done = 0) then -- request ran...let's see if everything done
2272 Done := private_check_for_sctl_done(goal_state, rarg1, rarg2, rarg3);
2273 end if;
2274
2275 /* are we done? */
2276 if (Done = 1) then
2277 return SCTL_REQ_COMPLETED;
2278 end if;
2279
2280 /* Let's see if there is a reason that we are not done */
2281 if (Done = 0) then
2282 if (Find_SC_Conflict(reqid) > -1) then
2283 return SCTL_REQ_CONFLICTS;
2284 end if;
2285 end if;
2286
2287 /* time out? */
2288 select ((sysdate - mystart) * 86400) - Timeout
2289 into timesup
2290 from dual;
2291
2292 /* have we run yet? */
2293 select decode(phase_code, 'C', 0, -1)
2294 into Done
2295 from fnd_concurrent_requests
2296 where request_id = reqid;
2297
2298 if ((timesup > 0) and (Done = 0)) then
2299 return SCTL_TIMEOUT_NOT_C;
2300 elsif (timesup > 0) then
2301 return SCTL_TIMEOUT_NOT_R;
2302 end if;
2303
2304 dbms_lock.sleep(5);
2305 END LOOP;
2306
2307 end Wait_for_SCTL_Done;
2308
2309 Function SCTL_REQ_NOT_FOUND return number is
2310 begin
2311 return 1;
2312 end SCTL_REQ_NOT_FOUND;
2313
2314 Function SCTL_REQ_NOT_SUPPD return number is
2315 begin
2316 return 2;
2317 end SCTL_REQ_NOT_SUPPD;
2318
2319 Function SCTL_TIMEOUT_NOT_R return number is
2320 begin
2321 return 3;
2322 end SCTL_TIMEOUT_NOT_R;
2323
2324 Function SCTL_REQ_CONFLICTS return number is
2325 begin
2326 return 4;
2327 end SCTL_REQ_CONFLICTS;
2328
2329 Function SCTL_TIMEOUT_NOT_C return number is
2330 begin
2331 return 5;
2332 end SCTL_TIMEOUT_NOT_C;
2333
2334 Function SCTL_REQ_COMPLETED return number is
2335 begin
2336 return 6;
2337 end SCTL_REQ_COMPLETED;
2338
2339
2340 -- Name
2341 -- FND_CONCURRENT.Wait_For_All_Down
2342 -- Purpose
2343 -- Waits for all services, managers, and icm to go down, or timesout.
2344 --
2345 -- Arguments (input)
2346 -- Timeout - in seconds.
2347 --
2348 -- Returns:
2349 -- True if all shut down, false for timeout.
2350
2351 Function Wait_For_All_Down(Timeout in number) return boolean is
2352
2353 mystart date;
2354 done number := -1;
2355 icm_tgt number;
2356 icm_act number;
2357 icm_pmon varchar2(255);
2358 icm_callstat number;
2359
2360 begin
2361
2362 select sysdate
2363 into mystart
2364 from dual;
2365
2366
2367 LOOP
2368 /* check to see if the icm is down */
2369 get_manager_status(0,1,icm_tgt,icm_act,icm_pmon,icm_callstat);
2370
2371 if ((icm_tgt = 0) and (icm_act = 0) and (icm_callstat = 0)) then
2372 return TRUE;
2373 end if;
2374
2375 /* time out? */
2376 select ((sysdate - mystart) * 86400) - Timeout
2377 into done
2378 from dual;
2379
2380 if (done > 0) then return FALSE;
2381 end if;
2382
2383 dbms_lock.sleep(5);
2384 END LOOP;
2385
2386 exception
2387 when others then
2388 oraerrmesg := substr(SQLERRM, 1, 80);
2389 Fnd_Message.Set_Name('FND', 'CP-Generic oracle error');
2390 Fnd_Message.Set_Token('ERROR', oraerrmesg, FALSE);
2391 Fnd_Message.Set_Token('ROUTINE',
2392 'FND_CONCURRENT.WAIT_FOR_ALL_DOWN', FALSE);
2393 return FALSE;
2394 end Wait_For_All_Down;
2395
2396
2397 -- Name
2398 -- FND_CONCURRENT.Build_Svc_Ctrl_Desc.
2399 -- Purpose
2400 -- Provides description text for svc ctrl request based on args.
2401 --
2402 -- Arguments (input)
2403 -- Arg1, Arg2, Arg3 - request arguments for svc ctrl request.
2404 --
2405 -- Returns:
2406 -- Description of Request
2407
2408 Function Build_Svc_Ctrl_Desc(Arg1 in number,
2409 Arg2 in number,
2410 Arg3 in number,
2411 Prog in varchar2
2412 ) return varchar2 is
2413
2414
2415 action varchar2(255) := Prog;
2416 descr varchar2(255) := null;
2417 detail varchar2(255) := null;
2418
2419 begin
2420 begin
2421 select cp.USER_CONCURRENT_PROGRAM_NAME
2422 into action
2423 from fnd_concurrent_programs_vl cp, fnd_application a
2424 where cp.concurrent_program_name = prog
2425 AND cp.application_id = a.application_id
2426 AND a.application_short_name = 'FND';
2427 exception when others then
2428 null;
2429 end;
2430
2431 if (Arg1 >=0) then
2432
2433 begin
2434 select USER_CONCURRENT_QUEUE_NAME
2435 into Detail
2436 from fnd_concurrent_queues_vl
2437 where APPLICATION_ID = Arg2
2438 and concurrent_queue_id = Arg1;
2439 exception
2440 when others then
2441 Detail := 'QID = ' || to_char(Arg1);
2442 end;
2443
2444 Fnd_Message.Set_Name('FND', 'CP-MultiQC OldStyle');
2445 Fnd_Message.Set_Token('ACTION', action, FALSE);
2446 Fnd_Message.Set_Token('QUEUE', detail, FALSE);
2447 Descr := Fnd_Message.get;
2448
2449 return Descr;
2450
2451 elsif (Arg1 = -1) then
2452 begin
2453 select APPLICATION_NAME
2454 into Detail
2455 from fnd_application_vl
2456 where APPLICATION_ID = Arg2;
2457 exception
2458 when others then
2459 Detail := 'APPID = ' || to_char(Arg2);
2460 end;
2461
2462 Fnd_Message.Set_Name('FND', 'CP-MultiQC -1 ' || to_char(Arg3));
2463 Fnd_Message.Set_Token('ACTION', action, FALSE);
2464 Fnd_Message.Set_Token('APP', detail, FALSE);
2465 Descr := Fnd_Message.get;
2466
2467 return Descr;
2468
2469 elsif (Arg1 = -2) then
2470
2471 Fnd_Message.Set_Name('FND', 'CP-MultiQC -2');
2472 Fnd_Message.Set_Token('ACTION', action, FALSE);
2473 Descr := Fnd_Message.get;
2474
2475 return Descr;
2476
2477 elsif (Arg1 = -3) then
2478 begin
2479 select SERVICE_NAME
2480 into Detail
2481 from fnd_cp_services_vl
2482 where SERVICE_ID = Arg2;
2483 exception
2484 when others then
2485 Detail := 'SVCID = ' || to_char(Arg2);
2486 end;
2487
2488 Fnd_Message.Set_Name('FND', 'CP-MultiQC -3');
2489 Fnd_Message.Set_Token('ACTION', action, FALSE);
2490 Fnd_Message.Set_Token('SVC', detail, FALSE);
2491 Descr := Fnd_Message.get;
2492
2493 return Descr;
2494
2495 elsif (Arg1 = -4) then
2496
2497 Fnd_Message.Set_Name('FND', 'CP-MultiQC -4');
2498 Fnd_Message.Set_Token('ACTION', action, FALSE);
2499 Descr := Fnd_Message.get;
2500
2501 return Descr;
2502
2503
2504 else
2505 return Null;
2506 end if;
2507
2508 end Build_Svc_Ctrl_Desc;
2509
2510 -- Name
2511 -- FND_CONCURRENT.Cancel_Request.
2512 -- Purpose
2513 -- It Cancels given Concurrent Request.
2514 --
2515 -- Arguments (input)
2516 -- request_id - request id of the request you want to cancel.
2517 --
2518 -- (out args)
2519 -- message - API will fill the message with any errors while canceling
2520 -- request.
2521 --
2522 -- Returns:
2523 -- Returns TRUE if success or FALSE on failure.
2524 Function Cancel_Request( Request_Id in NUMBER,
2525 Message out NOCOPY VARCHAR2) return boolean is
2526 ret_val number;
2527 submitter number;
2528 request_missing exception;
2529 no_privilege exception;
2530
2531 begin
2532 -- check this user got privilege to cancel request
2533 begin
2534 Select Requested_By
2535 into submitter
2536 from fnd_concurrent_requests
2537 where request_id = Cancel_Request.request_id;
2538 exception
2539 when no_data_found then
2540 raise request_missing;
2541 end;
2542
2543 if ( submitter <> fnd_global.user_id ) then
2544 raise no_privilege;
2545 end if;
2546
2547 ret_val := FND_AMP_PRIVATE.cancel_request(request_id, message);
2548
2549 if ( ret_val = 0 ) then
2550 return FALSE;
2551 elsif ( ret_val = 1 ) then
2552 fnd_message.set_name('FND', 'CONC-Could not lock Request');
2553 message := fnd_message.get;
2554 return FALSE;
2555 elsif ( ret_val = 2 ) then
2556 fnd_message.set_name('FND', 'CONC-request completed');
2557 message := fnd_message.get;
2558 return FALSE;
2559 elsif ( ret_val = 3 ) then
2560 fnd_message.set_name('FND', 'CONC-cannot cancel mgr dead');
2561 message := fnd_message.get;
2562 return FALSE;
2563 elsif ( ret_val in (4,5)) then
2564 return TRUE;
2565 end if;
2566
2567 exception
2568 when request_missing then
2569 fnd_message.set_name('FND', 'CONC-MISSING REQUEST');
2570 fnd_message.set_token('ROUTINE', 'FND_CONCURRENT.CANCEL_REQUEST');
2571 fnd_message.set_token('REQUEST', to_char(request_id));
2572 message := fnd_message.get;
2573 return FALSE;
2574 when no_privilege then
2575 fnd_message.set_name('FND', 'CONC-NOT OWNER OF REQUEST');
2576 fnd_message.set_token('REQUEST', to_char(request_id));
2577 message := fnd_message.get;
2578 return FALSE;
2579 when others then
2580 fnd_message.set_name('FND', 'SQL_PLSQL_ERROR');
2581 fnd_message.set_token('ROUTINE', 'FND_CONCURRENT.CANCEL_REQUEST');
2582 fnd_message.set_token('ERRNO', SQLCODE);
2583 fnd_message.set_token('REASON', SQLERRM);
2584 message := fnd_message.get;
2585 return FALSE;
2586
2587 end Cancel_Request;
2588
2589 --
2590 -- Name
2591 -- FND_CONCURRENT.get_resource_lock
2592 -- Purpose
2593 -- It gets an exclusive lock for a given resource or task name.
2594 --
2595 -- Arguments (input)
2596 -- Resource_name - Name of the resource that uniquely identifies
2597 -- in the system.
2598 -- timeout - Number of seconds to continue trying to grant the lock
2599 -- default is 2 seconds.
2600 --
2601 -- Returns:
2602 -- 0 - Success
2603 -- 1 - Timeout
2604 -- 2 - Deadlock
2605 -- 3 - Parameter error
2606 -- 4 - Already own lock specified by lockhandle
2607 -- 5 - Illegal lock handle
2608 -- -1 - Other exceptions, get the message from message stack for reason.
2609
2610 function get_resource_lock ( resource_name in varchar2,
2611 timeout in number default 2 )
2612 return number is
2613 hndl varchar2(128);
2614 lk varchar2(128);
2615 result number := -1;
2616 begin
2617
2618 lk := 'FND$_' || resource_name;
2619
2620 dbms_lock.allocate_unique( lockname => lk,
2621 lockhandle => hndl );
2622
2623 result := dbms_lock.request( lockhandle => hndl,
2624 lockmode => 6,
2625 timeout => timeout );
2626
2627 return result;
2628
2629 exception
2630 when others then
2631 fnd_message.set_name ('FND', 'CP-Generic oracle error');
2632 fnd_message.set_token ('ERROR', substr (sqlerrm, 1, 30), FALSE);
2633 fnd_message.set_token ('ROUTINE', 'fnd_concurrent.get_resource_lock',
2634 FALSE);
2635 return result;
2636
2637 end;
2638
2639 --
2640 -- Name
2641 -- FND_CONCURRENT.release_resource_lock
2642 -- Purpose
2643 -- It releases an exclusive lock for a given resource or task name.
2644 --
2645 -- Arguments (input)
2646 -- Resource_name - Name of the resource that uniquely identifies
2647 -- in the system.
2648 --
2649 -- Returns:
2650 -- 0 - Success
2651 -- 3 - Parameter Error
2652 -- 4 - Do not own lock
2653 -- 5 - Illegal lock handle
2654 -- -1 - Other exceptions, get the message from message stack for reason.
2655
2656 function release_resource_lock ( resource_name in varchar2 ) return number is
2657 hndl varchar2(128);
2658 lk varchar2(128);
2659 result number := -1;
2660 begin
2661
2662 lk := 'FND$_' || resource_name;
2663
2664 dbms_lock.allocate_unique( lockname => lk,
2665 lockhandle => hndl );
2666
2667 result := dbms_lock.release( lockhandle => hndl );
2668
2669 return result;
2670
2671 exception
2672 when others then
2673 fnd_message.set_name ('FND', 'CP-Generic oracle error');
2674 fnd_message.set_token ('ERROR', substr (sqlerrm, 1, 30), FALSE);
2675 fnd_message.set_token ('ROUTINE', 'fnd_concurrent.release_resource_lock',
2676 FALSE);
2677 return result;
2678
2679 end;
2680
2681
2682
2683
2684
2685
2686
2687 --
2688 -- Name
2689 -- FND_CONCURRENT.INIT_SQL_REQUEST
2690 -- Purpose
2691 -- Called for all SQL*PLUS concurrent requests to perform request initialization.
2692 --
2693
2694 procedure init_sql_request is
2695
2696 creqid number;
2697 session_id number;
2698 userid number;
2699 respid number;
2700 respappid number;
2701 secgrpid number;
2702 siteid number;
2703 loginid number;
2704 cloginid number;
2705 progappid number;
2706 cprogid number;
2707 cprireqid number;
2708 counter number := 0;
2709
2710 lpid v$session.process%type;
2711 lmachine v$session.machine%type;
2712 position number;
2713 begin
2714
2715 -- Select all the information needed for this request from fnd_concurrent_requests,
2716 -- using the fnd_cp_sql_requests table.
2717 -- A row should have been inserted earlier in usdspid, containing the current request id,
2718 -- machine name, and process id.
2719 -- By joining these tables with v$session, we can pull out all the information we need,
2720 -- using only our own session id.
2721 begin
2722
2723
2724
2725 select process, machine
2726 into lpid, lmachine
2727 from v$session
2728 where audsid = userenv('sessionid');
2729
2730 position := instr(lpid,':');
2731 if ( position>0 ) then
2732 lpid := substr(lpid,1,position-1);
2733 end if;
2734
2735 while counter <= 4 loop
2736 counter := counter + 1;
2737 begin
2738 select 0, fcr.requested_by,
2739 fcr.responsibility_id, fcr.responsibility_application_id,
2740 fcr.security_group_id, 0,
2741 fcr.requested_by, fcr.conc_login_id,
2742 fcr.program_application_id, fcr.concurrent_program_id,
2743 fcr.request_id, fcr.priority_request_id
2744 into session_id, userid, respid, respappid,
2745 secgrpid, siteid, loginid, cloginid,
2746 progappid, cprogid, creqid, cprireqid
2747 from fnd_concurrent_requests fcr,
2748 fnd_cp_sql_requests sr
2749 where fcr.phase_code = 'R'
2750 and fcr.status_code = 'R'
2751 and fcr.request_id = sr.request_id
2752 and sr.machine = lmachine
2753 and sr.client_process_id = lpid;
2754
2755 fnd_global.bless_next_init('FND_PERMIT_0002');
2756 FND_GLOBAL.INITIALIZE(session_id, userid, respid, respappid, secgrpid, siteid, loginid,
2757 cloginid, progappid, cprogid, creqid, cprireqid);
2758
2759 -- now delete the row, to avoid having to purge the table.
2760 DELETE from fnd_cp_sql_requests where request_id = creqid;
2761
2762 exit;
2763 exception
2764 when no_data_found then
2765 if (counter = 1) then
2766 DBMS_LOCK.sleep(5);
2767 elsif (counter > 1 and counter <= 4) then
2768 DBMS_LOCK.sleep(10);
2769 else
2770 -- no row found, most likely ran from the command line.
2771 -- Initialize a default context:
2772 -- USER = ANONYMOUS (-1)
2773 -- RESP = System Administrator (20420)
2774 -- RESP APPL = System Administration (1)
2775 FND_GLOBAL.APPS_INITIALIZE(-1, 20420, 1);
2776 end if;
2777
2778 end;
2779 end loop;
2780
2781 -- The rest of the initialization used to be hardcoded into the SQL script by fdpsql().
2782 INIT_REQUEST;
2783
2784 FND_PROFILE.PUT('SECURITY_GROUP_ID', FND_GLOBAL.SECURITY_GROUP_ID);
2785
2786 SET_PREFERRED_RBS;
2787
2788 exception
2789 when others then
2790
2791 if ( FND_LOG.LEVEL_EXCEPTION >= FND_LOG.G_CURRENT_RUNTIME_LEVEL ) then
2792 fnd_message.set_name ('FND', 'SQL-Generic error');
2793 fnd_message.set_token ('ERRNO', sqlcode, FALSE);
2794 fnd_message.set_token ('REASON', sqlerrm, FALSE);
2795 fnd_message.set_token ('ROUTINE', 'FND_CONCURRENT.INIT_SQL_REQUEST', FALSE);
2796 fnd_log.message(FND_LOG.LEVEL_EXCEPTION,
2797 'fnd.plsql.FND_CONCURRENT.INIT_SQL_REQUEST.others', FALSE);
2798 end if;
2799 end;
2800
2801 end init_sql_request;
2802
2803 --procedure debug(message in varchar2) is
2804 -- pragma autonomous_transaction;
2805 -- msg varchar2(2000);
2806 -- l_count number;
2807 -- begin
2808
2809 -- insert into FND_CONCURRENT_DEBUG_INFO(TIME, ACTION, message, TIME_IN_NUMBER)
2810 -- VALUES(sysdate,'FND_CONCURRENT.get_m_s',message,0);
2811 --commit;
2812 --end debug;
2813
2814
2815 function check_user_privileges( p_user_name IN varchar2,
2816 p_test_code IN varchar2 DEFAULT NULL) RETURN number IS
2817 l_user_id number := -1;
2818 l_resp_id number := -1;
2819 l_ret_value number := 0;
2820 CURSOR l_user_csr(p_user_name varchar2) IS
2821 SELECT user_id
2822 FROM fnd_user
2823 WHERE user_name = upper(p_user_name);
2824 CURSOR l_resp_csr(p_responsibility_key varchar2) IS
2825 SELECT responsibility_id
2826 FROM fnd_responsibility
2827 WHERE responsibility_key = p_responsibility_key;
2828 CURSOR l_user_resp_csr( p_user_id number, p_responsibility_id number)IS
2829 SELECT count(responsibility_id)
2830 FROM fnd_user_resp_groups
2831 WHERE user_id = p_user_id
2832 AND responsibility_id = p_responsibility_id;
2833 BEGIN
2834 IF (p_test_code <> 'STARTMGR' and p_test_code <> 'RUNCONCPROG') THEN
2835 l_ret_value := -1;
2836 RETURN l_ret_value;
2837 END IF;
2838
2839 OPEN l_user_csr(check_user_privileges.p_user_name);
2840 FETCH l_user_csr INTO l_user_id;
2841 CLOSE l_user_csr;
2842
2843 OPEN l_resp_csr('SYSTEM_ADMINISTRATOR');
2844 FETCH l_resp_csr INTO l_resp_id;
2845 CLOSE l_resp_csr;
2846
2847 IF (l_user_id <> -1 and l_resp_id <> -1) THEN
2848 OPEN l_user_resp_csr(l_user_id, l_resp_id);
2849 FETCH l_user_resp_csr INTO l_ret_value;
2850 CLOSE l_user_resp_csr;
2851 END IF;
2852
2853 IF (l_user_id <> -1 and l_ret_value = 0) THEN
2854 OPEN l_resp_csr('FND_CM_OPERATOR_RESP');
2855 FETCH l_resp_csr INTO l_resp_id;
2856 CLOSE l_resp_csr;
2857 IF (l_resp_id <> -1) THEN
2858 OPEN l_user_resp_csr(l_user_id, l_resp_id);
2859 FETCH l_user_resp_csr INTO l_ret_value;
2860 CLOSE l_user_resp_csr;
2861 END IF;
2862 END IF;
2863
2864 RETURN l_ret_value;
2865 END check_user_privileges;
2866
2867 function check_program_privileges( p_user_name IN varchar2,
2868 p_resp_id IN number DEFAULT NULL,
2869 p_resp_appl_id IN number DEFAULT NULL,
2870 p_program_name IN varchar2,
2871 p_application_short_name IN varchar2,
2872 p_sec_group_id IN number ) RETURN number IS
2873 l_ret_value number := 0;
2874 l_application_id number;
2875 l_conc_program_id number;
2876 l_user_id number := -1;
2877 l_srs_flag varchar2(1);
2878 l_predicate varchar2(9500);
2879 l_sql_stmt varchar2(10000);
2880 l_return_status varchar2(1);
2881
2882 CURSOR l_user_resp_csr(p_user_id number,
2883 p_resp_id number,
2884 p_resp_appl_id number,
2885 p_sec_group_id number)IS
2886 SELECT count(responsibility_id)
2887 FROM fnd_user_resp_groups
2888 WHERE user_id = p_user_id
2889 AND responsibility_id = p_resp_id
2890 AND responsibility_application_id = p_resp_appl_id
2891 AND security_group_id = p_sec_group_id;
2892
2893 CURSOR l_user_csr(p_user_name varchar2) IS
2894 SELECT user_id
2895 FROM fnd_user
2896 WHERE user_name = upper(p_user_name);
2897
2898 CURSOR l_appl_id_csr(p_application_short_name varchar2) IS
2899 SELECT application_id
2900 FROM fnd_application
2901 WHERE application_short_name = p_application_short_name;
2902
2903 CURSOR l_prog_id_csr(p_program_name varchar2,
2904 p_application_id number) IS
2905 SELECT concurrent_program_id, srs_flag
2906 FROM fnd_concurrent_programs
2907 WHERE concurrent_program_name = p_program_name
2908 AND application_id = p_application_id;
2909
2910 BEGIN
2911 OPEN l_user_csr(check_program_privileges.p_user_name);
2912 FETCH l_user_csr INTO l_user_id;
2913 CLOSE l_user_csr;
2914
2915 OPEN l_appl_id_csr(p_application_short_name);
2916 FETCH l_appl_id_csr INTO l_application_id;
2917 CLOSE l_appl_id_csr;
2918
2919 OPEN l_prog_id_csr(p_program_name, l_application_id);
2920 FETCH l_prog_id_csr INTO l_conc_program_id, l_srs_flag;
2921 CLOSE l_prog_id_csr;
2922
2923 IF (l_application_id is not null and l_conc_program_id is not NULL
2924 AND l_user_id IS NOT null) THEN
2925
2926 OPEN l_user_resp_csr(l_user_id, check_program_privileges.p_resp_id,
2927 check_program_privileges.p_resp_appl_id,
2928 check_program_privileges.p_sec_group_id);
2929 FETCH l_user_resp_csr INTO l_ret_value;
2930 CLOSE l_user_resp_csr;
2931 IF (l_ret_value = 0) THEN
2932 l_ret_value := -1;
2933 RETURN l_ret_value;
2934 END IF;
2935 l_ret_value := 0;
2936
2937 --check IF this program is not SRS-enabled and IF true let it pass through
2938 IF (check_user_privileges(p_user_name, 'RUNCONCPROG') > 0 AND (l_srs_flag = 'N' OR l_srs_flag = 'Q')) THEN
2939 l_ret_value := 1;
2940 ELSIF (l_srs_flag = 'Y') THEN
2941 fnd_global.apps_initialize
2942 (user_id => l_user_id,
2943 resp_id => p_resp_id,
2944 resp_appl_id => p_resp_appl_id,
2945 security_group_id => p_sec_group_id);
2946
2947 fnd_data_security.get_security_predicate
2948 (p_api_version => 1.0,
2949 p_function => 'FND_CP_REQ_SUBMIT',
2950 p_object_name => 'FND_CONCURRENT_PROGRAMS',
2951 x_predicate => l_predicate,
2952 x_return_status => l_return_status,
2953 p_table_alias => 'p');
2954
2955 l_sql_stmt := 'select count(p.concurrent_program_id) from fnd_concurrent_programs p where p.concurrent_program_id = :1 and p.application_id = :2 and ' || l_predicate || '';
2956
2957 execute immediate l_sql_stmt INTO l_ret_value using l_conc_program_id, l_application_id;
2958
2959 IF (l_ret_value > 0) THEN
2960 l_ret_value := 1;
2961 ELSE
2962 l_ret_value := 0;
2963 END IF;
2964
2965 END IF; --IF (l_srs...
2966 ELSE
2967 l_ret_value := -1;
2968 END IF; --IF l_application_id...
2969
2970 RETURN l_ret_value;
2971 END check_program_privileges;
2972
2973
2974 end FND_CONCURRENT;