DBA Data[Home] [Help]

PACKAGE BODY: APPS.FND_ADG_SUPPORT

Source


1 package body fnd_adg_support as
2 /* $Header: AFDGSUPB.pls 120.11 2010/08/13 15:22:16 rsanders noship $ */
3 
4 G_IS_STANDBY	boolean	:= null;
5 G_IS_PRIMARY    boolean := null;
6 G_IS_NO_DML	boolean := null;
7 G_IS_TRUE_STANDBY boolean := null;
8 G_HANDLE_REQUEST_ROW_ALL boolean := null;
9 G_HANDLE_REQUEST_ROW_PRIMARY boolean := null;
10 
11 C_OPEN_READ_ONLY	constant 	varchar2(30) := 'READ ONLY';
12 C_OPEN_READ_WRITE	constant 	varchar2(30) := 'READ WRITE';
13 C_STANDBY_ROLE		constant        varchar2(30) := 'PHYSICAL STANDBY';
14 C_PRIMARY_ROLE		constant        varchar2(30) := 'PRIMARY';
15 
16 C_REPORTWRITER		constant        varchar2(30) := 'P';
17 C_STATUS_NORMAL		constant	varchar2(10) := 'C';
18 C_PHASE_COMPLETE	constant        varchar2(10) := 'C';
19 
20 	-- use real CR to get passed arcs!
21 
22 LF			constant        varchar2(10) := '
23 ';
24 
25 /*==========================================================================*/
26 
27 procedure set_is_no_dml
28 as
29 begin
30 
31 	-- This routine currently does nothing but separates is_standby
32 	-- from dml.
33 
34   G_IS_NO_DML := true;
35 
36 end;
37 
38 /*==========================================================================*/
39 
40 procedure set_handle_request_row_change
41 as
42 begin
43 
44   G_HANDLE_REQUEST_ROW_ALL := false;
45   G_HANDLE_REQUEST_ROW_PRIMARY := false;
46 
47   if ( fnd_adg_utility.is_standby_access_supported )
48   then
49      if ( fnd_adg_utility.is_adg_support_enabled )
50      then
51         G_HANDLE_REQUEST_ROW_ALL := true;
52      end if;
53 
54      if ( fnd_adg_utility.is_always_collect_primary_data )
55      then
56         G_HANDLE_REQUEST_ROW_PRIMARY := true;
57      end if;
58   end if;
59 
60 end;
61 
62 /*==========================================================================*/
63 
64 	-- Currently unused and removed from spec.
65 
66 function is_standby_no_dml return boolean
67 as
68 begin
69 
70   if ( not is_standby )
71   then
72      return false;
73   end if;
74 
75   if ( G_IS_NO_DML is null )
76   then
77      set_is_no_dml;
78   end if;
79 
80   return G_IS_NO_DML;
81 
82 end;
83 
84 /*==========================================================================*/
85 
86 procedure set_is_standby
87 as
88 cursor c1 is select a.open_mode,a.database_role
89                from v$database a;
90 begin
91 
92   G_IS_STANDBY := false;
93 
94 	-- To keep in sync with RPC usage and to avoid redundant checks
95 	-- always return false unless compile directive is in force.
96 
97 $if fnd_adg_compile_directive.enable_rpc
98 $then
99 
100   if ( fnd_adg_utility.is_standby_access_supported and
101        fnd_adg_utility.is_adg_support_enabled )
102   then
103 
104      for f_rec in c1 loop
105 
106        if ( f_rec.open_mode    = C_OPEN_READ_ONLY    and
107             f_rec.database_role= C_STANDBY_ROLE )
108        then
109           G_IS_STANDBY := true;
110        end if;
111      end loop;
112 
113      if ( not G_IS_STANDBY )
114      then
115 	-- Allow for simulated standby if running on primary.
116 
117         if ( fnd_adg_utility.is_session_simulated_standby and is_primary )
118         then
119            if ( not is_rpc_from_standby ) -- only true when slave rpc
120            then
121               G_IS_STANDBY := true; -- rpc client is now simulated as standby.
122            end if;
123         end if;
124      end if;
125 
126   end if;
127 
128 $else
129      null;
130 $end
131 
132 end;
133 
134 /*==========================================================================*/
135 
136 procedure set_is_true_standby
137 as
138 cursor c1 is select a.open_mode,a.database_role
139                from v$database a;
140 begin
141 
142   G_IS_TRUE_STANDBY := false;
143 
144   if ( fnd_adg_utility.is_standby_access_supported )
145   then
146      for f_rec in c1 loop
147 
148        if ( f_rec.open_mode    = C_OPEN_READ_ONLY    and
149             f_rec.database_role= C_STANDBY_ROLE )
150        then
151           G_IS_TRUE_STANDBY := true;
152        end if;
153      end loop;
154   end if;
155 
156 end;
157 
158 /*==========================================================================*/
159 
160 procedure set_is_primary
161 as
162 cursor c1 is select a.open_mode,a.database_role
163                from v$database a;
164 begin
165 
166   G_IS_PRIMARY := false;
167 
168   for f_rec in c1 loop
169 
170     if ( f_rec.open_mode    = C_OPEN_READ_WRITE    and
171          f_rec.database_role= C_PRIMARY_ROLE )
172     then
173        G_IS_PRIMARY := true;
174     end if;
175   end loop;
176 
177 end;
178 
179 /*==========================================================================*/
180 
181 function boolean_to_yn(p_bool boolean) return varchar2
182 as
183 begin
184 
185   if ( p_bool is null )
186   then
187      return null;
188   end if;
189 
190   if ( p_bool )
191   then
192      return 'Y';
193   else
194      return 'N';
195   end if;
196 
197 end;
198 
199 /*==========================================================================*/
200 
201 function boolean_to_ynu(p_bool boolean) return varchar2
202 as
203 begin
204 
205   if ( p_bool is null )
206   then
207      return 'U';
208   end if;
209 
210   if ( p_bool )
211   then
212      return 'Y';
213   else
214      return 'N';
215   end if;
216 
217 end;
218 
219 /*==========================================================================*/
220 
221 function yn_to_boolean(p_yn varchar2) return boolean
222 as
223 begin
224 
225   if ( upper(p_yn) = 'Y' )
226   then
227      return true;
228   else
229      return false;
230   end if;
231 
232 end;
233 
234 /*==========================================================================*/
235 
236 function ynu_to_boolean(p_yn varchar2) return boolean
237 as
238 begin
239 
240   if ( upper(p_yn) = 'Y' )
241   then
242      return true;
243   else
244      if ( upper(p_yn) = 'N' )
245      then
246         return false;
247      else
248         return null;
249      end if;
250   end if;
251 
252 end;
253 
254 /*==========================================================================*/
255 /*==================== Start of concurrent program methods =================*/
256 /*==========================================================================*/
257 
258 /*==========================================================================*/
259 
260 function init_program_change_rec return fnd_adg_concurrent_program%rowtype
261 as
262 l_cp_rec fnd_adg_concurrent_program%rowtype;
263 begin
264 
265   l_cp_rec.Application_Id 		       := null;
266   l_cp_rec.Concurrent_Program_Id               := null;
267   l_cp_rec.Supported_Executable_Type           := null;
268   l_cp_rec.Has_Run_On_Primary                  := null;
269   l_cp_rec.Has_Run_In_Simulated_Standby        := null;
270   l_cp_rec.Run_On_Standby                      := null;
271   l_cp_rec.No_Standby_Failures                 := null;
272   l_cp_rec.Max_Standby_Failures                := null;
273   l_cp_rec.No_Simulated_Standby_Failures       := null;
274   l_cp_rec.Max_Simulated_Standby_Failures      := null;
275   l_cp_rec.always_redirect_if_valid	       := null;
276   l_cp_rec.use_automatic_redirection	       := null;
277 
278   return l_cp_rec;
279 
280 end;
281 
282 /*==========================================================================*/
283 
284 procedure update_conc_program_rec(p_cp_rec fnd_adg_concurrent_program%rowtype,
285                                   p_cp_chng_rec
286                                            fnd_adg_concurrent_program%rowtype,
287                                   p_util_caller boolean default false)
288 as
289 PRAGMA AUTONOMOUS_TRANSACTION;
290 l_curr_cp_rec fnd_adg_concurrent_program%rowtype;
291 begin
292 
293   select a.*
294     into l_curr_cp_rec
295     from fnd_adg_concurrent_program a
296    where a.Application_Id = p_cp_rec.Application_Id
297      and a.Concurrent_Program_Id = p_cp_rec.Concurrent_Program_Id
298      for update of a.Application_Id;
299 
300   if ( p_cp_chng_rec.Supported_Executable_Type is not null )
301   then
302      l_curr_cp_rec.Supported_Executable_Type :=
303                                   p_cp_chng_rec.Supported_Executable_Type;
304   end if;
305 
306   if ( p_cp_chng_rec.Has_Run_On_Primary is not null )
307   then
308      l_curr_cp_rec.Has_Run_On_Primary    := p_cp_chng_rec.Has_Run_On_Primary;
309   end if;
310 
311   if ( p_cp_chng_rec.Has_Run_In_Simulated_Standby is not null )
312   then
313      l_curr_cp_rec.Has_Run_In_Simulated_Standby :=
314                                   p_cp_chng_rec.Has_Run_In_Simulated_Standby;
315   end if;
316 
317   if ( p_cp_chng_rec.Run_On_Standby is not null )
318   then
319      if ( l_curr_cp_rec.Run_On_Standby <> p_cp_chng_rec.Run_On_Standby )
320      then
321         if ( ynu_to_boolean(l_curr_cp_rec.Run_On_Standby) is null or
322              ynu_to_boolean(l_curr_cp_rec.Run_On_Standby) or p_util_caller )
323         then
324            l_curr_cp_rec.Run_On_Standby        := p_cp_chng_rec.Run_On_Standby;
325         end if;
326      end if;
327   end if;
328 
329   if ( p_cp_chng_rec.No_Standby_Failures is not null )
330   then
331      l_curr_cp_rec.No_Standby_Failures   := p_cp_chng_rec.No_Standby_Failures;
332   end if;
333 
334   if ( p_cp_chng_rec.Max_Standby_Failures is not null )
335   then
336      l_curr_cp_rec.Max_Standby_Failures  := p_cp_chng_rec.Max_Standby_Failures;
337   end if;
338 
339   if ( p_cp_chng_rec.No_Simulated_Standby_Failures is not null )
340   then
341      l_curr_cp_rec.No_Simulated_Standby_Failures :=
342                                   p_cp_chng_rec.No_Simulated_Standby_Failures;
343   end if;
344 
345   if ( p_cp_chng_rec.Max_Simulated_Standby_Failures is not null )
346   then
347      l_curr_cp_rec.Max_Simulated_Standby_Failures :=
348                                   p_cp_chng_rec.Max_Simulated_Standby_Failures;
349   end if;
350 
351   if ( p_cp_chng_rec.always_redirect_if_valid is not null )
352   then
353      l_curr_cp_rec.always_redirect_if_valid :=
354                        p_cp_chng_rec.always_redirect_if_valid;
355   end if;
356 
357   if ( p_cp_chng_rec.use_automatic_redirection is not null )
358   then
359      l_curr_cp_rec.use_automatic_redirection :=
360                        p_cp_chng_rec.use_automatic_redirection;
361   end if;
362 
363   update fnd_adg_concurrent_program a
364      set row = l_curr_cp_rec
365    where a.Application_Id = p_cp_rec.Application_Id
366      and a.Concurrent_Program_Id = p_cp_rec.Concurrent_Program_Id;
367 
368   commit;
369 
370 end;
371 
372 /*==========================================================================*/
373 
374 function is_standalone_executable(p_cp_rec fnd_adg_concurrent_program%rowtype)
375                                     return boolean
376 as
377 begin
378 
379 	-- We currently only support standalone executables. If this
380 	-- ever changes this function needs to be changed. Why? Because with
381 	-- standalone we update simulation stats on logoff whereas
382 	-- for embedded stats are done under the update trigger.
383 	-- This only applies to simulation stats.
384 
385   return true;
386 
387 end;
388 
389 /*==========================================================================*/
390 
391 function is_conc_program_supported(p_program_application_id number,
392                                    p_concurrent_program_id number)
393                                                            return boolean
394 as
395 l_Execution_Method_Code varchar2(10);
396 begin
397 
398   begin
399 
400     select a.Execution_Method_Code
401       into l_Execution_Method_Code
402       from fnd_concurrent_programs a
403      where a.APPLICATION_ID = p_program_application_id
404        and a.CONCURRENT_PROGRAM_ID = p_concurrent_program_id;
405 
406     if ( l_Execution_Method_Code = C_REPORTWRITER )
407     then
408        return true;
409     else
410        return false;
411     end if;
412 
413   exception
414       when no_data_found then
415             return null;
416   end;
417 
418 end;
419 
420 /*==========================================================================*/
421 
422 function create_conc_program_rec(p_program_application_id number,
423                                  p_concurrent_program_id number)
424                                return fnd_adg_concurrent_program%rowtype
425 as
426 PRAGMA AUTONOMOUS_TRANSACTION;
427 l_new_cp_rec fnd_adg_concurrent_program%rowtype;
428 l_is_supported_exe_type boolean;
429 begin
430 
431   l_is_supported_exe_type :=
432         is_conc_program_supported(p_program_application_id,
433                                   p_concurrent_program_id);
434 
435   if ( l_is_supported_exe_type is null ) -- conc. program doesn't exist!
436   then
437      l_new_cp_rec.Application_Id                 := null;
438      l_new_cp_rec.Concurrent_Program_Id          := null;
439      commit;
440      return l_new_cp_rec;
441   end if;
442 
443   l_new_cp_rec.Application_Id                 := p_program_application_id;
444   l_new_cp_rec.Concurrent_Program_Id          := p_concurrent_program_id;
445   l_new_cp_rec.Supported_Executable_Type      :=
446                                          boolean_to_yn(l_is_supported_exe_type);
447   l_new_cp_rec.Has_Run_On_Primary             := boolean_to_yn(false);
448   l_new_cp_rec.Has_Run_In_Simulated_Standby   := boolean_to_yn(false);
449   l_new_cp_rec.Run_On_Standby                 := boolean_to_ynu(null);
450   l_new_cp_rec.No_Standby_Failures            := 0;
451   l_new_cp_rec.Max_Standby_Failures           := 0;
452   l_new_cp_rec.No_Simulated_Standby_Failures  := 0;
453   l_new_cp_rec.Max_Simulated_Standby_Failures := 0;
454   l_new_cp_rec.always_redirect_if_valid       := boolean_to_yn(true);
455   l_new_cp_rec.use_automatic_redirection      := boolean_to_yn(false);
456 
457   begin
458 
459     insert into fnd_adg_concurrent_program values l_new_cp_rec ;
460 
461     commit;
462 
463   exception
464 
465     when DUP_VAL_ON_INDEX then   -- somebody got there first
466 
467        select a.*
468          into l_new_cp_rec
469          from fnd_adg_concurrent_program a
470         where a.Application_Id = p_program_application_id
471           and a.Concurrent_Program_Id = p_concurrent_program_id;
472 
473   end;
474 
475   return l_new_cp_rec;
476 
477 end;
478 
479 /*==========================================================================*/
480 
481 function get_conc_program_rec(p_program_application_id number,
482                               p_concurrent_program_id number)
483                                return fnd_adg_concurrent_program%rowtype
484 as
485 l_cp_rec fnd_adg_concurrent_program%rowtype;
486 begin
487 
488   begin
489 
490     select a.*
491       into l_cp_rec
492       from fnd_adg_concurrent_program a
493      where a.Application_Id = p_program_application_id
494        and a.Concurrent_Program_Id = p_concurrent_program_id;
495 
496   exception
497 
498     when no_data_found then
499 
500          l_cp_rec := create_conc_program_rec(p_program_application_id,
501                                              p_concurrent_program_id);
502   end;
503 
504   return l_cp_rec;
505 
506 end;
507 
508 /*==========================================================================*/
509 
510 function is_conc_program_changes(p_cp_chng_rec
511                                     fnd_adg_concurrent_program%rowtype)
512                                                return boolean
513 as
514 begin
515 
516   if (
517        p_cp_chng_rec.Application_Id                      is not null or
518        p_cp_chng_rec.Concurrent_Program_Id               is not null or
519        p_cp_chng_rec.Supported_Executable_Type           is not null or
520        p_cp_chng_rec.Has_Run_On_Primary                  is not null or
521        p_cp_chng_rec.Has_Run_In_Simulated_Standby        is not null or
522        p_cp_chng_rec.Run_On_Standby                      is not null or
523        p_cp_chng_rec.No_Standby_Failures                 is not null or
524        p_cp_chng_rec.Max_Standby_Failures                is not null or
525        p_cp_chng_rec.No_Simulated_Standby_Failures       is not null or
526        p_cp_chng_rec.Max_Simulated_Standby_Failures      is not null or
527        p_cp_chng_rec.always_redirect_if_valid		 is not null or
528        p_cp_chng_rec.use_automatic_redirection           is not null
529      )
530   then
531      return true;
532   else
533      return false;
534   end if;
535 
536 end;
537 
538 /*==========================================================================*/
539 
540 procedure do_handle_request_row_update(p_cp_rec
541                                           fnd_adg_concurrent_program%rowtype,
542                                        p_cp_chng_rec in out nocopy
543                                           fnd_adg_concurrent_program%rowtype,
544                                        p_connstr1 in out nocopy varchar2,
545                                        p_phase_code varchar2,
546                                        p_status_code varchar2
547                                       )
548 as
549 l_request_success boolean;
550 l_standby_exists boolean;
551 l_standby_valid boolean;
552 l_simulation_connstr varchar2(255);
553 l_simulation_valid boolean;
554 l_mgr_stndby_req_class_app_id number;
555 l_mgr_stndby_req_class_id number;
556 begin
557 
558   if ( p_status_code = C_STATUS_NORMAL and
559        p_phase_code  = C_PHASE_COMPLETE )
560   then
561      l_request_success := true;
562   else
563      l_request_success := false;
564   end if;
565 
566        -- Handle PRIMARY only functions first.
567 
568   if ( l_request_success and is_primary and
569                 not yn_to_boolean(p_cp_rec.Has_Run_On_Primary))
570   then
571      p_cp_chng_rec.Has_Run_On_Primary := boolean_to_yn(true);
572   end if;
573 
574   if ( not G_HANDLE_REQUEST_ROW_ALL )
575   then
576      return;
577   end if;
578 
579         -- Nothing to do if connstr is null;
580 
581   if ( p_connstr1 is null )
582   then
583      return;
584   end if;
585 
586   fnd_adg_utility.find_registered_standby
587              (p_connstr1,l_standby_exists,l_standby_valid,
588               l_mgr_stndby_req_class_app_id,l_mgr_stndby_req_class_id);
589 
590   fnd_adg_utility.get_connection_data
591                   (fnd_adg_utility.C_CONNECT_TO_SIMULATED_STANDBY,
592                    l_simulation_valid, l_simulation_connstr);
593 
594   if ( not l_standby_exists )
595   then
596      if ( l_simulation_valid and l_simulation_connstr = p_connstr1 )
597      then
598         null;
599      else
600         return;
601      end if;
602   end if;
603 
604   if ( l_request_success )
605   then
606      if ( l_simulation_valid and p_connstr1 = l_simulation_connstr )
607      then
608         if ( not yn_to_boolean(p_cp_rec.Has_Run_In_Simulated_Standby) )
609         then
610            p_cp_chng_rec.Has_Run_In_Simulated_Standby := boolean_to_yn(true);
611         end if;
612 
613         if ( p_cp_rec.No_Standby_Failures <= p_cp_rec.Max_Standby_Failures and
614              p_cp_rec.No_Simulated_Standby_Failures <=
615                             p_cp_rec.Max_Simulated_Standby_Failures )
616         then
617 
618            if ( fnd_adg_utility.is_simulated_standby_enabled and
619                 fnd_adg_utility.is_auto_simulation_enabled )
620            then
621               p_cp_chng_rec.Run_On_Standby := boolean_to_ynu(true);
622            end if;
623         end if;
624      end if;
625   else
626 
627      if ( l_standby_valid )
628      then
629         if ( p_cp_rec.No_Standby_Failures > p_cp_rec.Max_Standby_Failures )
630         then
631            if ( ynu_to_boolean(p_cp_rec.Run_On_Standby) is null or
632                 ynu_to_boolean(p_cp_rec.Run_On_Standby) )
633            then
634               p_cp_chng_rec.Run_On_Standby := boolean_to_ynu(false);
635            end if;
636         end if;
637      else
638          if ( p_cp_rec.No_Simulated_Standby_Failures >
639                             p_cp_rec.Max_Simulated_Standby_Failures )
640          then
641             if ( ynu_to_boolean(p_cp_rec.Run_On_Standby) is null or
642                  ynu_to_boolean(p_cp_rec.Run_On_Standby) )
643             then
644                p_cp_chng_rec.Run_On_Standby := boolean_to_ynu(false);
645             end if;
646          end if;
647      end if;
648 
649   end if;
650 
651 end;
652 
653 /*==========================================================================*/
654 
655 procedure do_handle_request_row_insert(p_cp_rec
656                                           fnd_adg_concurrent_program%rowtype,
657                                        p_cp_chng_rec in out nocopy
658                                           fnd_adg_concurrent_program%rowtype,
659                                        p_connstr1 in out nocopy varchar2,
660                                        p_nodename1 in out nocopy varchar2,
661                                        p_request_class_application_id
662                                                      in out nocopy number,
663                                        p_concurrent_request_class_id
664                                                      in out nocopy number
665                                       )
666 as
667 l_mgr_stndby_req_class_app_id number;
668 l_mgr_stndby_req_class_id number;
669 l_auto_stndby_req_class_app_id number;
670 l_auto_stndby_req_class_id number;
671 l_standby_exists boolean;
672 l_standby_valid boolean;
673 l_simulation_connstr varchar2(255);
674 l_simulation_valid boolean;
675 l_manager_must_be_running boolean;
676 l_auto_valid boolean;
677 l_auto_connstr1 varchar(255);
678 l_known_adg_connection boolean;
679 l_is_standby_mgr_defined boolean;
680 
681 begin
682 
683 	-- Must be ALL processing for INSERT.
684 
685   if ( not G_HANDLE_REQUEST_ROW_ALL )
686   then
687      return;
688   end if;
689 
690   l_auto_valid := false;
691 
692 	-- Special handling when automatic redirection is enabled.
693 
694 
695   if ( fnd_adg_utility.is_automatic_redirection and
696        yn_to_boolean(p_cp_rec.use_automatic_redirection ) )
697   then
698      for i in 1..fnd_adg_utility.get_max_standby_systems loop
699 
700        fnd_adg_utility.get_connection_data
701                        (fnd_adg_utility.C_CONNECT_PRIMARY_TO_STANDBY,
702                         l_auto_valid,l_auto_connstr1,i);
703 
704         if ( l_auto_valid )
705         then
706            fnd_adg_utility.get_standby_cm_class(i,l_auto_stndby_req_class_app_id,
707                                                l_auto_stndby_req_class_id);
708            exit;
709         end if;
710      end loop;
711   end if;
712 
713 	-- Nothing to do if connstr is null and no automatic redirection;
714 
715   if ( p_connstr1 is null and not l_auto_valid )
716   then
717      return;
718   end if;
719 
720 	-- Connstr could be standby or simulation
721 
722   fnd_adg_utility.find_registered_standby
723              (p_connstr1,l_standby_exists,l_standby_valid,
724               l_mgr_stndby_req_class_app_id,l_mgr_stndby_req_class_id);
725 
726   fnd_adg_utility.get_connection_data
727                   (fnd_adg_utility.C_CONNECT_TO_SIMULATED_STANDBY,
728                    l_simulation_valid,l_simulation_connstr);
729 
730 	-- If supplied connstr exists then we use it and ignore
731 	-- automatic redirection even if it turns out to be invalid. After
732 	-- all user supplied it.
733 
734   if ( l_standby_exists )
735   then
736      l_auto_valid := false;
737   end if;
738 
739 	-- Now determine whether supplied connect string is known by
740 	-- ADG. At the same time set the on-validation return string - i.e.
741 	-- if we're using automatic redirection but the report is not a
742 	-- candidate we need to return string as is - it could be an instance
743 	-- connect string.
744 
745   l_known_adg_connection := false;
746 
747   if ( p_connstr1 is not null )
748   then
749      if ( l_standby_exists )
750      then
751 	-- Doesn't matter whether valid or not we always return null
752 	-- except for the final switch.
753 
754         l_known_adg_connection := true;
755      else
756         if ( l_simulation_connstr is not null and
757              l_simulation_connstr = p_connstr1 )
758         then
759            l_known_adg_connection := true;
760         end if;
761      end if;
762   end if;
763 
764   	-- If connstr not standby or simulation and not
765 	-- auto redirection enabled then nothing to do with us.
766 
767   if ( not l_auto_valid )
768   then
769      if ( l_known_adg_connection )
770      then
771         if ( l_standby_exists )
772         then
773            if ( not l_standby_valid )
774            then
775               p_connstr1 := null;
776               return;
777            end if;
778         else
779            if ( not l_simulation_valid )
780            then
781               p_connstr1 := null;
782               return;
783            end if;
784         end if;
785      else
786         return;
787      end if;
788   end if;
789 
790 	-- Only allow supported program types.
791 
792   if ( not yn_to_boolean(p_cp_rec.Supported_Executable_Type) )
793   then
794      if ( l_known_adg_connection )
795      then
796         p_connstr1 := null;
797      end if;
798 
799      return;
800   end if;
801 
802 	-- Need to first run on primary before being a standby candidate.
803 
804   if ( not yn_to_boolean(p_cp_rec.Has_Run_On_Primary) )
805   then
806      if ( l_known_adg_connection )
807      then
808         p_connstr1 := null;
809      end if;
810 
811      return;
812   end if;
813 
814 	-- If connect string is known and not standby then must be simulated
815 	-- standby.
816 
817   if ( l_known_adg_connection and not l_standby_exists )
818   then
819      if ( not l_auto_valid ) -- use simulation only if auto-redirect not in effect
820      then
821         if ( l_simulation_valid )
822         then
823            p_connstr1 := l_simulation_connstr;
824         else
825            p_connstr1 := null;
826         end if;
827 
828         return;
829      end if;
830   end if;
831 
832 	-- Need to have run on simulated standby before real standby.
833 
834   if ( not yn_to_boolean(p_cp_rec.Has_Run_In_Simulated_Standby) )
835   then
836      	-- If auto simulation enabled and valid, then use simulation
837         -- connect string.
838 
839 	-- This will redirect for null and instance strings. It's not clear
840 	-- we really want this happen but we can just disable auto-simulation.
841 
842      if ( fnd_adg_utility.is_simulated_standby_enabled and
843           fnd_adg_utility.is_auto_simulation_enabled and l_simulation_valid )
844      then
845         p_connstr1 := l_simulation_connstr;
846         return;
847      end if;
848 
849      if ( l_known_adg_connection )
850      then
851         p_connstr1 := null;
852      end if;
853 
854      return;
855   end if;
856 
857 	-- If Run_On_Standby not set then return.
858 
859   if ( ynu_to_boolean(p_cp_rec.Run_On_Standby) is null or
860        not ynu_to_boolean(p_cp_rec.Run_On_Standby) )
861   then
862      if ( l_known_adg_connection )
863      then
864         p_connstr1 := null;
865      end if;
866 
867      return;
868   end if;
869 
870 	-- Ready to go - make sure manager is running for class id.
871 
872 	-- Does manager have to be running - can be put in queue for later.
873 
874   if ( fnd_adg_utility.is_enable_redirect_if_valid and
875        yn_to_boolean(p_cp_rec.always_redirect_if_valid) )
876   then
877      l_manager_must_be_running := false;
878   else
879      l_manager_must_be_running := true;
880   end if;
881 
882   if ( not l_auto_valid )
883   then
884      l_is_standby_mgr_defined :=
885                   fnd_adg_utility.is_standby_manager_defined
886                                       (l_mgr_stndby_req_class_app_id,
887                                        l_mgr_stndby_req_class_id,
888                                        l_manager_must_be_running);
889   else
890      l_is_standby_mgr_defined :=
891                   fnd_adg_utility.is_standby_manager_defined
892                                       (l_auto_stndby_req_class_app_id,
893                                        l_auto_stndby_req_class_id,
894                                        l_manager_must_be_running);
895   end if;
896 
897   if ( l_is_standby_mgr_defined )
898   then
899 
900 	-- Redirect to ADG manager.
901 
902 	-- Auto-redirection will not be valid if connstr was standby
903 
904      if ( not l_auto_valid )
905      then
906 
907         p_request_class_application_id := l_mgr_stndby_req_class_app_id;
908         p_concurrent_request_class_id  := l_mgr_stndby_req_class_id;
909 
910      else
911 
912         p_connstr1		       := l_auto_connstr1;
913         p_request_class_application_id := l_auto_stndby_req_class_app_id;
914         p_concurrent_request_class_id  := l_auto_stndby_req_class_id;
915 
916      end if;
917 
918      if ( p_nodename1 is not null )
919      then
920         p_nodename1 := null;  -- use class not node for standby control.
921      end if;
922 
923      return;
924 
925   else
926      if ( l_known_adg_connection )
927      then
928         p_connstr1 := null;
929      end if;
930 
931      return;
932   end if;
933 
934 end;
935 
936 /*==========================================================================*/
937 
938 	-- Private method - no access code check
939 
940 procedure do_handle_concurrent_program
941                        (p_application_id              number,
942                         p_concurrent_program_id       number,
943                         p_has_run_on_primary          boolean default null,
944                         p_has_run_on_simulated_standby boolean default null,
945                         p_run_on_standby              boolean default null,
946                         p_no_standby_failures         number default null,
947                         p_max_standby_failures        number default null,
948                         p_no_simulated_stdby_failures number default null,
949                         p_max_simulated_stdby_failures number default null,
950                         p_always_redirect_if_valid    boolean default null,
951                         p_use_automatic_redirection   boolean default null
952                        )
953 as
954 l_cp_chng_rec fnd_adg_concurrent_program%rowtype;
955 l_cp_rec fnd_adg_concurrent_program%rowtype;
956 begin
957 
958   l_cp_rec := get_conc_program_rec(p_application_id,
959                                    p_concurrent_program_id);
960 
961 	-- Does concurrent program exist
962 
963   if ( l_cp_rec.Application_Id is null and
964        l_cp_rec.Concurrent_Program_Id is null )
965   then
966      fnd_adg_exception.raise_error(
967                      fnd_adg_exception.C_SUPERR_INVALID_CONC_PROGRAM);
968   end if;
969 
970   l_cp_chng_rec := init_program_change_rec;
971 
972   l_cp_chng_rec.Has_Run_On_Primary       := boolean_to_yn(p_has_run_on_primary);
973   l_cp_chng_rec.Has_Run_In_Simulated_Standby  :=
974                                 boolean_to_yn(p_has_run_on_simulated_standby);
975 
976   if ( p_run_on_standby is not null )
977   then
978      l_cp_chng_rec.Run_On_Standby        := boolean_to_ynu(p_run_on_standby);
979   end if;
980 
981   l_cp_chng_rec.No_Standby_Failures           := p_no_standby_failures;
982   l_cp_chng_rec.Max_Standby_Failures          := p_max_standby_failures;
983   l_cp_chng_rec.No_Simulated_Standby_Failures := p_no_simulated_stdby_failures;
984   l_cp_chng_rec.Max_Simulated_Standby_Failures:= p_max_simulated_stdby_failures;
985 
986   l_cp_chng_rec.always_redirect_if_valid
987 				:= boolean_to_yn(p_always_redirect_if_valid);
988 
989   l_cp_chng_rec.use_automatic_redirection
990                                 := boolean_to_yn(p_use_automatic_redirection);
991 
992   if ( is_conc_program_changes(l_cp_chng_rec) )
993   then
994      update_conc_program_rec(l_cp_rec,l_cp_chng_rec,true);
995   end if;
996 
997 end;
998 
999 /*==========================================================================*/
1000 /*==================== Start of public methods =============================*/
1001 /*==========================================================================*/
1002 
1003 /*==========================================================================*/
1004 
1005 function is_standby return boolean
1006 as
1007 l_err number;
1008 l_msg varchar2(255);
1009 
1010 begin
1011 
1012   if ( G_IS_STANDBY is null )
1013   then
1014      set_is_standby;
1015 
1016 	-- check that we're using the right primary.
1017 
1018      if ( G_IS_STANDBY )
1019      then
1020 
1021 	-- validate will call back into is_standby. That's ok as G_IS_STANDBY
1022 	-- will be not null and this code path will not be reached.
1023 	-- Otherwise we'd recurse into oblivion...
1024 
1025         fnd_adg_manage.validate_standby_to_primary(l_err,l_msg,true);
1026 
1027         if ( l_err <> 0 )
1028         then
1029            G_IS_STANDBY := false;
1030 
1031            fnd_adg_exception.raise_error(
1032                            fnd_adg_exception.C_SUPERR_VALIDATE_PRIMARY,l_msg);
1033         end if;
1034 
1035         fnd_adg_manage.handle_rpc_debug(true);  -- enable debug trace.
1036 
1037      end if;
1038   end if;
1039 
1040   return G_IS_STANDBY;
1041 
1042 end;
1043 
1044 /*==========================================================================*/
1045 
1046 function is_true_standby return boolean
1047 as
1048 begin
1049 
1050   if ( G_IS_TRUE_STANDBY is null )
1051   then
1052      set_is_true_standby;
1053   end if;
1054 
1055   return G_IS_TRUE_STANDBY;
1056 
1057 end;
1058 
1059 /*==========================================================================*/
1060 
1061 function is_rpc_from_standby return boolean
1062 as
1063 begin
1064 
1065   return fnd_adg_manage.is_session_slave_to_standby;
1066 
1067 end;
1068 
1069 /*==========================================================================*/
1070 
1071 function is_primary return boolean
1072 as
1073 begin
1074 
1075   if ( G_IS_PRIMARY is null )
1076   then
1077      set_is_primary;
1078   end if;
1079 
1080   return G_IS_PRIMARY;
1081 
1082 end;
1083 
1084 /*==========================================================================*/
1085 
1086 procedure log_unhandled_exception(p_location varchar2,p_sqlerr varchar2)
1087 as
1088 begin
1089 
1090    dbms_system.ksdwrt(1,'ADGEBS: Unhandled Exception : ' ||p_location||
1091                           ' SQLERRM='||p_sqlerr);
1092 
1093    dbms_system.ksdwrt(1,'ADGEBS: Backtrace : ' ||p_location||LF||
1094                       dbms_utility.format_error_backtrace);
1095 
1096 end;
1097 
1098 /*==========================================================================*/
1099 
1100 function is_connstr_registered(p_connstr varchar2,
1101                                p_check_valid boolean default false,
1102                                p_check_available boolean default false)
1103                      return boolean
1104 as
1105 begin
1106 
1107   return fnd_adg_utility.is_connection_registered(p_connstr,p_check_valid,
1108                                                   p_check_available);
1109 
1110 end;
1111 
1112 /*==========================================================================*/
1113 
1114 function is_connstr_registered(p_connstr varchar2,
1115                                p_check_valid number,
1116                                p_check_available number)
1117                      return number
1118 as
1119 l_bool_check_valid boolean := false;
1120 l_bool_check_available boolean := false;
1121 begin
1122 
1123   if ( p_check_valid = 1 )
1124   then
1125      l_bool_check_valid := true;
1126   end if;
1127 
1128   if ( p_check_available = 1 )
1129   then
1130      l_bool_check_available := true;
1131   end if;
1132 
1133   if ( fnd_adg_utility.is_connection_registered(p_connstr,
1134                                                 l_bool_check_valid,
1135                                                 l_bool_check_available) )
1136   then
1137      return 1;
1138   else
1139      return 0;
1140   end if;
1141 
1142 end;
1143 
1144 /*==========================================================================*/
1145 
1146 procedure handle_request_row_change(p_is_inserting boolean,
1147                                     p_program_application_id number,
1148                                     p_concurrent_program_id number,
1149                                     p_connstr1 in out nocopy varchar2,
1150                                     p_nodename1 in out nocopy varchar2,
1151                                     p_request_class_application_id
1152                                                   in out nocopy number,
1153                                     p_concurrent_request_class_id
1154                                                   in out nocopy number,
1155                                     p_phase_code varchar2,
1156                                     p_status_code varchar2
1157                                    )
1158 as
1159 l_cp_chng_rec fnd_adg_concurrent_program%rowtype;
1160 l_cp_rec fnd_adg_concurrent_program%rowtype;
1161 l_cache_state boolean := null;
1162 begin
1163 
1164 	-- Use the control cache to avoid repeated reads.
1165 
1166   l_cache_state := fnd_adg_utility.enable_control_cache;
1167 
1168 	-- Always check state
1169 
1170   set_handle_request_row_change;
1171 
1172   if ( G_HANDLE_REQUEST_ROW_ALL or G_HANDLE_REQUEST_ROW_PRIMARY )
1173   then
1174      null;
1175   else
1176      fnd_adg_utility.disable_control_cache(l_cache_state);
1177      return;
1178   end if;
1179 
1180 	-- If someone tries to insert nulls we just ignore the row as
1181 	-- cols are defined as not null!
1182 
1183   if ( p_program_application_id is null or
1184        p_concurrent_program_id is null )
1185   then
1186      fnd_adg_utility.disable_control_cache(l_cache_state);
1187      return;
1188   end if;
1189 
1190   l_cp_rec := get_conc_program_rec(p_program_application_id,
1191                                    p_concurrent_program_id);
1192 
1193   if ( l_cp_rec.Application_Id is null and
1194        l_cp_rec.Concurrent_Program_Id is null ) -- concurrent program doesn't
1195                                                 -- exist - can't happen!
1196   then
1197      fnd_adg_utility.disable_control_cache(l_cache_state);
1198      return;
1199   end if;
1200 
1201 	-- Now the real processing starts.
1202 
1203   l_cp_chng_rec := init_program_change_rec;
1204 
1205   if ( p_is_inserting )
1206   then
1207      do_handle_request_row_insert(l_cp_rec,l_cp_chng_rec,
1208                                   p_connstr1, p_nodename1,
1209                                   p_request_class_application_id,
1210                                   p_concurrent_request_class_id);
1211   else
1212 
1213         -- If embedded then we need to calculate simulation errors now.
1214         -- Currently we only support standalone so this code path is
1215         -- never executed.
1216 
1217      if ( not is_standalone_executable(l_cp_rec) )
1218      then
1219         fnd_adg_utility.process_adg_violations(false,
1220                                                p_program_application_id,
1221                                                p_concurrent_program_id);
1222 
1223         l_cp_rec := get_conc_program_rec(p_program_application_id,
1224                                          p_concurrent_program_id);
1225      end if;
1226 
1227      do_handle_request_row_update(l_cp_rec,l_cp_chng_rec,
1228                                   p_connstr1,p_phase_code,p_status_code);
1229   end if;
1230 
1231   if ( is_conc_program_changes(l_cp_chng_rec) )
1232   then
1233      update_conc_program_rec(l_cp_rec,l_cp_chng_rec);
1234   end if;
1235 
1236   fnd_adg_utility.disable_control_cache(l_cache_state);
1237 
1238 exception
1239   when others then
1240        fnd_adg_utility.disable_control_cache(l_cache_state);
1241        raise;
1242 
1243 end;
1244 
1245 /*==========================================================================*/
1246 
1247 procedure handle_concurrent_program
1248                        (p_code                        number,
1249                         p_application_id              number,
1250                         p_concurrent_program_id       number,
1251                         p_has_run_on_primary          boolean default null,
1252                         p_has_run_on_simulated_standby boolean default null,
1253                         p_run_on_standby              boolean default null,
1254                         p_no_standby_failures         number default null,
1255                         p_max_standby_failures        number default null,
1256                         p_no_simulated_stdby_failures number default null,
1257                         p_max_simulated_stdby_failures number default null,
1258                         p_always_redirect_if_valid    boolean default null,
1259                         p_use_automatic_redirection   boolean default null
1260                        )
1261 as
1262 l_access_code number;
1263 l_cp_chng_rec fnd_adg_concurrent_program%rowtype;
1264 l_cp_rec fnd_adg_concurrent_program%rowtype;
1265 begin
1266 
1267   l_access_code := fnd_adg_utility.get_program_access_code;
1268 
1269   if ( p_code is null or l_access_code is null or p_code <> l_access_code )
1270   then
1271      fnd_adg_exception.raise_error(
1272                      fnd_adg_exception.C_SUPERR_PROGRAM_ACCESS_CODE);
1273   end if;
1274 
1275   do_handle_concurrent_program(p_application_id              ,
1276                                p_concurrent_program_id       ,
1277                                p_has_run_on_primary          ,
1278                                p_has_run_on_simulated_standby,
1279                                p_run_on_standby              ,
1280                                p_no_standby_failures         ,
1281                                p_max_standby_failures        ,
1282                                p_no_simulated_stdby_failures ,
1283                                p_max_simulated_stdby_failures,
1284                                p_always_redirect_if_valid,
1285                                p_use_automatic_redirection
1286                               );
1287 
1288 end;
1289 
1290 /*==========================================================================*/
1291 
1292 procedure handle_standby_error ( p_program_application_id number,
1293                                  p_concurrent_program_id number,
1294                                  p_simulation boolean,
1295                                  p_logoff boolean,
1296                                  p_error_count number)
1297 as
1298 l_cp_rec fnd_adg_concurrent_program%rowtype;
1299 l_run_on_standby boolean;
1300 l_No_Standby_Failures number;
1301 l_No_Simulated_Failures number;
1302 begin
1303 
1304   if ( p_program_application_id is null or p_concurrent_program_id is null or
1305        p_simulation is null or p_error_count is null or
1306        p_error_count <= 0 or p_logoff is null )
1307   then
1308      return;
1309   end if;
1310 
1311 	-- All the error checking has already taken place so
1312 	-- just update the run flag.
1313 
1314   l_run_on_standby := null;
1315   l_No_Standby_Failures := null;
1316   l_No_Simulated_Failures := null;
1317 
1318   l_cp_rec := get_conc_program_rec(p_program_application_id,
1319                                    p_concurrent_program_id);
1320 
1321   if ( not p_simulation )
1322   then
1323      l_No_Standby_Failures := l_cp_rec.No_Standby_Failures + p_error_count;
1324 
1325      if ( l_No_Standby_Failures >= l_cp_rec.Max_Standby_Failures )
1326      then
1327         l_run_on_standby := false;
1328      end if;
1329   else
1330      if ( ( is_standalone_executable(l_cp_rec) and p_logoff ) or
1331           ( not is_standalone_executable(l_cp_rec) and not p_logoff ) )
1332      then
1333         l_No_Simulated_Failures :=
1334                   l_cp_rec.No_Simulated_Standby_Failures + p_error_count;
1335      end if;
1336   end if;
1337 
1338   do_handle_concurrent_program
1339                   (
1340                     p_application_id       => p_program_application_id,
1341                     p_concurrent_program_id=> p_concurrent_program_id,
1342                     p_run_on_standby       => l_run_on_standby,
1343                     p_No_Standby_Failures  => l_No_Standby_Failures,
1344                     p_no_simulated_stdby_failures =>
1345                                        l_No_Simulated_Failures
1346                   );
1347 
1348 exception
1349   when others then
1350        null;  -- called from error handler so nothing we can do!
1351 
1352 end;
1353 
1354 /*==========================================================================*/
1355 
1356 	-- This entry point is only valid outside of trigger code
1357 	-- due to mutating errors.
1358 
1359 procedure handle_standby_error ( p_request_id number,
1360                                  p_simulation boolean,
1361                                  p_logoff boolean,
1362                                  p_error_count number)
1363 as
1364 cursor c1 is select R.Program_APPLICATION_ID,R.CONCURRENT_PROGRAM_ID
1365                from FND_CONCURRENT_REQUESTS r
1366               where R.request_id = p_request_id;
1367 begin
1368 
1369   if ( p_request_id is null )
1370   then
1371      return;
1372   end if;
1373 
1374   for f_rec in c1 loop
1375 
1376       handle_standby_error(f_rec.Program_APPLICATION_ID,
1377                            f_rec.CONCURRENT_PROGRAM_ID,
1378                            p_simulation,
1379                            p_logoff,
1380                            p_error_count);
1381 
1382       exit;
1383 
1384   end loop;
1385 
1386 exception
1387   when others then
1388        null;  -- called from error handler so nothing we can do!
1389 
1390 end;
1391 
1392 /*==========================================================================*/
1393 
1394 begin
1395   null;
1396 end fnd_adg_support;