Rem drv:
Rem
Rem $Header: notification_pkgbodys.sql 18-jul-2007.18:39:38 minfan Exp $
Rem
Rem notification_pkgbodys.sql
Rem
Rem Copyright (c) 2002, 2007, Oracle. All rights reserved.
Rem
Rem NAME
Rem notification_pkgbodys.sql
Rem
Rem DESCRIPTION
Rem This is the implementation of the Notification Manager for
Rem Oracle Enterprise Manager
Rem NOTES
Rem The Notification Manager is implemented using one DBMS JOB that calls
Rem the CHECK_FOR_SEVERITIES procedure and another that calls the
Rem CHECK_FOR_JOBS procedure. This procedures check for new notification
Rem source events, match rules to them and queues notifications that are
Rem delivered by one or more OMSs
Rem
Rem RCA: for 10gR2 RCA tasks are added to the set of notification tasks
Rem handled by this subsystem. If the overhead of handling these
Rem tasks impacts notifications adversely then they should be removed.
Rem
Rem MODIFIED (MM/DD/YY)
Rem minfan 07/18/07 - bug 6260471
Rem denath 06/27/07 - Fix 5983944.proc ping devices modified for
Rem checking device in ping status along with down
Rem status and create a ping notification.
Rem neearora 07/13/07 - Bug 6122386
Rem denath 07/05/07 - Bug fix 6082882.modified
Rem queue_metric_notification. passed
Rem violation.target_guid to devices cursor and use
Rem in place of c.target_guid while joining with
Rem MGMT_METRICS_COMPOSITE_KEYS.target_guid for
Rem wildcard key value metrics to get picked up.
Rem neearora 06/21/07 - added validations in set_rule_repeat
Rem neearora 06/20/07 - bug 6142074
Rem minfan 06/15/07 - backport of bug 5852652
Rem shnavane 04/06/07 - Fix bug #5850762
Rem shnavane 06/13/07 - Backport shnavane_bug-5850762 from main
Rem neearora 06/09/07 - bug 6122386
Rem neearora 05/26/07 - bug 6067642
Rem neearora 05/03/07 - added API to get set global repeat settings
Rem smalathe 04/23/07 - Bug 5881705: Add a debug message
Rem neearora 03/27/07 - added procedure QUEUE_NOTIF_INPUT
Rem denath 07/26/06 - Fix Bug 5383506.Added check for policy violation
Rem warning and information notifiications to be
Rem sent in queue_metric_notifications.
Rem denath 03/18/07 - Backport denath_bug-5383506 from main
Rem neearora 06/24/06 - bug 5045575. Modify GET_JOB_STATE_CHANGE_DETAILS
Rem to select target on the basis of execution id
Rem neearora 07/20/06 - Backport neearora_bug-5045575 from main
Rem rmaggarw 06/25/06 - bug5347519: sort by checkuser
Rem rmaggarw 07/10/06 - Backport rmaggarw_bug-5347519 from main
Rem neearora 10/21/05 - Added support for java notifications
Rem neearora 10/21/05 - Added support for java notifications
Rem rmaggarw 11/28/05 - use this_date instead of sysdate in
Rem check_for_severities
Rem rmaggarw 12/05/05 - Backport rmaggarw_bug-4764102 from main
Rem dcawley 11/25/05 - Backport dcawley_bug-4607171 from main
Rem dcawley 09/13/05 - Default job type
Rem dcawley 11/25/05 - Backport dcawley_bug-4602660 from main
Rem dcawley 10/17/05 - Change summary message
Rem dcawley 11/25/05 - Remove check for OMS
Rem dcawley 09/24/05 - Remove plsql check when queuing
Rem dcawley 09/09/05 - Improve performance of rule matching
Rem dcawley 08/31/05 - Get job type label
Rem dcawley 08/05/05 - Use metric name for CAs not label
Rem dcawley 08/04/05 - Include occurred timestamp for jobs and cas
Rem dcawley 08/04/05 - Add logging
Rem dcawley 08/03/05 - Fix index for getting keys
Rem rmaggarw 07/29/05 - remove commit from failover
Rem dcawley 07/13/05 - Add callback for cleaning up keys
Rem smalathe 07/13/05 - Bug4487356: Use Select count
Rem scgrover 07/07/05 - add extended sql trace
Rem gsbhatia 07/01/05 - New repmgr header impl
Rem gsbhatia 06/26/05 - New repmgr header impl
Rem dcawley 06/30/05 - Include aborted state for ca
Rem dcawley 06/21/05 - Change annotation for ca
Rem dcawley 06/16/05 - Do not include rca in summary
Rem dcawley 04/04/05 - Fix sql injection problems
Rem dcawley 03/24/05 - Set additional gateway parameters
Rem dcawley 03/24/05 - Sepcify escape character for rule matching
Rem dcawley 03/22/05 - Fix cleanup
Rem dcawley 03/15/05 - Support wild cards for composites
Rem jriel 03/15/05 - queue rca task with normal type
Rem dcawley 03/10/05 - Reorder columns
Rem pkantawa 03/09/05 - exclude jobs in delete pending state
Rem dcawley 02/24/05 - Increase queue name size
Rem dcawley 02/24/05 - Change get repository owner
Rem dcawley 02/24/05 - Fix timezone problem when logging delivery times
Rem gsbhatia 02/13/05 - updating repmgr header
Rem rzazueta 02/04/05 - Prepend queue_name with schema name
Rem gsbhatia 02/07/05 - updating repmgr header
Rem ramalhot 02/02/05 - changed signature for handle_target_deleted
Rem dcawley 01/28/05 - Use policy name
Rem dcawley 01/11/05 - Allow registration without e-mail addresses
Rem ktlaw 01/11/05 - add repmgr header
Rem dcawley 01/11/05 - Rename callback
Rem dcawley 01/06/05 - Add target deletion callback
Rem dcawley 01/10/05 - Upper case job details
Rem dcawley 01/05/05 - Fix test routine for plsql method
Rem dcawley 12/22/04 - Truncate minutes when checking schedule
Rem dcawley 12/20/04 - Catch errors with timezone
Rem dcawley 12/20/04 - Fix rule for rca
Rem dcawley 12/16/04 - Add RCA notification type
Rem dcawley 12/14/04 - Include policy flags when matching rules
Rem dcawley 12/09/04 - Change annotation values
Rem dcawley 12/07/04 - Delete job configs
Rem jriel 11/18/04 - don't filter RCA during cleanup
Rem dcawley 11/16/04 - Pass back nlsid for violation details
Rem dcawley 10/28/04 - Cleanup old administrative messages
Rem dcawley 10/27/04 - Add api for deleting a specific configuration
Rem jriel 10/11/04 - only handle new severities
Rem dcawley 10/11/04 - RCA changes to rule
Rem jriel 09/28/04 - add proc to queue rca directly
Rem dcawley 09/27/04 - Queue corrective action
Rem dcawley 09/15/04 - Switch to violations table
Rem dcawley 09/01/04 - Use job status buckets
Rem jriel 08/31/04 - add target guid to notification for RCA
Rem dcawley 08/19/04 - Register OS of OMS
Rem dcawley 08/11/04 - Do not notify user's without target priv
Rem jriel 08/06/04 - add queue rca
Rem jriel 07/20/04 - add RCA
Rem dcawley 07/22/04 - Allow states per metric
Rem dcawley 07/21/04 - Change target table for jobs
Rem dcawley 07/15/04 - Add corrective actions
Rem dcawley 07/12/04 - Add procedure for getting job state details
Rem dcawley 07/07/04 - Increase user name size
Rem dcawley 06/29/04 - Remove tracing
Rem dcawley 06/14/04 - Changes for 10gR2
Rem aholser 05/13/04 - enable method performance logging
Rem dcawley 04/15/04 - remove send mail
Rem dcawley 03/25/04 - Add timezone to schedule
Rem yaofeng 02/07/04 - device name length
Rem yaofeng 02/05/04 - use target name
Rem dcawley 01/27/04 - Fix schedule for when Sunday is first day
Rem dcawley 01/26/04 - Log problems with metric versioning
Rem dcawley 12/19/03 - Remove retry recirds
Rem dcawley 11/25/03 - Do not send emails when there is no schedule
Rem yaofeng 11/12/03 - show date in NLS format
Rem yaofeng 11/11/03 - don't use . *
Rem dcawley 10/16/03 - Fix host label lookup
Rem dcawley 09/25/03 - Add key column name
Rem dcawley 09/18/03 - Add key value guid for plsql notifications
Rem dcawley 09/08/03 - Use timezone_region
Rem dcawley 09/03/03 - Annotations should be target timezone
Rem dcawley 08/27/03 - Use upper case for schedule owner
Rem dcawley 08/27/03 - Clear old parameters when editing a command
Rem rpinnama 07/25/03 -
Rem rpinnama 07/25/03 - Move queue initialization to post_creation
Rem dcawley 07/23/03 - Log device specific delivery times
Rem dcawley 07/18/03 - Change annotations
Rem dcawley 07/09/03 - Move queue initialization
Rem dcawley 06/26/03 - Add UNREGISTER_OMS
Rem dcawley 06/25/03 - Check for missing guids
Rem dcawley 05/21/03 - Update for moving delivery to OMS
Rem
CREATE OR REPLACE PACKAGE BODY EMD_NOTIFICATION
IS
-- Queues sizes, these are read from MGMT_PARAMETERS
NUM_EMAIL_QUEUES number := DEFAULT_NOTIFY_EMAIL_QUEUES;
NUM_OSCMD_QUEUES number := DEFAULT_NOTIFY_OSCMD_QUEUES;
NUM_PLSQL_QUEUES number := DEFAULT_NOTIFY_PLSQL_QUEUES;
NUM_SNMP_QUEUES number := DEFAULT_NOTIFY_SNMP_QUEUES;
NUM_RCA_QUEUES number := DEFAULT_NOTIFY_RCA_QUEUES;
NUM_JAVA_QUEUES number := DEFAULT_NOTIFY_JAVA_QUEUES;
G_DEV_PING_STATE_TIMEOUT number := DEF_DEV_PING_STATE_TIMEOUT;
-- A cache of device availability. Entries are of the form:
--
AVAILABLE_DEVICES SMP_EMD_STRING_ARRAY := SMP_EMD_STRING_ARRAY();
UNAVAILABLE_DEVICES SMP_EMD_STRING_ARRAY := SMP_EMD_STRING_ARRAY();
-- Work out what monday is using a well known data, so schedule starts
-- can be calculated
MONDAY NUMBER := TO_CHAR(TO_DATE('05-01-2004', 'dd-mm-yyyy'), 'D');
-- Performance data
NUM_EMAILS_QUEUED number := 0;
NUM_OSCMDS_QUEUED number := 0;
NUM_PLSQLS_QUEUED number := 0;
NUM_SNMPS_QUEUED number := 0;
NUM_JAVA_QUEUED number := 0;
TOTAL_ENQUEUE_TIME number := 0;
NUM_JOB_EMAILS_QUEUED number := 0;
NUM_JOB_OSCMDS_QUEUED number := 0;
NUM_JOB_PLSQLS_QUEUED number := 0;
NUM_JOB_SNMPS_QUEUED number := 0;
NUM_JOB_JAVA_QUEUED number := 0;
NUM_RCAS_QUEUED number := 0;
TOTAL_JOB_ENQUEUE_TIME number := 0;
OLDERR number := 0;
OLDERRTIME DATE;
G_RECURSIVE_CLEANUP BOOLEAN := FALSE;
-- Repository owner
G_REPOSITORY_OWNER VARCHAR2(30) := NULL;
G_QUEUE_NAME VARCHAR2(50) := NULL;
G_NOTIFY_INPUT_Q_NAME VARCHAR2(50) := NULL;
-- Logging context
G_LOG_CONTEXT VARCHAR2(15) := 'NOTIFICATION';
-- The escape character for matching strings in rules
G_ESC VARCHAR2(1) := '\';
FUNCTION GET_MILLISEC_FROM_INTERVAL(i INTERVAL DAY TO SECOND)
RETURN NUMBER
IS
duration_sec NUMBER;
BEGIN
duration_sec := (extract (day from i)) * 24 * 60 * 60 +
(extract (hour from i)) * 60 * 60 +
(extract (minute from i)) * 60 +
(extract (second from i));
return duration_sec * 1000;
END GET_MILLISEC_FROM_INTERVAL;
FUNCTION IS_WINDOWS_PROGRAM(v_program IN VARCHAR2)
RETURN BOOLEAN
IS
l_program VARCHAR2(512);
BEGIN
l_program := UPPER(v_program);
-- Check if this is a Windows program
IF INSTR(l_program, '\') > 0 OR
SUBSTR(l_program, 2, 1) = ':' OR
INSTR(l_program, '.BAT') > 0 OR
INSTR(l_program, '.CMD') > 0 OR
INSTR(l_program, '.EXE') > 0
THEN
RETURN TRUE;
END IF;
RETURN FALSE;
END IS_WINDOWS_PROGRAM;
-- PURPOSE
-- Procedure to set a configuration value
PROCEDURE SET_CONFIG_VALUE(p_name IN VARCHAR2, p_value IN VARCHAR2)
IS
BEGIN
UPDATE mgmt_parameters
SET parameter_value = p_value
WHERE parameter_name = p_name;
IF (SQL%ROWCOUNT = 0) THEN
INSERT INTO mgmt_parameters (parameter_name, parameter_value)
VALUES (p_name, p_value);
END IF;
END SET_CONFIG_VALUE;
-- PURPOSE
-- Function to check the availabilty of a device based on its notification
-- schedule
FUNCTION DEVICE_AVAILABLE(v_device_name IN VARCHAR2,
v_profile_name IN VARCHAR2,
v_time_to_check IN DATE DEFAULT SYSDATE)
RETURN BOOLEAN
IS
dev_type NUMBER;
sd DATE;
disable_s DATE;
disable_e DATE;
num_wks NUMBER := 1;
hour NUMBER;
day NUMBER;
adj_hour NUMBER;
available VARCHAR2(1);
log_msg VARCHAR2(512);
cache_entry VARCHAR2(256);
timezone_rgn VARCHAR2(64);
adj_time_to_check DATE := v_time_to_check;
BEGIN
-- Do not check schedule for non-email devices
BEGIN
SELECT type INTO dev_type FROM MGMT_NOTIFY_DEVICES
WHERE device_name = v_device_name AND
profile_name = v_profile_name;
IF dev_type <> LONG_EMAIL_DEVICE_TYPE AND
dev_type <> SHORT_EMAIL_DEVICE_TYPE
THEN
RETURN TRUE;
END IF;
EXCEPTION
WHEN NO_DATA_FOUND
THEN
-- No device found so return false
RETURN FALSE;
END;
-- Check the cache
BEGIN
SELECT column_value INTO cache_entry FROM
TABLE(CAST(AVAILABLE_DEVICES AS SMP_EMD_STRING_ARRAY))
WHERE column_value = v_device_name || v_profile_name;
RETURN TRUE;
EXCEPTION WHEN NO_DATA_FOUND
THEN
BEGIN
SELECT column_value INTO cache_entry FROM
TABLE(CAST(UNAVAILABLE_DEVICES AS SMP_EMD_STRING_ARRAY))
WHERE column_value = v_device_name || v_profile_name;
RETURN FALSE;
EXCEPTION WHEN NO_DATA_FOUND
THEN
-- this is the first time checking this device's schedule
NULL;
END;
END;
-- Get the start date, length and disable dates of the user's schedule
BEGIN
SELECT start_date, num_weeks, disable_start, disable_end, timezone_region
INTO sd, num_wks, disable_s, disable_e, timezone_rgn
FROM MGMT_NOTIFY_SCHEDULES
WHERE schedule_owner = v_profile_name
AND schedule_name = ' ';
EXCEPTION
WHEN NO_DATA_FOUND
THEN
-- No schedule found so return false
RETURN FALSE;
END;
-- Adjust the time to check based on the user's timezone
adj_time_to_check := MGMT_GLOBAL.ADJUST_TZ(v_time_to_check,
TO_CHAR(SYSTIMESTAMP,'TZR'),
timezone_rgn);
-- Make sure we are after the start date
IF adj_time_to_check < sd
THEN
UNAVAILABLE_DEVICES.EXTEND;
UNAVAILABLE_DEVICES(UNAVAILABLE_DEVICES.COUNT) := v_device_name ||
v_profile_name;
RETURN FALSE;
END IF;
-- Make sure the schedule is not disabled
IF SYSDATE >= disable_s AND SYSDATE <= disable_e
THEN
UNAVAILABLE_DEVICES.EXTEND;
UNAVAILABLE_DEVICES(UNAVAILABLE_DEVICES.COUNT) := v_device_name ||
v_profile_name;
RETURN FALSE;
END IF;
-- Get the day of the start date. Note Sunday is 1, Monday 2 etc. The UI
-- always shows Monday as the first day even if the start date happens to
-- be a Tuesday. So the effective start date of a schedule is the preceeding
-- Monday since the first 24 characters of the schedule array in
-- MGMT_NOTIFY_DEV_SCHEDULES will be for the Monday
day := TO_CHAR(sd, 'D');
IF day >= MONDAY
THEN
sd := sd - (day - MONDAY);
ELSE
sd := sd - (7 - (MONDAY - day));
END IF;
-- Remove the minutes from the time to check to avoid any rounding errors
adj_time_to_check := TRUNC(adj_time_to_check, 'HH');
-- Get the hour
hour := ROUND((adj_time_to_check - sd) * 24);
-- If the current hour is greater than the number of hours in the schedule
IF hour > (num_wks * 7 * 24)
THEN
adj_hour := mod(hour, (num_wks * 7 * 24)) + 1;
ELSE
adj_hour := hour + 1;
END IF;
BEGIN
-- Check the schedule for the device
SELECT SUBSTR(schedule, adj_hour, 1) INTO available
FROM MGMT_NOTIFY_DEV_SCHEDULES
WHERE schedule_owner = v_profile_name
AND schedule_name = ' '
AND device_name = v_device_name
AND device_owner = v_profile_name;
IF available = 'Y'
THEN
AVAILABLE_DEVICES.EXTEND;
AVAILABLE_DEVICES(AVAILABLE_DEVICES.COUNT) := v_device_name ||
v_profile_name;
RETURN TRUE;
ELSE
UNAVAILABLE_DEVICES.EXTEND;
UNAVAILABLE_DEVICES(UNAVAILABLE_DEVICES.COUNT) := v_device_name ||
v_profile_name;
RETURN FALSE;
END IF;
EXCEPTION
WHEN NO_DATA_FOUND
THEN
-- This device does not exist in the schedule
UNAVAILABLE_DEVICES.EXTEND;
UNAVAILABLE_DEVICES(UNAVAILABLE_DEVICES.COUNT) := v_device_name ||
v_profile_name;
RETURN FALSE;
END;
END DEVICE_AVAILABLE;
-- PURPOSE
-- Function used for testing DEVICE_AVAILABLE
FUNCTION IS_DEVICE_AVAILABLE(v_device_name IN VARCHAR2,
v_profile_name IN VARCHAR2,
v_time_to_check IN DATE)
RETURN BOOLEAN
IS
BEGIN
UNAVAILABLE_DEVICES := SMP_EMD_STRING_ARRAY();
AVAILABLE_DEVICES := SMP_EMD_STRING_ARRAY();
RETURN DEVICE_AVAILABLE(v_device_name, UPPER(v_profile_name),
v_time_to_check);
END IS_DEVICE_AVAILABLE;
-- PURPOSE
-- Function to read a configuration value
FUNCTION GET_CONFIG_VALUE(pname IN VARCHAR2, default_value IN VARCHAR2)
RETURN VARCHAR2
IS
value VARCHAR2(256);
BEGIN
SELECT parameter_value INTO value FROM MGMT_PARAMETERS
WHERE parameter_name = pname;
RETURN value;
EXCEPTION
WHEN NO_DATA_FOUND
THEN
RETURN default_value;
END GET_CONFIG_VALUE;
-- PURPOSE
-- To initialize the queue table and get the number of queues which
-- can be using in mapping user/object combinations to a queue
--
-- NOTES
-- The number of queues remains fixed once they have been initialized. To
-- modify the number of queues, the SET_NUMBER_QUEUES procedure must be
-- called which results in the temporary disabling of the queues while
--- reassignment tables place
PROCEDURE INITIALIZE_QUEUES
IS
BEGIN
-- Get the number of queues
SELECT COUNT(qname) INTO NUM_EMAIL_QUEUES FROM MGMT_NOTIFY_QUEUES
WHERE qname LIKE 'EMAIL%';
IF NUM_EMAIL_QUEUES = 0
THEN
NUM_EMAIL_QUEUES := GET_CONFIG_VALUE(NOTIFY_EMAIL_QUEUES,
DEFAULT_NOTIFY_EMAIL_QUEUES);
-- Insert the queue names
FOR i IN 1..NUM_EMAIL_QUEUES
LOOP
INSERT INTO MGMT_NOTIFY_QUEUES (qname) VALUES ('EMAIL' || i);
END LOOP;
END IF;
SELECT COUNT(qname) INTO NUM_OSCMD_QUEUES FROM MGMT_NOTIFY_QUEUES
WHERE qname LIKE 'OSCMD%';
IF NUM_OSCMD_QUEUES = 0
THEN
NUM_OSCMD_QUEUES := GET_CONFIG_VALUE(NOTIFY_OSCMD_QUEUES,
DEFAULT_NOTIFY_OSCMD_QUEUES);
FOR i IN 1..NUM_OSCMD_QUEUES
LOOP
INSERT INTO MGMT_NOTIFY_QUEUES (qname) VALUES ('OSCMD' || i);
END LOOP;
END IF;
SELECT COUNT(qname) INTO NUM_PLSQL_QUEUES FROM MGMT_NOTIFY_QUEUES
WHERE qname LIKE 'PLSQL%';
IF NUM_PLSQL_QUEUES = 0
THEN
NUM_PLSQL_QUEUES := GET_CONFIG_VALUE(NOTIFY_PLSQL_QUEUES,
DEFAULT_NOTIFY_PLSQL_QUEUES);
FOR i IN 1..NUM_PLSQL_QUEUES
LOOP
INSERT INTO MGMT_NOTIFY_QUEUES (qname) VALUES ('PLSQL' || i);
END LOOP;
END IF;
SELECT COUNT(qname) INTO NUM_SNMP_QUEUES FROM MGMT_NOTIFY_QUEUES
WHERE qname LIKE 'SNMP%';
IF NUM_SNMP_QUEUES = 0
THEN
NUM_SNMP_QUEUES := GET_CONFIG_VALUE(NOTIFY_SNMP_QUEUES,
DEFAULT_NOTIFY_SNMP_QUEUES);
FOR i IN 1..NUM_SNMP_QUEUES
LOOP
INSERT INTO MGMT_NOTIFY_QUEUES (qname) VALUES ('SNMP' || i);
END LOOP;
END IF;
SELECT COUNT(qname) INTO NUM_JAVA_QUEUES FROM MGMT_NOTIFY_QUEUES
WHERE qname LIKE 'JAVA%';
IF NUM_JAVA_QUEUES = 0
THEN
NUM_JAVA_QUEUES := GET_CONFIG_VALUE(NOTIFY_JAVA_QUEUES,
DEFAULT_NOTIFY_JAVA_QUEUES);
FOR i IN 1..NUM_JAVA_QUEUES
LOOP
INSERT INTO MGMT_NOTIFY_QUEUES (qname) VALUES ('JAVA' || i);
END LOOP;
END IF;
-- for 10gR2 RCA will only support a single queue. This is due to the fact
-- that RCA tasks may have to be synchronized under some circumstances and
-- there is not support to do this in 10gR2 across OMSs, so a single RCA
-- queue forces all tasks to run on a single OMS
SELECT COUNT(qname) INTO NUM_RCA_QUEUES FROM MGMT_NOTIFY_QUEUES
WHERE qname LIKE 'RCA%';
IF NUM_RCA_QUEUES = 0
THEN
NUM_RCA_QUEUES := GET_CONFIG_VALUE(NUM_RCA_QUEUES,
DEFAULT_NOTIFY_RCA_QUEUES);
FOR i IN 1..NUM_RCA_QUEUES
LOOP
INSERT INTO MGMT_NOTIFY_QUEUES (qname) VALUES ('RCA' || i);
END LOOP;
END IF;
COMMIT;
END INITIALIZE_QUEUES;
-- PURPOSE
-- To get the name of a queue to which the notification will be assigned
--
-- NOTES
-- Queueing is done based on the user and object GUID (target, policy or job)
-- of the notification. Queues have a name of the form:
--
--
--
-- where device-type is EMAIL, OSCMD, SNMP or PLSQL and number is the queue
-- number which is based on values defined in MGMT_PARAMETERS for queue
-- sizes
FUNCTION GET_QUEUE(device_type_in IN NUMBER, device_owner_in IN VARCHAR2,
source_guid_in IN RAW)
RETURN VARCHAR2
IS
qname VARCHAR2(30);
qnumber NUMBER := 0;
windows_os_qs SMP_EMD_STRING_ARRAY := SMP_EMD_STRING_ARRAY();
BEGIN
-- Check the device type so the start of the qname can be set
IF device_type_in IN (EMAIL_DEVICE_TYPE, LONG_EMAIL_DEVICE_TYPE,
SHORT_EMAIL_DEVICE_TYPE)
THEN
-- Get the hash of the user and source_guid
qnumber := DBMS_UTILITY.GET_HASH_VALUE(device_owner_in || source_guid_in,
1, NUM_EMAIL_QUEUES);
RETURN 'EMAIL' || qnumber;
ELSIF device_type_in = PROGRAM_DEVICE_TYPE
THEN
-- Get the hash of the user and source_guid
qnumber := DBMS_UTILITY.GET_HASH_VALUE(device_owner_in || source_guid_in,
1, NUM_OSCMD_QUEUES);
RETURN 'OSCMD' || qnumber;
ELSIF device_type_in = WINDOWS_PROGRAM_DEVICE_TYPE
THEN
SELECT qname BULK COLLECT INTO windows_os_qs
FROM MGMT_NOTIFY_QUEUES
WHERE qname LIKE 'OSCMD%' AND windows = 1;
IF windows_os_qs IS NULL OR windows_os_qs.COUNT = 0
THEN
RETURN NULL;
END IF;
-- Get the hash of the user and source_guid
qnumber := DBMS_UTILITY.GET_HASH_VALUE(device_owner_in || source_guid_in,
1, windows_os_qs.COUNT);
RETURN windows_os_qs(qnumber);
ELSIF device_type_in = PLSQL_DEVICE_TYPE
THEN
-- Get the hash of the user and source_guid
qnumber := DBMS_UTILITY.GET_HASH_VALUE(device_owner_in || source_guid_in,
1, NUM_PLSQL_QUEUES);
RETURN 'PLSQL' || qnumber;
ELSIF device_type_in = SNMP_DEVICE_TYPE
THEN
-- Get the hash of the user and source_guid
qnumber := DBMS_UTILITY.GET_HASH_VALUE(device_owner_in || source_guid_in,
1, NUM_SNMP_QUEUES);
RETURN 'SNMP' || qnumber;
ELSIF device_type_in = RCA_DEVICE_TYPE
THEN
-- Get the hash of the user and source_guid
qnumber := DBMS_UTILITY.GET_HASH_VALUE(device_owner_in || source_guid_in,
1, NUM_RCA_QUEUES);
RETURN 'RCA' || qnumber;
ELSIF device_type_in = JAVA_DEVICE_TYPE
THEN
-- Get the hash of the user and source_guid
qnumber := DBMS_UTILITY.GET_HASH_VALUE(device_owner_in || source_guid_in,
1, NUM_JAVA_QUEUES);
RETURN 'JAVA' || qnumber;
END IF;
RETURN NULL;
END GET_QUEUE;
-- PURPOSE
-- Procedure to queue a notification.
--
-- NOTES
--
PROCEDURE QUEUE(qname_in IN VARCHAR2,
notification_in IN MGMT_NOTIFY_NOTIFICATION)
IS
enq_options dbms_aq.enqueue_options_t;
qMsg_properties dbms_aq.message_properties_t;
qMsg_handle RAW(16);
recipient sys.aq$_agent;
BEGIN
-- Set up the qname as the recipient name
recipient := sys.aq$_agent(qname_in, NULL, 0);
qMsg_properties.recipient_list(1) := recipient;
-- Add the message to the queue
DBMS_AQ.ENQUEUE(queue_name => G_QUEUE_NAME,
enqueue_options => enq_options,
message_properties => qMsg_properties,
payload => notification_in,
msgid => qMsg_handle);
EXCEPTION
WHEN OTHERS
THEN
mgmt_log.log_error(EMD_NOTIFICATION.CHECK_MODULE_NAME,
MGMT_GLOBAL.UNEXPECTED_ERR,
MGMT_GLOBAL.UNEXPECTED_ERR_M ||
'QUEUE('
|| qname_in || '/' || notification_in.device_name ||
'/' || notification_in.device_owner || ') ' ||
SQLERRM, 'ORA', notification_in.source_guid);
END QUEUE;
PROCEDURE QUEUE_READY(qnames_in IN SMP_EMD_STRING_ARRAY,
qtimeout_in IN NUMBER,
qname_out OUT VARCHAR2)
IS
agents dbms_aq.aq$_agent_list_t;
agent sys.aq$_agent;
BEGIN
-- in standalone mode where is no dbms job to process the data
-- of MGMT_NOTIFY_INPUT_Q. calling CHECK_FOR_SEVERITIES from
-- listen call to process repeat notifications.
IF (EMD_MAINTENANCE.IS_CENTRAL_MODE = 0)
THEN
CHECK_FOR_SEVERITIES();
END IF;
FOR i IN qnames_in.FIRST..qnames_in.LAST
LOOP
agents(i) := sys.aq$_agent(qnames_in(i), G_QUEUE_NAME, 0);
END LOOP;
-- This raises an ORA-25254 exception if there is nothing in the queue
DBMS_AQ.LISTEN (agents, qtimeout_in, agent);
qname_out := agent.name;
END QUEUE_READY;
PROCEDURE DEQUEUE(qname_in IN VARCHAR2,
qtimeout_in IN NUMBER,
qmsg_id_out OUT RAW,
notification_out OUT MGMT_NOTIFY_NOTIFICATION)
IS
dq_options dbms_aq.dequeue_options_t;
qMsg_properties dbms_aq.message_properties_t;
BEGIN
dq_options.consumer_name := qname_in;
dq_options.wait := qtimeout_in;
dq_options.navigation := DBMS_AQ.FIRST_MESSAGE;
-- Dequeue a notification
DBMS_AQ.DEQUEUE(queue_name => G_QUEUE_NAME,
dequeue_options => dq_options,
message_properties => qMsg_properties,
payload => notification_out,
msgid => qmsg_id_out);
END DEQUEUE;
-- PURPOSE
-- Procedure to queue an RCA update task
-- NOTE: this is used during regression runs only!!
--
PROCEDURE QUEUE_RCA_TASK(target_guid_in IN RAW,
severity_guid_in IN RAW,
rca_type_in IN NUMBER,
rca_mode_in IN VARCHAR2)
IS
qMsg_properties dbms_aq.message_properties_t;
qMsg MGMT_NOTIFY_NOTIFICATION;
qname VARCHAR2(30);
BEGIN
qname := GET_QUEUE(RCA_DEVICE_TYPE,
'RCA',
target_guid_in);
qMsg := MGMT_NOTIFY_NOTIFICATION(NORMAL_NOTIFICATION,
IS_NOT_PING,
rca_type_in,
severity_guid_in,
'RCA',
'RCA',
RCA_DEVICE_TYPE,
rca_mode_in,
RAWTOHEX(target_guid_in),
qname,
0);
QUEUE(qname, qMsg);
END QUEUE_RCA_TASK;
-- PURPOSE
-- Procedure to queue an RCA update task
--
PROCEDURE QUEUE_RCA_UPDATE(target_guid_in IN RAW,
severity_guid_in IN RAW,
event_guid_in IN RAW,
delay_in IN NUMBER)
IS
qMsg_properties dbms_aq.message_properties_t;
qMsg MGMT_NOTIFY_NOTIFICATION;
qname VARCHAR2(30);
rca_type VARCHAR2(30);
BEGIN
qname := GET_QUEUE(RCA_DEVICE_TYPE,
'RCA',
target_guid_in);
IF delay_in = 0 THEN
rca_type := 'RCA_IMMEDIATE';
ELSE
rca_type := 'RCA_NORMAL';
END IF;
IF severity_guid_in IS NULL
THEN
qMsg := MGMT_NOTIFY_NOTIFICATION(NORMAL_NOTIFICATION,
IS_NOT_PING,
RCA_RETRY_EVENT,
event_guid_in,
'RCA',
'RCA',
RCA_DEVICE_TYPE,
rca_type,
RAWTOHEX(target_guid_in),
qname,
0);
ELSE
qMsg := MGMT_NOTIFY_NOTIFICATION(NORMAL_NOTIFICATION,
IS_NOT_PING,
RCA_RETRY_SEVERITY,
severity_guid_in,
'RCA',
'RCA',
RCA_DEVICE_TYPE,
rca_type,
RAWTOHEX(target_guid_in),
qname,
0);
END IF;
QUEUE_WITH_DELAY(qname, qMsg, delay_in);
END QUEUE_RCA_UPDATE;
-- PURPOSE
-- Procedure to queue a task with a delay
--
-- NOTES
--
PROCEDURE QUEUE_WITH_DELAY(qname_in IN VARCHAR2,
notification_in IN MGMT_NOTIFY_NOTIFICATION,
delay_in IN NUMBER)
IS
enq_options dbms_aq.enqueue_options_t;
qMsg_properties dbms_aq.message_properties_t;
qMsg_handle RAW(16);
recipient sys.aq$_agent;
BEGIN
-- Set up the qname as the recipient name
recipient := sys.aq$_agent(qname_in, NULL, 0);
qMsg_properties.recipient_list(1) := recipient;
qMsg_properties.delay := delay_in;
-- Add the message to the queue
DBMS_AQ.ENQUEUE(queue_name => G_QUEUE_NAME,
enqueue_options => enq_options,
message_properties => qMsg_properties,
payload => notification_in,
msgid => qMsg_handle);
EXCEPTION
WHEN OTHERS
THEN
mgmt_log.log_error(EMD_NOTIFICATION.CHECK_MODULE_NAME,
MGMT_GLOBAL.UNEXPECTED_ERR,
MGMT_GLOBAL.UNEXPECTED_ERR_M ||
'QUEUE_WITH_DELAY('
|| qname_in || '/' || notification_in.device_name ||
'/' || notification_in.device_owner || ') ' ||
SQLERRM, 'ORA', notification_in.source_guid);
END QUEUE_WITH_DELAY;
PROCEDURE CHK_AND_QUEUE_REP_NOTIF(p_sev_guid_in IN RAW,
p_rule_guid IN RAW,
p_curr_repeat_count NUMBER)
IS
l_repeat_enabled NUMBER(1);
l_rep_frequency NUMBER;
l_max_rep_count NUMBER;
l_ack NUMBER(1);
l_violation_type NUMBER(1);
l_cnt NUMBER(1);
l_source_type NUMBER(1);
l_qname VARCHAR2(30);
l_target_guid RAW(16);
l_notif_status NUMBER;
l_violation_level NUMBER;
tgt_is_service NUMBER := 0;
l_num_emails NUMBER := 0;
l_tz_region VARCHAR2(64);
qMsg MGMT_NOTIFY_NOTIFICATION;
l_target_type MGMT_TARGETS.TARGET_TYPE%TYPE;
CURSOR devices
IS
SELECT
DISTINCT d.profile_name, d.device_name, d.type, d.status,
d.program, r.owner, r.rule_name
FROM mgmt_notify_rules r, mgmt_notify_devices d, mgmt_notify_notifyees n
WHERE r.rule_guid = p_rule_guid
AND r.rule_name = n.rule_name
AND r.owner = n.owner
AND n.device_name = d.device_name
AND n.profile_name = d.profile_name
AND d.type IN (LONG_EMAIL_DEVICE_TYPE, SHORT_EMAIL_DEVICE_TYPE);
BEGIN
BEGIN
GET_GLOBAL_REPEAT_SETTINGS(l_repeat_enabled, l_rep_frequency, l_max_rep_count);
IF(l_repeat_enabled = 0)
THEN
IF EMDW_LOG.P_IS_INFO_SET
THEN
EMDW_LOG.INFO('Global repeat setting is turned off. ' ||
' No more repeat notificaion will be send'
, 'CHK_AND_QUEUE_REP_NOTIF');
END IF;
RETURN;
END IF;
IF(p_curr_repeat_count > l_max_rep_count)
THEN
IF EMDW_LOG.P_IS_INFO_SET
THEN
EMDW_LOG.INFO('Global repeat setting count is less the current repeat count. ' ||
' No more repeat notificaion will be send'
, 'CHK_AND_QUEUE_REP_NOTIF');
END IF;
RETURN;
END IF;
SELECT acknowledged, violation_type, target_guid, notification_status
INTO l_ack, l_violation_type, l_target_guid, l_notif_status
FROM mgmt_violations
WHERE violation_guid = p_sev_guid_in;
IF(l_ack = 1)
THEN
IF EMDW_LOG.P_IS_DEBUG_SET
THEN
EMDW_LOG.DEBUG('Severity is already acknowledge. ' ||
' No more repeat notificaion will be send'
, 'CHK_AND_QUEUE_REP_NOTIF');
END IF;
RETURN;
END IF;
IF(l_violation_type = MGMT_GLOBAL.G_SEVERITY_TYPE_AVAILABILITY)
THEN
SELECT count(*)
INTO l_cnt
FROM mgmt_current_availability
WHERE severity_guid = p_sev_guid_in;
ELSE
SELECT count(*)
INTO l_cnt
FROM mgmt_current_violation
WHERE violation_guid = p_sev_guid_in;
END IF;
IF(l_cnt = 0)
THEN
IF EMDW_LOG.P_IS_DEBUG_SET
THEN
EMDW_LOG.DEBUG('Severity state has changed. ' ||
' No more repeat notificaion will be send'
, 'CHK_AND_QUEUE_REP_NOTIF');
END IF;
RETURN;
END IF;
IF l_violation_type = MGMT_GLOBAL.G_SEVERITY_TYPE_POLICY
THEN
l_source_type := POLICY_VIOLATION;
ELSE
l_source_type := METRIC_SEVERITY;
END IF;
-- Check if this is an RCA notification
SELECT target_type
INTO l_target_type
FROM mgmt_targets
WHERE target_guid = l_target_guid;
tgt_is_service := mgmt_service.implements_service_interface(l_target_type);
IF tgt_is_service = 1 AND
l_violation_type = MGMT_GLOBAL.G_SEVERITY_TYPE_AVAILABILITY AND
l_notif_status IN
(MGMT_GLOBAL.G_NOTIF_STATUS_RCA_CAUSE,
MGMT_GLOBAL.G_NOTIF_STATUS_RCA_NO_CAUSE) AND
l_violation_level = MGMT_GLOBAL.G_SEVERITY_CRITICAL
THEN
l_source_type := RCA_COMPLETED_SEVERITY;
END IF;
FOR device IN devices
LOOP
IF DEVICE_AVAILABLE(device.device_name, device.profile_name)
THEN
-- Get the queue name for this user/object combination
l_qname := GET_QUEUE(device.type, device.profile_name,
l_target_guid);
IF l_qname IS NOT NULL
THEN
qMsg := MGMT_NOTIFY_NOTIFICATION(REPEAT_NOTIFICATION, IS_NOT_PING,
l_source_type,
p_sev_guid_in,
device.device_name,
device.profile_name,
device.type,
device.rule_name,
device.owner, l_qname, p_curr_repeat_count);
QUEUE(l_qname, qMsg);
NUM_EMAILS_QUEUED := NUM_EMAILS_QUEUED + 1;
l_num_emails := l_num_emails + 1;
END IF;
ELSE
IF EMDW_LOG.P_IS_INFO_SET
THEN
EMDW_LOG.INFO( device.device_name || ' Email device is not avaliable.' ||
' Repeat notificaion will not be send'
, 'CHK_AND_QUEUE_REP_NOTIF');
END IF;
END IF;
END LOOP;
IF(l_num_emails > 0)
THEN
SELECT TIMEZONE_REGION
INTO l_tz_region
FROM mgmt_targets
WHERE target_guid = l_target_guid;
INSERT INTO MGMT_ANNOTATION (source_obj_type, source_obj_guid, timestamp,
annotation_type, user_name, message)
VALUES (MGMT_GLOBAL.G_ANNOTATION_SOURCE_SEVERITY, p_sev_guid_in,
mgmt_global.sysdate_tzrgn(l_tz_region), 'NOTIFICATION',
'', l_num_emails || ' repeat email notifications will be sent ');
END IF;
IF(p_curr_repeat_count < l_max_rep_count)
THEN
queue_repeat_notif_input(p_sev_guid_in, p_rule_guid, p_curr_repeat_count + 1, l_rep_frequency);
END IF;
EXCEPTION
WHEN OTHERS THEN
mgmt_log.log_error(EMD_NOTIFICATION.CHECK_MODULE_NAME,
MGMT_GLOBAL.UNEXPECTED_ERR,
MGMT_GLOBAL.UNEXPECTED_ERR_M ||
' CHK_AND_QUEUE_REP_NOTIF('
|| p_sev_guid_in || '/' || p_rule_guid || '/' || p_curr_repeat_count || ') ' ||
SQLERRM, 'ORA', p_sev_guid_in);
END;
END CHK_AND_QUEUE_REP_NOTIF;
-- PURPOSE
-- Procedure to find the devices that need to be notified for a severity
-- occurrence and queue the notifications
--
PROCEDURE QUEUE_METRIC_NOTIFICATIONS
(
v_violation IN MGMT_VIOLATIONS%ROWTYPE,
v_ca_state_change IN MGMT_JOB_STATE_CHANGES%ROWTYPE DEFAULT NULL
)
IS
qMsg MGMT_NOTIFY_NOTIFICATION;
tguid RAW(16);
tgt_name MGMT_TARGETS.target_name%TYPE;
tgt_type MGMT_TARGETS.target_type%TYPE;
tz_region VARCHAR2(64);
met_name VARCHAR2(64);
met_col VARCHAR2(64);
pname VARCHAR2(64);
dname VARCHAR2(132);
qname VARCHAR2(30);
origUser VARCHAR2(256);
checkUser VARCHAR2(256);
lastUser VARCHAR2(256);
has_priv NUMBER := 0;
is_response NUMBER := 0;
qstart DATE;
num_emails NUMBER := 0;
num_oscmds NUMBER := 0;
num_plsql NUMBER := 0;
num_snmp NUMBER := 0;
num_java NUMBER := 0;
tgt_is_service NUMBER := 0;
t DATE;
l_device_type NUMBER := 0;
l_source_type NUMBER := 0;
l_source_id RAW(16) := v_violation.violation_guid;
l_annotation_type NUMBER := MGMT_GLOBAL.G_ANNOTATION_SOURCE_SEVERITY;
l_annotation_msg VARCHAR2(256) := 'The following notifications will be sent: ';
l_ca_state NUMBER := -1;
l_notification_type NUMBER := NORMAL_NOTIFICATION;
l_error_message VARCHAR2(256);
l_rule_guid RAW(16);
l_repeat NUMBER(1);
l_repeat_enabled NUMBER(1);
l_rep_frequency NUMBER;
l_max_rep_count NUMBER;
l_ack NUMBER(1);
l_tz_region VARCHAR2(64);
l_rule_guids MGMT_USER_GUID_ARRAY := MGMT_USER_GUID_ARRAY();
l_distinct_rules MGMT_USER_GUID_ARRAY := MGMT_USER_GUID_ARRAY();
CURSOR devices(tguid RAW, tname VARCHAR2, ttype VARCHAR2, mname VARCHAR2,
mcol VARCHAR2, kval VARCHAR2, violation_level NUMBER,
is_response_metric NUMBER, ca_state NUMBER,
is_service NUMBER)
IS
SELECT /*+ ORDERED PUSH_SUBQ */
DISTINCT d.profile_name, d.device_name, d.type, d.status, d.program,
cfg.owner, cfg.rule_name, DECODE(d.type,
SHORT_EMAIL_DEVICE_TYPE,d.profile_name,
LONG_EMAIL_DEVICE_TYPE ,d.profile_name,
cfg.owner) checkUser
FROM
(SELECT rule_name, owner
FROM MGMT_NOTIFY_RULE_CONFIGS c
WHERE ((ttype LIKE c.target_type ESCAPE G_ESC AND
tname LIKE c.target_name ESCAPE G_ESC)
OR (c.target_guid IS NOT NULL AND
EXISTS (SELECT 1
FROM MGMT_FLAT_TARGET_ASSOC a,
MGMT_TARGETS t
WHERE a.source_target_guid = c.target_guid
AND a.is_membership = 1
AND a.assoc_target_guid = t.target_guid
AND t.target_type = c.target_type
AND t.target_name = tname)))
AND mname LIKE c.metric_name ESCAPE G_ESC
AND mcol LIKE c.metric_column ESCAPE G_ESC
AND ((kval LIKE c.key_value ESCAPE G_ESC)
OR (c.key_value <> ' ' AND EXISTS
(SELECT 1 FROM mgmt_metrics_composite_keys k
WHERE k.composite_key = kval
AND NVL(k.key_part1_value, ' ') LIKE c.key_part_1 ESCAPE G_ESC
AND NVL(k.key_part2_value, ' ') LIKE c.key_part_2 ESCAPE G_ESC
AND NVL(k.key_part3_value, ' ') LIKE c.key_part_3 ESCAPE G_ESC
AND NVL(k.key_part4_value, ' ') LIKE c.key_part_4 ESCAPE G_ESC
AND NVL(k.key_part5_value, ' ') LIKE c.key_part_5 ESCAPE G_ESC
AND k.target_guid = tguid)))
AND ((ca_state = -1 AND
(
-- The following conditions should only match violation related to
-- metric severities and policies
(violation_level = MGMT_GLOBAL.G_SEVERITY_UNREACHABLE_START AND
want_target_unreachable_start = 1) OR
(violation_level = MGMT_GLOBAL.G_SEVERITY_UNREACHABLE_CLEAR AND
want_target_unreachable_end = 1) OR
(violation_level = MGMT_GLOBAL.G_SEVERITY_BLACKOUT_START AND
want_target_blackout_start = 1) OR
(violation_level = MGMT_GLOBAL.G_SEVERITY_BLACKOUT_END AND
want_target_blackout_end = 1) OR
(violation_level = MGMT_GLOBAL.G_SEVERITY_ERROR_START AND
((want_target_metric_err_start = 1 AND is_response_metric = 1) OR
(want_target_metric_err_start = 2 AND is_response_metric = 0) OR
(want_target_metric_err_start = 3))) OR
(violation_level = MGMT_GLOBAL.G_SEVERITY_ERROR_END AND
((want_target_metric_err_end = 1 AND is_response_metric = 1) OR
(want_target_metric_err_end = 2 AND is_response_metric = 0) OR
(want_target_metric_err_end = 3))) OR
(violation_level = MGMT_GLOBAL.G_SEVERITY_CLEAR AND
want_clears = 1 AND v_violation.violation_type <> 1) OR
(violation_level = MGMT_GLOBAL.G_SEVERITY_CLEAR AND
want_target_up = 1 AND v_violation.violation_type = 1) OR
(violation_level = MGMT_GLOBAL.G_SEVERITY_WARNING AND
want_warnings = 1) OR
(violation_level = MGMT_GLOBAL.G_SEVERITY_CRITICAL AND
want_critical_alerts = 1 AND v_violation.violation_type <> 1) OR
(violation_level = MGMT_GLOBAL.G_SEVERITY_CRITICAL AND
want_target_down = 1 AND v_violation.violation_type = 1 AND
is_service = 0) OR
(violation_level = MGMT_GLOBAL.G_SEVERITY_CRITICAL AND
want_target_down = 1 AND v_violation.violation_type = 1 AND
is_service = 1 AND is_response_metric = 1 and ignore_rca = 1 AND
v_violation.notification_status NOT IN
(MGMT_GLOBAL.G_NOTIF_STATUS_RCA_CAUSE,
MGMT_GLOBAL.G_NOTIF_STATUS_RCA_NO_CAUSE)) OR
(violation_level = MGMT_GLOBAL.G_SEVERITY_CRITICAL AND
want_target_down = 1 AND v_violation.violation_type = 1 AND
is_service = 1 AND is_response_metric = 1 and ignore_rca = 0 AND
v_violation.notification_status IN
(MGMT_GLOBAL.G_NOTIF_STATUS_RCA_CAUSE,
MGMT_GLOBAL.G_NOTIF_STATUS_RCA_NO_CAUSE)) OR
((violation_level = MGMT_GLOBAL.G_SEVERITY_INFORMATIONAL OR violation_level = MGMT_GLOBAL.G_SEVERITY_WARNING OR violation_level = MGMT_GLOBAL.G_SEVERITY_CRITICAL) AND
want_policy_violations = 1 ) OR
(violation_level = MGMT_GLOBAL.G_SEVERITY_CLEAR AND
want_policy_clears = 1 )
)
)
OR
(ca_state <> -1 AND
(
-- The following conditions should only match violations related to
-- corrective action executions
(ca_state = MGMT_JOBS.STATUS_BUCKET_OK AND
violation_level = MGMT_GLOBAL.G_SEVERITY_WARNING AND
want_warning_job_succeeded = 1) OR
(ca_state = MGMT_JOBS.STATUS_BUCKET_OK AND
violation_level = MGMT_GLOBAL.G_SEVERITY_CRITICAL AND
want_critical_job_succeeded = 1) OR
(ca_state = MGMT_JOBS.STATUS_BUCKET_OK AND
violation_level <> MGMT_GLOBAL.G_SEVERITY_CLEAR AND
want_policy_job_succeeded = 1) OR
(ca_state = MGMT_JOBS.STATUS_BUCKET_PROBLEM AND
violation_level = MGMT_GLOBAL.G_SEVERITY_WARNING AND
want_warning_job_problems = 1) OR
(ca_state = MGMT_JOBS.STATUS_BUCKET_PROBLEM AND
violation_level = MGMT_GLOBAL.G_SEVERITY_CRITICAL AND
want_critical_job_problems = 1) OR
(ca_state = MGMT_JOBS.STATUS_BUCKET_PROBLEM AND
violation_level <> MGMT_GLOBAL.G_SEVERITY_CLEAR AND
want_policy_job_problems = 1)
)
)
)) cfg, mgmt_notify_notifyees n, mgmt_notify_devices d
WHERE n.rule_name = cfg.rule_name
AND n.owner = cfg.owner
AND ((d.device_name = n.device_name AND d.profile_name = n.profile_name)
OR
(n.device_name = ' ' AND d.profile_name = n.profile_name AND
d.type IN (SHORT_EMAIL_DEVICE_TYPE, LONG_EMAIL_DEVICE_TYPE)
)
)
ORDER BY checkUser;
BEGIN
BEGIN
GET_GLOBAL_REPEAT_SETTINGS(l_repeat_enabled, l_rep_frequency, l_max_rep_count);
-- Get the target name and
SELECT target_name, target_type, timezone_region
INTO tgt_name, tgt_type, tz_region
FROM MGMT_TARGETS
WHERE target_guid = v_violation.target_guid;
tgt_is_service := mgmt_service.implements_service_interface(tgt_type);
EXCEPTION
WHEN NO_DATA_FOUND
THEN
-- Severity contains an invalid target guid
IF emdw_log.p_is_debug_set
THEN
emdw_log.debug('QMN: invalid target: violation_guid = '
|| v_violation.violation_guid
|| ' target_guid=' || v_violation.target_guid,
CHECK_MODULE_NAME) ;
END IF;
RETURN;
END;
-- If this is a policy violation then get the policy name
IF v_violation.violation_type = MGMT_GLOBAL.G_SEVERITY_TYPE_POLICY
THEN
l_source_type := POLICY_VIOLATION;
BEGIN
-- Get the policy_name
SELECT policy_name INTO met_name FROM MGMT_POLICIES p
WHERE policy_guid = v_violation.policy_guid;
met_col := '%';
EXCEPTION
WHEN NO_DATA_FOUND
THEN
-- Severity contains an invalid policy guid
IF emdw_log.p_is_debug_set
THEN
emdw_log.debug('QMN: invalid policy: violation_guid = '
|| v_violation.violation_guid
|| ' policy_guid=' || v_violation.policy_guid,
CHECK_MODULE_NAME) ;
END IF;
RETURN;
END;
ELSE
l_source_type := METRIC_SEVERITY;
BEGIN
-- Get the metric name and column
SELECT m.metric_name, m.metric_column INTO met_name, met_col
FROM MGMT_TARGETS t, MGMT_METRICS m
WHERE t.target_guid = v_violation.target_guid
AND m.metric_guid = v_violation.policy_guid
AND t.target_type = m.target_type
AND m.type_meta_ver = t.type_meta_ver
AND (m.category_prop_1 = t.category_prop_1 or m.category_prop_1 = ' ')
AND (m.category_prop_2 = t.category_prop_2 or m.category_prop_2 = ' ')
AND (m.category_prop_3 = t.category_prop_3 or m.category_prop_3 = ' ')
AND (m.category_prop_4 = t.category_prop_4 or m.category_prop_4 = ' ')
AND (m.category_prop_5 = t.category_prop_5 or m.category_prop_5 = ' ');
EXCEPTION
WHEN NO_DATA_FOUND
THEN
-- Severity contains an invalid metric guid
IF emdw_log.p_is_debug_set
THEN
emdw_log.debug('QMN: invalid metric: violation_guid = '
|| v_violation.violation_guid
|| ' metric_guid' || v_violation.policy_guid,
CHECK_MODULE_NAME) ;
END IF;
RETURN;
WHEN TOO_MANY_ROWS
THEN
-- Get the metric name and column
SELECT m.metric_name, m.metric_column INTO met_name, met_col
FROM MGMT_TARGETS t, MGMT_METRICS m
WHERE t.target_guid = v_violation.target_guid
AND m.metric_guid = v_violation.policy_guid
AND t.target_type = m.target_type
AND m.type_meta_ver = t.type_meta_ver
AND (m.category_prop_1 = t.category_prop_1 or m.category_prop_1 = ' ')
AND (m.category_prop_2 = t.category_prop_2 or m.category_prop_2 = ' ')
AND (m.category_prop_3 = t.category_prop_3 or m.category_prop_3 = ' ')
AND (m.category_prop_4 = t.category_prop_4 or m.category_prop_4 = ' ')
AND (m.category_prop_5 = t.category_prop_5 or m.category_prop_5 = ' ')
AND rownum < 2;
IF emdw_log.p_is_debug_set
THEN
emdw_log.debug('QMN: duplicate metric: violation_guid = '
|| v_violation.violation_guid
|| ' metric_guid=' || v_violation.policy_guid,
CHECK_MODULE_NAME) ;
END IF;
-- Log an error
mgmt_log.log_error(EMD_NOTIFICATION.CHECK_MODULE_NAME,
MGMT_GLOBAL.UNEXPECTED_ERR,
'QUEUE_METRIC_NOTIFICATIONS found duplicate metric definition for '
|| met_name || '/' || met_col || '/' ||
tgt_type, 'ORA', v_violation.violation_guid);
RETURN;
END;
END IF;
-- Check if this is the Response Metric
IF met_name = MGMT_GLOBAL.G_AVAIL_METRIC_NAME AND
met_col = MGMT_GLOBAL.G_AVAIL_METRIC_COLUMN
THEN
is_response := 1;
END IF;
-- First get the currently logged in user. this user name will be used
-- later for resetting the context back to this user
origUser := mgmt_user.get_current_em_user();
-- Check if this is for a corrective action
IF v_ca_state_change.state_change_guid IS NOT NULL
THEN
l_ca_state := v_ca_state_change.status_bucket;
l_source_id := v_ca_state_change.state_change_guid;
l_annotation_msg := 'The following notifications will be sent for the Corrective Action: ';
-- Update the source type
IF l_source_type = METRIC_SEVERITY
THEN
l_source_type := METRIC_CA_STATE_CHANGE;
ELSIF l_source_type = POLICY_VIOLATION
THEN
l_source_type := POLICY_CA_STATE_CHANGE;
END IF;
END IF;
-- Check if this is an RCA notification
IF tgt_is_service = 1 AND
is_response = 1 AND
v_violation.notification_status IN
(MGMT_GLOBAL.G_NOTIF_STATUS_RCA_CAUSE,
MGMT_GLOBAL.G_NOTIF_STATUS_RCA_NO_CAUSE) AND
v_violation.violation_level = MGMT_GLOBAL.G_SEVERITY_CRITICAL
THEN
l_source_type := RCA_COMPLETED_SEVERITY;
END IF;
IF emdw_log.p_is_debug_set
THEN
emdw_log.debug('QMN: violation_guid = ' || v_violation.violation_guid
|| ' target=' || tgt_name
|| ' type=' || tgt_type
|| ' metric/policy=' || met_name
|| ' column=' || met_col
|| ' level=' || v_violation.violation_level
|| ' source_type=' || l_source_type
|| ' is_response=' || is_response
|| ' message=' || v_violation.message,
CHECK_MODULE_NAME) ;
END IF ;
-- Get the devices that need to be notified
FOR device IN devices(v_violation.target_guid, tgt_name, tgt_type, met_name, met_col,
v_violation.key_value, v_violation.violation_level,
is_response, l_ca_state, tgt_is_service)
LOOP
-- For use in error message
pname := device.profile_name;
dname := device.device_name;
IF emdw_log.p_is_debug_set
THEN
emdw_log.debug('QMN: Match found. Rule=' || device.rule_name
|| ' Owner=' || device.owner || ' Method=' || dname ||
' Owner=' || pname,
CHECK_MODULE_NAME) ;
END IF ;
-- There is no need to check privileges for standalone mode
-- since there is no VPD
IF (EMD_MAINTENANCE.IS_CENTRAL_MODE > 0)
THEN
-- For emails you need to make sure the user associated with the
-- address has accees to the target. For all other notification methods
-- you need to make sure the owner of the rule has access to the target
-- since those methods are always owned by the Super User
checkUser := device.checkUser;
-- Only check if this user has not been checked before
IF lastUser IS NULL OR lastUser <> checkUser
THEN
lastUser := checkUser;
has_priv := 0;
-- Check if the device owner has access to the target
SETEMUSERCONTEXT(checkUser, MGMT_USER.OP_SET_IDENTIFIER);
BEGIN
-- the following line has been changed by dcawley to fix a problem
-- with VPD policies not being applied correctly by the RDBMS.
-- See bug 4143213
SELECT count(target_guid) INTO has_priv FROM MGMT_TARGETS
WHERE target_guid = v_violation.target_guid;
EXCEPTION
WHEN NO_DATA_FOUND
THEN
-- Continue onto the next device since this device has no access to
-- the target
has_priv := 0;
END;
END IF;
IF has_priv = 0
THEN
IF emdw_log.p_is_debug_set
THEN
emdw_log.debug('QMN: ' || checkUser || ' has no access to ' ||
tgt_name || '/' || tgt_type,
CHECK_MODULE_NAME) ;
END IF ;
GOTO end_device_loop;
END IF;
END IF;
-- Check the notification schedule to see if the device is available
IF device.type NOT IN (SHORT_EMAIL_DEVICE_TYPE, LONG_EMAIL_DEVICE_TYPE) OR
DEVICE_AVAILABLE(device.device_name, device.profile_name)
THEN
-- Check the status to make sure it is contactable
IF device.status = DEVICE_UP
THEN
qstart := SYSDATE;
IF device.type = PROGRAM_DEVICE_TYPE AND
IS_WINDOWS_PROGRAM(device.program)
THEN
l_device_type := WINDOWS_PROGRAM_DEVICE_TYPE;
ELSE
l_device_type := device.type;
END IF;
-- Get the queue name for this user/object combination
qname := GET_QUEUE(l_device_type, device.profile_name,
v_violation.target_guid);
IF qname IS NOT NULL
THEN
-- Set up the message for the queue
qMsg := MGMT_NOTIFY_NOTIFICATION(l_notification_type, IS_NOT_PING,
l_source_type,
l_source_id,
device.device_name,
device.profile_name,
device.type,
device.rule_name,
device.owner, qname, 0);
IF emdw_log.p_is_debug_set
THEN
emdw_log.debug('QMN: Queueing notification for' ||
' device_name=' || dname ||
' owner=' || pname,
CHECK_MODULE_NAME) ;
END IF ;
QUEUE(qname, qMsg);
TOTAL_ENQUEUE_TIME := TOTAL_ENQUEUE_TIME + (SYSDATE - qstart);
-- Update the local and overall stats
IF device.type IN (LONG_EMAIL_DEVICE_TYPE,
SHORT_EMAIL_DEVICE_TYPE)
THEN
NUM_EMAILS_QUEUED := NUM_EMAILS_QUEUED + 1;
num_emails := num_emails + 1;
ELSIF device.type = PROGRAM_DEVICE_TYPE
THEN
NUM_OSCMDS_QUEUED := NUM_OSCMDS_QUEUED + 1;
num_oscmds := num_oscmds + 1;
ELSIF device.type = SNMP_DEVICE_TYPE
THEN
NUM_SNMPS_QUEUED := NUM_SNMPS_QUEUED + 1;
num_snmp := num_snmp + 1;
ELSIF device.type = PLSQL_DEVICE_TYPE
THEN
NUM_PLSQLS_QUEUED := NUM_PLSQLS_QUEUED + 1;
num_plsql := num_plsql + 1;
ELSIF device.type = JAVA_DEVICE_TYPE
THEN
NUM_JAVA_QUEUED := NUM_JAVA_QUEUED + 1;
num_java := num_java + 1;
END IF;
ELSE
-- Could not find a queue to service notification. Must be an
-- OS Command where no Windows OMSs are registered
IF emdw_log.p_is_debug_set
THEN
emdw_log.debug('QMN: No Windows OMS to handle OS Command',
CHECK_MODULE_NAME) ;
END IF ;
LOG_HISTORY(l_annotation_type, v_violation.violation_guid, 'N',
'A Windows based Management Server is not registered ' ||
'(Rule Owner=' || device.owner || ', Rule Name=' ||
device.rule_name || ')', tz_region);
END IF;
ELSE
-- The device is currently down so set this up for retry
IF emdw_log.p_is_debug_set
THEN
emdw_log.debug('QMN: Device down so setup for retry',
CHECK_MODULE_NAME) ;
END IF ;
INSERT INTO mgmt_notify_requeue
(source_guid, source_type, notification_type,
device_name, device_owner, device_type, rule_name, rule_owner)
VALUES (v_violation.violation_guid, l_source_type,
RETRY_NOTIFICATION,
device.device_name, device.profile_name, device.type,
device.rule_name, device.owner);
END IF;
ELSE
IF emdw_log.p_is_debug_set
THEN
emdw_log.debug('QMN: ' || dname || ' is not in notification schedule',
CHECK_MODULE_NAME) ;
END IF ;
END IF;
IF (EMD_MAINTENANCE.IS_CENTRAL_MODE > 0) THEN
-- Commit/Rollback only in central repository mode.
-- In Standalone mode, this procedure is called in the severity insert
-- trigger. (Commits/Rollbacks are not allowed in triggers)
COMMIT;
END IF;
-- if the source is not CA then check for repeat and severity is not for clear
IF l_source_type NOT IN (METRIC_CA_STATE_CHANGE, POLICY_CA_STATE_CHANGE) AND
v_violation.violation_level NOT IN (mgmt_global.g_severity_clear, mgmt_global.g_severity_unreachable_clear,
mgmt_global.g_severity_blackout_start, mgmt_global.g_severity_blackout_end,
mgmt_global.g_severity_error_end, mgmt_global.g_severity_unknown,
mgmt_global.g_severity_informational)
THEN
SELECT rule_guid, repeat
INTO l_rule_guid, l_repeat
FROM mgmt_notify_rules
WHERE rule_name = device.rule_name
AND owner = device.owner;
IF(l_repeat = 1 AND l_repeat_enabled = 1 AND l_max_rep_count > 0)
THEN
l_rule_guids.extend(1);
l_rule_guids(l_rule_guids.COUNT) := l_rule_guid;
END IF;
END IF;
<< end_device_loop >>
NULL;
END LOOP;
-- check if the severity should produce an RCA task; this requires that the
-- target is a service and that the severity is for the Response-Status metric,
-- in other words, that its a Service Down alert.
IF tgt_is_service = 1 AND
is_response = 1 AND
v_violation.notification_status <> MGMT_GLOBAL.G_NOTIF_STATUS_RCA_CAUSE AND
v_violation.notification_status <> MGMT_GLOBAL.G_NOTIF_STATUS_RCA_NO_CAUSE AND
v_violation.violation_level = MGMT_GLOBAL.G_SEVERITY_CRITICAL
THEN
-- queue the RCA task
qstart := SYSDATE;
-- Get the queue name for this user/object combination
qname := GET_QUEUE(RCA_DEVICE_TYPE,
'RCA',
v_violation.target_guid);
qMsg := MGMT_NOTIFY_NOTIFICATION(NORMAL_NOTIFICATION,
IS_NOT_PING,
RCA_SEVERITY,
v_violation.violation_guid,
'RCA',
'RCA',
RCA_DEVICE_TYPE,
'RCA_NORMAL',
RAWTOHEX(v_violation.target_guid),
qname,
0);
QUEUE(qname, qMsg);
IF emdw_log.p_is_debug_set
THEN
emdw_log.debug('QMN: Queued RCA task',
CHECK_MODULE_NAME) ;
END IF ;
TOTAL_ENQUEUE_TIME := TOTAL_ENQUEUE_TIME + (SYSDATE - qstart);
END IF;
IF num_emails > 0 OR num_oscmds > 0 OR num_plsql > 0 OR num_snmp > 0 OR num_java > 0
THEN
t := mgmt_global.sysdate_tzrgn(tz_region);
-- The message needs to be NLS'ed
INSERT INTO MGMT_ANNOTATION (source_obj_type, source_obj_guid, timestamp,
annotation_type, user_name, message)
VALUES (l_annotation_type, v_violation.violation_guid, t, 'NOTIFICATION',
'', l_annotation_msg ||
decode(num_emails, 0, '', num_emails || ' e-mail messages ') ||
decode(num_snmp, 0, '', num_snmp || ' SNMP traps ') ||
decode(num_plsql, 0, '', num_plsql || ' PL/SQL procedures ') ||
decode(num_oscmds, 0, '', num_oscmds || ' OS Commands ') ||
decode(num_java, 0, '', num_java || ' Java callbacks'));
END IF;
-- if l_rule_guids.COUNT > 0 then enqueue repeat signal for each rule
IF l_rule_guids.COUNT > 0
THEN
BEGIN
SELECT distinct(l.COLUMN_VALUE)
BULK COLLECT INTO l_distinct_rules
FROM TABLE (CAST(l_rule_guids as MGMT_USER_GUID_ARRAY)) l;
FOR i in 1 .. l_distinct_rules.COUNT
LOOP
l_rule_guid := l_distinct_rules(i);
queue_repeat_notif_input(l_source_id, l_rule_guid, 1, l_rep_frequency);
END LOOP;
EXCEPTION
WHEN OTHERS THEN
mgmt_log.log_error(EMD_NOTIFICATION.CHECK_MODULE_NAME,
MGMT_GLOBAL.UNEXPECTED_ERR,
MGMT_GLOBAL.UNEXPECTED_ERR_M ||
'QUEUE_METRIC_NOTIFICATIONS : '
|| ' Error while enquing repeat signal for ( ' ||
l_source_id || ', ' || l_rule_guid || ' ' ||
SQLERRM, 'ORA', l_source_id);
END;
END IF;
-- Reset the context back to the original user
SETEMUSERCONTEXT(origUser, MGMT_USER.OP_SET_IDENTIFIER);
IF (EMD_MAINTENANCE.IS_CENTRAL_MODE > 0) THEN
-- Commit/Rollback only in central repository mode.
-- In Standalone mode, this procedure is called in the
-- severity insert trigger. (Commits/Rollbacks are not allowed in triggers)
COMMIT;
END IF;
EXCEPTION
WHEN OTHERS
THEN
IF (EMD_MAINTENANCE.IS_CENTRAL_MODE > 0) THEN
-- Commit/Rollback only in central repository mode.
-- In Standalone mode, this procedure is called in the
-- severity insert trigger.(Commits/Rollbacks are not allowed in triggers)
ROLLBACK;
END IF;
-- Reset the context back to the original user
IF origUser IS NOT NULL
THEN
SETEMUSERCONTEXT(origUser, MGMT_USER.OP_SET_IDENTIFIER);
END IF;
IF (EMD_MAINTENANCE.IS_CENTRAL_MODE > 0) THEN
-- Commit/Rollback only in central repository mode.
-- In Standalone mode, this procedure is called in the
-- severity insert trigger.(Commits/Rollbacks are not allowed in triggers)
COMMIT;
END IF;
IF emdw_log.p_is_debug_set
THEN
emdw_log.debug('QMN: Unexpected error ' || SQLERRM,
CHECK_MODULE_NAME) ;
END IF ;
mgmt_log.log_error(EMD_NOTIFICATION.CHECK_MODULE_NAME,
MGMT_GLOBAL.UNEXPECTED_ERR,
MGMT_GLOBAL.UNEXPECTED_ERR_M ||
'QUEUE_METRIC_NOTIFICATIONS ('
|| pname || '/' || dname || ') ' ||
SQLERRM, 'ORA', v_violation.violation_guid);
END QUEUE_METRIC_NOTIFICATIONS;
-- PURPOSE
-- Procedure to find the devices that need to be notified for a job state
-- change and queue the notifications
--
PROCEDURE QUEUE_JOB_NOTIFICATIONS(v_state_change IN MGMT_JOB_STATE_CHANGES%ROWTYPE)
IS
qMsg MGMT_NOTIFY_NOTIFICATION;
tguid RAW(16);
l_job_id RAW(16);
tgt_guids MGMT_USER_GUID_ARRAY;
tgt_matches MGMT_LONG_STRING_ARRAY;
tgt_types MGMT_SHORT_STRING_ARRAY;
tz_regions MGMT_SHORT_STRING_ARRAY;
job_name VARCHAR2(64) := '%';
job_owner VARCHAR2(256) := '%';
job_type VARCHAR2(32) := '%';
pname VARCHAR2(64);
dname VARCHAR2(132);
qname VARCHAR2(30);
origUser VARCHAR2(256);
checkUser VARCHAR2(256);
lastUser VARCHAR2(256);
has_priv NUMBER := 0;
qstart DATE;
num_emails NUMBER := 0;
num_oscmds NUMBER := 0;
num_plsql NUMBER := 0;
num_java NUMBER := 0;
num_snmp NUMBER := 0;
t DATE;
l_device_type NUMBER := 0;
l_error_message VARCHAR2(256);
l_tz_rgn MGMT_TARGETS.timezone_region%TYPE;
CURSOR devices(ttypes MGMT_SHORT_STRING_ARRAY,
tname_type MGMT_LONG_STRING_ARRAY,
jname VARCHAR2, jowner VARCHAR2, jtype VARCHAR2,
job_state NUMBER)
IS
SELECT /*+ ORDERED PUSH_SUBQ */
DISTINCT d.profile_name, d.device_name, d.type, d.status, d.program,
cfg.owner, cfg.rule_name
FROM
(SELECT rule_name, owner
FROM MGMT_NOTIFY_JOB_RULE_CONFIGS c
WHERE (c.target_name||';'||c.target_type IN
(SELECT * FROM TABLE(CAST(tname_type AS MGMT_LONG_STRING_ARRAY)))
OR
(c.target_name = '%' AND c.target_type IN
(SELECT * FROM TABLE(CAST(ttypes AS MGMT_SHORT_STRING_ARRAY))))
OR (c.target_guid IS NOT NULL AND
EXISTS (SELECT 1
FROM MGMT_FLAT_TARGET_ASSOC a, MGMT_TARGETS t
WHERE a.source_target_guid = c.target_guid
AND a.is_membership = 1
AND a.assoc_target_guid = t.target_guid
AND t.target_type = c.target_type
AND t.target_name||';'||c.target_type IN
(SELECT * FROM TABLE(CAST(tname_type
AS MGMT_LONG_STRING_ARRAY)))
)))
AND jname LIKE c.job_name ESCAPE G_ESC
AND jowner LIKE c.job_owner ESCAPE G_ESC
AND jtype LIKE c.job_type ESCAPE G_ESC
AND ((job_state = MGMT_JOBS.STATUS_BUCKET_SCHEDULED AND
want_job_scheduled = 1) OR
(job_state = MGMT_JOBS.STATUS_BUCKET_RUNNING AND
want_job_running = 1) OR
(job_state = MGMT_JOBS.STATUS_BUCKET_SUSPENDED AND
want_job_suspended = 1) OR
(job_state = MGMT_JOBS.STATUS_BUCKET_OK AND
want_job_succeeded = 1) OR
(job_state = MGMT_JOBS.STATUS_BUCKET_PROBLEM AND
want_job_problems = 1))) cfg, mgmt_notify_notifyees n,
mgmt_notify_devices d
WHERE n.rule_name = cfg.rule_name
AND n.owner = cfg.owner
AND ((d.device_name = n.device_name AND d.profile_name = n.profile_name)
OR
(n.device_name = ' ' AND d.profile_name = n.profile_name AND
d.type IN (SHORT_EMAIL_DEVICE_TYPE, LONG_EMAIL_DEVICE_TYPE)
)
);
BEGIN
BEGIN
-- Get the target name and type
SELECT DISTINCT job_tgt.target_guid, tgt.target_type, tgt.timezone_region,
tgt.target_name||';'||tgt.target_type
BULK COLLECT INTO tgt_guids, tgt_types, tz_regions, tgt_matches
FROM MGMT_JOB_EXT_TARGETS job_tgt, MGMT_TARGETS tgt
WHERE job_tgt.job_id = v_state_change.job_id
AND tgt.target_guid = job_tgt.target_guid;
EXCEPTION
WHEN NO_DATA_FOUND
THEN
-- State change contains an invalid target guid
IF emdw_log.p_is_debug_set
THEN
emdw_log.debug('QJN: invalid target: state_change_guid = '
|| v_state_change.state_change_guid,
CHECK_MODULE_NAME) ;
END IF;
RETURN;
END;
if tz_regions.count>0
then
-- Use Target TimeZone when available
l_tz_rgn := tz_regions(1);
else
-- Use emdrep TimeZone for Targetless jobs
BEGIN
select TIMEZONE_REGION into l_tz_rgn from MGMT_TARGETS where target_type='oracle_emrep';
EXCEPTION
WHEN NO_DATA_FOUND THEN
l_tz_rgn := TO_CHAR(SYSTIMESTAMP,'TZR');
END ;
end if;
-- Get the job details
BEGIN
SELECT job_name, job_owner, job_type INTO job_name, job_owner, job_type
FROM MGMT_JOB WHERE job_id = v_state_change.job_id
AND job_status != MGMT_JOBS.JOB_STATUS_DELETE_PENDING;
EXCEPTION
WHEN NO_DATA_FOUND
THEN
-- State change contains an invalid job id
IF emdw_log.p_is_debug_set
THEN
emdw_log.debug('QJN: invalid job: state_change_guid = '
|| v_state_change.state_change_guid
|| ' job_id=' || v_state_change.job_id,
CHECK_MODULE_NAME) ;
END IF;
RETURN;
END;
IF emdw_log.p_is_debug_set
THEN
emdw_log.debug('QJN: state_change_guid = '
|| v_state_change.state_change_guid
|| ' job_id=' || v_state_change.job_id
|| ' execution_id=' || v_state_change.execution_id
|| ' newstate=' || v_state_change.newstate
|| ' status_bucket=' || v_state_change.status_bucket,
CHECK_MODULE_NAME) ;
END IF;
-- First get the currently logged in user. this user name will be used
-- later for resetting the context back to this user
origUser := mgmt_user.get_current_em_user();
-- Check if the owner of the job wants to be notified
BEGIN
SELECT job_id INTO l_job_id FROM MGMT_JOB_NOTIFY_STATES
WHERE job_id = v_state_change.job_id
AND notify_state = v_state_change.status_bucket;
IF emdw_log.p_is_debug_set
THEN
emdw_log.debug('QJN: the job owner ' || job_owner ||
' has selected to be notified',
CHECK_MODULE_NAME) ;
END IF;
-- Get the job owner's email addresses
FOR oe IN (SELECT device_name, email_address, type, status
FROM MGMT_NOTIFY_DEVICES
WHERE profile_name = job_owner
AND type IN (SHORT_EMAIL_DEVICE_TYPE,
LONG_EMAIL_DEVICE_TYPE))
LOOP
-- Do we need to check if the owner has access to the target?
IF DEVICE_AVAILABLE(oe.device_name, job_owner)
THEN
-- Check the status to make sure it is contactable
IF oe.status = DEVICE_UP
THEN
qstart := SYSDATE;
-- Get the queue name for this user/object combination
qname := GET_QUEUE(oe.type, job_owner,
v_state_change.job_id);
IF qname IS NOT NULL
THEN
-- Set up the message for the queue
qMsg := MGMT_NOTIFY_NOTIFICATION(NORMAL_NOTIFICATION, IS_NOT_PING,
JOB_STATE_CHANGE,
v_state_change.state_change_guid,
oe.device_name, job_owner,
oe.type, NULL, NULL, qname, 0);
IF emdw_log.p_is_debug_set
THEN
emdw_log.debug('QJN: Queuing notification to ' ||
oe.device_name,
CHECK_MODULE_NAME) ;
END IF;
QUEUE(qname, qMsg);
TOTAL_ENQUEUE_TIME := TOTAL_ENQUEUE_TIME + (SYSDATE - qstart);
NUM_JOB_EMAILS_QUEUED := NUM_JOB_EMAILS_QUEUED + 1;
num_emails := num_emails + 1;
END IF;
ELSE
IF emdw_log.p_is_debug_set
THEN
emdw_log.debug('QJN: ' || oe.device_name || ' is down',
CHECK_MODULE_NAME) ;
END IF;
END IF;
ELSE
IF emdw_log.p_is_debug_set
THEN
emdw_log.debug('QJN: ' || oe.device_name ||
' is not in the notification schedule',
CHECK_MODULE_NAME) ;
END IF;
END IF;
END LOOP;
EXCEPTION
WHEN NO_DATA_FOUND
THEN
NULL;
END;
FOR device IN devices(tgt_types, tgt_matches,
job_name, job_owner, job_type,
v_state_change.status_bucket)
LOOP
-- For use in error message
pname := device.profile_name;
dname := device.device_name;
IF emdw_log.p_is_debug_set
THEN
emdw_log.debug('QJN: Match found. Rule=' || device.rule_name
|| ' Owner=' || device.owner || ' Method=' || dname ||
' Owner=' || pname,
CHECK_MODULE_NAME) ;
END IF ;
-- There is no need to check privileges for standalone mode
-- since there is no VPD
IF (EMD_MAINTENANCE.IS_CENTRAL_MODE > 0)
THEN
-- For emails you need to make sure the user associated with the
-- address has accees to the target. For all other notification methods
-- you need to make sure the owner of the rule has access to the target
-- since those methods are always owned by the Super User
IF device.type IN (SHORT_EMAIL_DEVICE_TYPE, LONG_EMAIL_DEVICE_TYPE)
THEN
checkUser := device.profile_name;
ELSE
checkUser := device.owner;
END IF;
-- Only check if this user has not been checked before
IF lastUser IS NULL OR lastUser <> checkUser
THEN
has_priv := 0;
lastUser := checkUser;
-- Check if the device owner has access to the target
SETEMUSERCONTEXT(checkUser, MGMT_USER.OP_SET_IDENTIFIER);
-- Get a count of the targets the user can see
SELECT count(target_guid) INTO has_priv FROM MGMT_TARGETS
WHERE target_guid IN
(SELECT * FROM TABLE(CAST(tgt_guids AS MGMT_USER_GUID_ARRAY)));
IF has_priv = 1
THEN
BEGIN
SELECT job_id INTO l_job_id FROM MGMT_JOB
WHERE job_id = v_state_change.job_id
AND job_status != MGMT_JOBS.JOB_STATUS_DELETE_PENDING;
has_priv := 1;
EXCEPTION WHEN NO_DATA_FOUND
THEN
has_priv := 0;
END;
END IF;
END IF;
IF has_priv = 0
THEN
-- Continue onto the next device since this device has no access to
-- the target
IF emdw_log.p_is_debug_set
THEN
DECLARE
l_tgts VARCHAR2(4000);
BEGIN
FOR i IN tgt_guids.FIRST..tgt_guids.LAST
LOOP
l_tgts := l_tgts || tgt_guids(i) || ', ';
END LOOP;
emdw_log.debug('QJN: ' || checkUser ||
' has no access to any of the job targets ' ||
l_tgts,
CHECK_MODULE_NAME) ;
EXCEPTION WHEN OTHERS
THEN
emdw_log.debug('QJN: ' || checkUser ||
' has no access to any of the job targets',
CHECK_MODULE_NAME) ;
END;
END IF ;
GOTO end_device_loop;
END IF;
END IF;
-- Check the notification schedule to see if the device is available
IF device.type NOT IN (SHORT_EMAIL_DEVICE_TYPE, LONG_EMAIL_DEVICE_TYPE) OR
DEVICE_AVAILABLE(device.device_name, device.profile_name)
THEN
-- Check the status to make sure it is contactable
IF device.status = DEVICE_UP
THEN
qstart := SYSDATE;
IF device.type = PROGRAM_DEVICE_TYPE AND
IS_WINDOWS_PROGRAM(device.program)
THEN
l_device_type := WINDOWS_PROGRAM_DEVICE_TYPE;
ELSE
l_device_type := device.type;
END IF;
-- Get the queue name for this user/object combination
qname := GET_QUEUE(l_device_type, device.profile_name,
v_state_change.job_id);
IF qname IS NOT NULL
THEN
-- Set up the message for the queue
qMsg := MGMT_NOTIFY_NOTIFICATION(NORMAL_NOTIFICATION, IS_NOT_PING,
JOB_STATE_CHANGE,
v_state_change.state_change_guid,
device.device_name,
device.profile_name,
device.type,
device.rule_name,
device.owner, qname, 0);
IF emdw_log.p_is_debug_set
THEN
emdw_log.debug('QJN: Queueing notification for' ||
' device_name=' || dname ||
' owner=' || pname,
CHECK_MODULE_NAME) ;
END IF ;
QUEUE(qname, qMsg);
TOTAL_ENQUEUE_TIME := TOTAL_ENQUEUE_TIME + (SYSDATE - qstart);
-- Update the local and overall stats
IF device.type IN (LONG_EMAIL_DEVICE_TYPE,
SHORT_EMAIL_DEVICE_TYPE)
THEN
NUM_JOB_EMAILS_QUEUED := NUM_JOB_EMAILS_QUEUED + 1;
num_emails := num_emails + 1;
ELSIF device.type = PROGRAM_DEVICE_TYPE
THEN
NUM_JOB_OSCMDS_QUEUED := NUM_JOB_OSCMDS_QUEUED + 1;
num_oscmds := num_oscmds + 1;
ELSIF device.type = SNMP_DEVICE_TYPE
THEN
NUM_JOB_SNMPS_QUEUED := NUM_JOB_SNMPS_QUEUED + 1;
num_snmp := num_snmp + 1;
ELSIF device.type = PLSQL_DEVICE_TYPE
THEN
NUM_JOB_PLSQLS_QUEUED := NUM_JOB_PLSQLS_QUEUED + 1;
num_plsql := num_plsql + 1;
ELSIF device.type = JAVA_DEVICE_TYPE
THEN
NUM_JOB_JAVA_QUEUED := NUM_JOB_JAVA_QUEUED + 1;
num_java := num_java + 1;
END IF;
ELSE
-- Could not find a queue to service notification. Must be an
-- OS Command where no Windows OMSs are registered
IF emdw_log.p_is_debug_set
THEN
emdw_log.debug('QJN: No Windows OMS to handle OS Command',
CHECK_MODULE_NAME) ;
END IF ;
LOG_HISTORY(MGMT_GLOBAL.G_ANNOTATION_SOURCE_JOB,
v_state_change.state_change_guid, 'N',
'A Windows based Management Server is not registered ' ||
'(Rule Owner=' || device.owner || ', Rule Name=' ||
device.rule_name || ')', l_tz_rgn);
END IF;
ELSE
-- The device is currently down so set this up for retry
IF emdw_log.p_is_debug_set
THEN
emdw_log.debug('QJN: Device down so setup for retry',
CHECK_MODULE_NAME) ;
END IF ;
INSERT INTO mgmt_notify_requeue
(source_guid, source_type, notification_type,
device_name, device_owner, device_type, rule_name, rule_owner)
VALUES (v_state_change.state_change_guid, JOB_STATE_CHANGE,
RETRY_NOTIFICATION,
device.device_name, device.profile_name, device.type,
device.rule_name, device.owner);
END IF;
ELSE
IF emdw_log.p_is_debug_set
THEN
emdw_log.debug('QJN: ' || dname || ' is not in notification schedule',
CHECK_MODULE_NAME) ;
END IF ;
END IF;
IF (EMD_MAINTENANCE.IS_CENTRAL_MODE > 0) THEN
-- Commit/Rollback only in central repository mode.
-- In Standalone mode, this procedure is called in the severity insert
-- trigger. (Commits/Rollbacks are not allowed in triggers)
COMMIT;
END IF;
<< end_device_loop >>
NULL;
END LOOP;
IF num_emails > 0 OR num_oscmds > 0 OR num_plsql > 0 OR num_snmp > 0 OR num_java > 0
THEN
t := mgmt_global.sysdate_tzrgn(l_tz_rgn);
-- The message needs to be NLS'ed
INSERT INTO MGMT_ANNOTATION (source_obj_type, source_obj_guid, timestamp,
annotation_type, user_name, message)
VALUES (JOB_STATE_CHANGE, v_state_change.state_change_guid, t,
'NOTIFICATION',
'', 'The following notifications will be sent: ' ||
decode(num_emails, 0, '', num_emails || ' e-mail messages ') ||
decode(num_snmp, 0, '', num_snmp || ' SNMP traps ') ||
decode(num_plsql, 0, '', num_plsql || ' PL/SQL procedures ') ||
decode(num_oscmds, 0, '', num_oscmds || ' OS Commands ') ||
decode(num_java, 0, '', num_java || ' Java callbacks'));
END IF;
-- Reset the context back to the original user
SETEMUSERCONTEXT(origUser, MGMT_USER.OP_SET_IDENTIFIER);
IF (EMD_MAINTENANCE.IS_CENTRAL_MODE > 0) THEN
-- Commit/Rollback only in central repository mode.
-- In Standalone mode, this procedure is called in the
-- severity insert trigger. (Commits/Rollbacks are not allowed in triggers)
COMMIT;
END IF;
EXCEPTION
WHEN OTHERS
THEN
IF (EMD_MAINTENANCE.IS_CENTRAL_MODE > 0) THEN
-- Commit/Rollback only in central repository mode.
-- In Standalone mode, this procedure is called in the
-- severity insert trigger. (Commits/Rollbacks are not allowed in triggers)
ROLLBACK;
END IF;
-- Reset the context back to the original user
SETEMUSERCONTEXT(origUser, MGMT_USER.OP_SET_IDENTIFIER);
IF (EMD_MAINTENANCE.IS_CENTRAL_MODE > 0) THEN
-- Commit/Rollback only in central repository mode.
-- In Standalone mode, this procedure is called in the
-- severity insert trigger. (Commits/Rollbacks are not allowed in triggers)
COMMIT;
END IF;
IF emdw_log.p_is_debug_set
THEN
emdw_log.debug('QJN: Unexpected error ' || SQLERRM,
CHECK_MODULE_NAME) ;
END IF ;
mgmt_log.log_error(EMD_NOTIFICATION.CHECK_MODULE_NAME,
MGMT_GLOBAL.UNEXPECTED_ERR,
MGMT_GLOBAL.UNEXPECTED_ERR_M ||
'QUEUE_JOB_NOTIFICATIONS ('
|| pname || '/' || dname || ') ' ||
SQLERRM, 'ORA', v_state_change.state_change_guid);
END QUEUE_JOB_NOTIFICATIONS;
--
-- PURPOSE
-- This procedure gets a list of all devices that are currently in the
-- down state and have pending notifications. It queues a notification that
-- the OMS will attempt to delivery. If the delivery succeeds the OMS has
-- to call the REQUEUE procedure
--
PROCEDURE PING_DEVICES
IS
sguid RAW(16);
hash_guid RAW(16);
stype NUMBER;
rname VARCHAR2(64);
rowner VARCHAR2(256);
qname VARCHAR2(30);
qMsg MGMT_NOTIFY_NOTIFICATION;
l_device_type NUMBER := 0;
-- This only works for retries. It needs to be updated for escalation and
-- repeat notifications
CURSOR devices IS
SELECT device_name, profile_name, type, program
FROM mgmt_notify_devices d
WHERE d.status = DEVICE_DOWN AND EXISTS
(SELECT 1 FROM MGMT_NOTIFY_REQUEUE r
WHERE r.device_name = d.device_name
AND r.device_owner = d.profile_name
AND (r.notification_type = RETRY_NOTIFICATION AND
r.last_timestamp < SYSDATE - (r.num_requeues/1440)));
BEGIN
-- For each device that has notification that need to be retried
FOR device IN devices
LOOP
IF device.type NOT IN (SHORT_EMAIL_DEVICE_TYPE, LONG_EMAIL_DEVICE_TYPE) OR
DEVICE_AVAILABLE(device.device_name, device.profile_name)
THEN
-- Get the source_guid of the oldest record
SELECT r1.source_guid, r1.source_type, r1.rule_name, r1.rule_owner
INTO sguid, stype, rname, rowner
FROM MGMT_NOTIFY_REQUEUE r1
WHERE r1.device_owner = device.profile_name AND
r1.device_name = device.device_name AND
r1.insertion_timestamp =
(SELECT MIN(r2.insertion_timestamp) FROM MGMT_NOTIFY_REQUEUE r2
WHERE r2.device_owner = r1.device_owner AND
r2.device_name = r1.device_name) AND ROWNUM = 1;
BEGIN
IF stype = JOB_STATE_CHANGE
THEN
SELECT job_id INTO hash_guid FROM MGMT_JOB_STATE_CHANGES
WHERE state_change_guid = sguid;
ELSE
SELECT target_guid INTO hash_guid FROM MGMT_VIOLATIONS
WHERE violation_guid = sguid;
END IF;
EXCEPTION WHEN NO_DATA_FOUND
THEN
-- The source record is missing so remove this requeue record
DELETE FROM MGMT_NOTIFY_REQUEUE
WHERE device_name = device.device_name
AND device_owner = device.profile_name
AND source_guid = sguid
AND rule_name = rname
AND rule_owner = rowner;
GOTO next_device;
END;
IF device.type = PROGRAM_DEVICE_TYPE AND
IS_WINDOWS_PROGRAM(device.program)
THEN
l_device_type := WINDOWS_PROGRAM_DEVICE_TYPE;
ELSE
l_device_type := device.type;
END IF;
-- Get the queue name for this user/object combination
qname := GET_QUEUE(l_device_type, device.profile_name, hash_guid);
IF qname IS NOT NULL
THEN
-- Try and deliver the notification
qMsg := MGMT_NOTIFY_NOTIFICATION(RETRY_NOTIFICATION, IS_PING,
stype, sguid,
device.device_name,
device.profile_name,
device.type,
rname, rowner, qname, 0);
QUEUE(qname, qMsg);
ELSE
-- Could not find a queue to service notification. Must be an
-- OS Command where no Windows OMSs are registered
DELETE FROM MGMT_NOTIFY_REQUEUE
WHERE device_name = device.device_name
AND device_owner = device.profile_name
AND source_guid = sguid
AND rule_name = rname
AND rule_owner = rowner;
END IF;
-- Update the device to indicate a ping notification has been queued so
-- that no more are queued
UPDATE MGMT_NOTIFY_DEVICES
SET STATUS = DEVICE_BEING_PINGED,
CONTACT_TIMESTAMP = SYSDATE
WHERE device_name = device.device_name AND
profile_name = device.profile_name;
IF (EMD_MAINTENANCE.IS_CENTRAL_MODE > 0) THEN
-- Commit/Rollback only in central repository mode.
-- In Standalone mode, this procedure is called in the severity insert
-- trigger. (Commits/Rollbacks are not allowed in triggers)
COMMIT;
END IF;
END IF;
<< next_device >>
IF (EMD_MAINTENANCE.IS_CENTRAL_MODE > 0) THEN
-- Commit/Rollback only in central repository mode.
-- In Standalone mode, this procedure is called in the
-- severity insert trigger. (Commits/Rollbacks are not allowed in triggers)
COMMIT;
END IF;
END LOOP;
-- Simple mark device as DOWN and update timestamp.
UPDATE mgmt_notify_devices
set status = DEVICE_DOWN,
contact_timestamp = SYSDATE
WHERE status = DEVICE_BEING_PINGED AND
contact_timestamp < SYSDATE - ( G_DEV_PING_STATE_TIMEOUT/86400 );
IF (EMD_MAINTENANCE.IS_CENTRAL_MODE > 0) THEN
-- Commit/Rollback only in central repository mode.
-- In Standalone mode, this procedure is called in the
-- severity insert trigger. (Commits/Rollbacks are not allowed in triggers)
COMMIT;
END IF;
EXCEPTION WHEN OTHERS
THEN
mgmt_log.log_error(EMD_NOTIFICATION.CHECK_MODULE_NAME,
MGMT_GLOBAL.UNEXPECTED_ERR,
MGMT_GLOBAL.UNEXPECTED_ERR_M ||
'PING_DEVICES ' ||
SQLERRM);
END PING_DEVICES;
--
-- PURPOSE
-- To requeue all notifications for a device because the device is now
-- available again
PROCEDURE REQUEUE(v_device_name IN VARCHAR2,
v_device_owner IN VARCHAR2)
IS
qMsg MGMT_NOTIFY_NOTIFICATION;
qname VARCHAR2(30);
hash_guid RAW(16);
ttl NUMBER := 1;
l_program VARCHAR2(512);
l_device_type NUMBER := 0;
CURSOR retries
IS
SELECT source_guid, source_type, device_name, device_owner, device_type,
rule_name, rule_owner, insertion_timestamp
FROM mgmt_notify_requeue
WHERE device_name = v_device_name AND
device_owner = v_device_owner AND
notification_type = RETRY_NOTIFICATION
ORDER BY insertion_timestamp ASC;
BEGIN
-- Make sure to check the device is available
IF NOT DEVICE_AVAILABLE(v_device_name, v_device_owner)
THEN
RETURN;
END IF;
-- Get the time to live of the notifications for this user
SELECT notification_ttl INTO ttl FROM MGMT_NOTIFY_PROFILES
WHERE profile_name = v_device_owner;
FOR r IN retries
LOOP
-- Check if the entry has been in the table more than a day and if so
-- remove it
IF r.insertion_timestamp < SYSDATE - ttl
THEN
DELETE FROM mgmt_notify_requeue
WHERE device_name = r.device_name
AND device_owner = r.device_owner
AND source_guid = r.source_guid
AND rule_name = r.rule_name
AND rule_owner = r.rule_owner;
ELSE
BEGIN
IF r.source_type = JOB_STATE_CHANGE
THEN
SELECT job_id INTO hash_guid FROM MGMT_JOB_STATE_CHANGES
WHERE state_change_guid = r.source_guid;
ELSE
SELECT target_guid INTO hash_guid FROM MGMT_VIOLATIONS
WHERE violation_guid = r.source_guid;
END IF;
EXCEPTION WHEN NO_DATA_FOUND
THEN
-- The source record is missing so remove this requeue record
DELETE FROM MGMT_NOTIFY_REQUEUE
WHERE device_name = r.device_name
AND device_owner = r.device_owner
AND source_guid = r.source_guid
AND rule_name = r.rule_name
AND rule_owner = r.rule_owner;
GOTO next_retry;
END;
IF r.device_type = PROGRAM_DEVICE_TYPE
THEN
SELECT program INTO l_program FROM MGMT_NOTIFY_DEVICES
WHERE device_name = r.device_name AND profile_name = r.device_owner;
IF IS_WINDOWS_PROGRAM(l_program)
THEN
l_device_type := WINDOWS_PROGRAM_DEVICE_TYPE;
ELSE
l_device_type := r.device_type;
END IF;
ELSE
l_device_type := r.device_type;
END IF;
-- Get the queue name for this user/object combination
qname := GET_QUEUE(l_device_type, r.device_owner, hash_guid);
IF qname IS NOT NULL
THEN
qMsg := MGMT_NOTIFY_NOTIFICATION(RETRY_NOTIFICATION, 0,
r.source_type, r.source_guid,
r.device_name, r.device_owner,
r.device_type,
r.rule_name, r.rule_owner, qname, 0);
QUEUE(qname, qMsg);
DELETE FROM mgmt_notify_requeue
WHERE device_name = r.device_name
AND device_owner = r.device_owner
AND source_guid = r.source_guid
AND rule_name = r.rule_name
AND rule_owner = r.rule_owner;
ELSE
-- Could not find a queue to service notification. Must be an
-- OS Command where no Windows OMSs are registered
DELETE FROM MGMT_NOTIFY_REQUEUE
WHERE device_name = r.device_name
AND device_owner = r.device_owner
AND source_guid = r.source_guid
AND rule_name = r.rule_name
AND rule_owner = r.rule_owner;
END IF;
END IF;
<< next_retry >>
COMMIT;
END LOOP;
END REQUEUE;
PROCEDURE DBMSJOB_EXTENDED_SQL_TRACE_ON(p_value IN BOOLEAN) IS
BEGIN
MGMT_SQLTRACE.EXTENDED_SQL_TRACE_ON(EST_NOTIFICATION_NAME, p_value);
END DBMSJOB_EXTENDED_SQL_TRACE_ON;
-- PURPOSE
-- Main procedure to go through severity table, execute notification rules
-- and queue notifications for delivery. This should be called from a
-- DBMS_JOB that is running on a specified interval
PROCEDURE CHECK_FOR_SEVERITIES
IS
job_id NUMBER;
perf_start TIMESTAMP;
sev_duration INTERVAL DAY TO SECOND;
job_duration INTERVAL DAY TO SECOND;
nSeverities NUMBER := 0;
nStateChanges NUMBER := 0;
total_queued NUMBER := 0;
severity MGMT_VIOLATIONS%ROWTYPE;
state_change MGMT_JOB_STATE_CHANGES%ROWTYPE;
ca_severity MGMT_VIOLATIONS%ROWTYPE;
guid_type VARCHAR2(1);
notif_src_guid RAW(16);
last_run DATE;
this_run DATE;
l_rule_guid RAW(16);
l_repeat_count NUMBER;
CURSOR job_ids IS
SELECT job FROM USER_JOBS
WHERE what = 'EMD_NOTIFICATION.CHECK_FOR_SEVERITIES();';
BEGIN
MGMT_SQLTRACE.EXTENDED_SQL_TRACE(EST_NOTIFICATION_NAME);
EMDW_LOG.SET_CONTEXT(v_context_Type=>G_LOG_CONTEXT,
v_context_Identifier=>'dbms_job');
BEGIN
SELECT last_date, this_date INTO last_run, this_run from USER_JOBS
WHERE what = 'EMD_NOTIFICATION.CHECK_FOR_SEVERITIES();';
EXCEPTION
WHEN TOO_MANY_ROWS
THEN
-- There should never be more than one job running this routine
OPEN job_ids;
FETCH job_ids INTO job_id;
CLOSE job_ids;
DBMS_JOB.REMOVE(job_id);
RETURN;
WHEN OTHERS
THEN
BEGIN
last_run := SYSDATE;
this_run := SYSDATE;
END;
END;
IF last_run IS NULL
THEN
-- It will only be NULL the first time the job runs
last_run := SYSDATE;
END IF;
IF this_run IS NULL
THEN
-- It should never be null
this_run := SYSDATE;
END IF;
-- Queue a notification for any device that is currently down that has
-- pending retries. Note that this procedure will only
-- attempt to queue one notification (i.e. if there are multiple retries,
-- only one will be queued) and update the status accordingly.
-- The procedure REQUEUE will be called from the OMS once the message has
-- been delivered which will result in all pending notifications being
-- queued
PING_DEVICES();
perf_start := LOCALTIMESTAMP;
sev_duration := perf_start - perf_start;
job_duration := perf_start - perf_start;
-- log job run details
IF EMDW_LOG.P_IS_INFO_SET
THEN
EMDW_LOG.INFO('(sysdate, last_run, this_run) = (' ||
to_char(sysdate, 'mm/dd/yyyy hh24:mi:ss') || ', ' ||
to_char(last_run, 'mm/dd/yyyy hh24:mi:ss') || ', ' ||
to_char(this_run, 'mm/dd/yyyy hh24:mi:ss') || ', ' ||
')', 'check_for_severities');
END IF;
-- Go through each severity record and apply the notification rules
WHILE TRUE
LOOP
BEGIN
perf_start := LOCALTIMESTAMP;
dequeue_notif_input(notif_src_guid, guid_type, l_rule_guid, l_repeat_count);
IF guid_type = GUID_TYPE_SEVERITY
THEN
nSeverities := nSeverities + 1;
SELECT *
INTO severity
FROM mgmt_violations
WHERE violation_guid = notif_src_guid;
QUEUE_METRIC_NOTIFICATIONS(severity);
ELSIF guid_type = GUID_TYPE_JOB_STATE_CHANGE
THEN
nStateChanges := nStateChanges + 1;
SELECT *
INTO state_change
FROM mgmt_job_state_changes
WHERE state_change_guid = notif_src_guid;
IF state_change.type = JOB_STATE_CHANGE
THEN
QUEUE_JOB_NOTIFICATIONS(state_change);
ELSE
BEGIN
SELECT * INTO ca_severity FROM MGMT_VIOLATIONS
WHERE violation_guid = state_change.violation_guid;
QUEUE_METRIC_NOTIFICATIONS(ca_severity, state_change);
EXCEPTION
WHEN NO_DATA_FOUND
THEN
IF EMDW_LOG.P_IS_DEBUG_SET
THEN
EMDW_LOG.DEBUG('Severity record already deleted for state change job record : ' || notif_src_guid,
'check_for_severities');
END IF;
END;
END IF;
ELSIF guid_type = GUID_TYPE_REP_SEVERITY
THEN
CHK_AND_QUEUE_REP_NOTIF(notif_src_guid, l_rule_guid, l_repeat_count);
END IF;
EXCEPTION
WHEN NO_DATA_FOUND
THEN
IF EMDW_LOG.P_IS_DEBUG_SET
THEN
EMDW_LOG.DEBUG('Got NO_DATA_FOUND while processing the record notif_src_guid : ' || notif_src_guid ||
' guid_type : ' || guid_type || ' Skipping this record', 'check_for_severities');
END IF;
-- commit the dequeue operation
COMMIT;
WHEN OTHERS
THEN
-- exit the loop if there is no message in the queue
IF SQLCODE = QUEUE_TIMEOUT
THEN
exit;
ELSE
mgmt_log.log_error(EMD_NOTIFICATION.CHECK_MODULE_NAME,
MGMT_GLOBAL.UNEXPECTED_ERR,
MGMT_GLOBAL.UNEXPECTED_ERR_M || 'CHECK_FOR_SEVERITIES. '
|| SQLERRM);
-- commit the dequeue operation
COMMIT;
exit;
END IF;
END;
IF guid_type = GUID_TYPE_SEVERITY
THEN
sev_duration := sev_duration + LOCALTIMESTAMP - perf_start;
ELSE
job_duration := job_duration + LOCALTIMESTAMP - perf_start;
END IF;
END LOOP;
-- Log the stats for severities handled and number of notifications queued
IF nSeverities > 0
THEN
mgmt_log.log_performance(EMD_NOTIFICATION.CHECK_MODULE_NAME, get_millisec_from_interval(sev_duration),
SYSDATE, 'Y', PERF_NUM_SEVERITIES_CHECKED,
nSeverities);
END IF;
total_queued := NUM_EMAILS_QUEUED + NUM_OSCMDS_QUEUED + NUM_PLSQLS_QUEUED +
NUM_SNMPS_QUEUED + NUM_RCAS_QUEUED + NUM_JAVA_QUEUED;
IF total_queued > 0
THEN
mgmt_log.log_performance(EMD_NOTIFICATION.CHECK_MODULE_NAME,
(TOTAL_ENQUEUE_TIME * (24 * 60 * 60 * 1000)),
SYSDATE, 'Y', PERF_NUM_QUEUED,
total_queued);
END IF;
IF NUM_EMAILS_QUEUED > 0
THEN
mgmt_log.log_performance(EMD_NOTIFICATION.CHECK_MODULE_NAME, 0,
SYSDATE, 'N', PERF_NUM_EMAILS_QUEUED,
NUM_EMAILS_QUEUED);
END IF;
IF NUM_OSCMDS_QUEUED > 0
THEN
mgmt_log.log_performance(EMD_NOTIFICATION.CHECK_MODULE_NAME, 0,
SYSDATE, 'N', PERF_NUM_OSCMDS_QUEUED,
NUM_OSCMDS_QUEUED);
END IF;
IF NUM_PLSQLS_QUEUED > 0
THEN
mgmt_log.log_performance(EMD_NOTIFICATION.CHECK_MODULE_NAME, 0,
SYSDATE, 'N', PERF_NUM_PLSQLS_QUEUED,
NUM_PLSQLS_QUEUED);
END IF;
IF NUM_SNMPS_QUEUED > 0
THEN
mgmt_log.log_performance(EMD_NOTIFICATION.CHECK_MODULE_NAME, 0,
SYSDATE, 'N', PERF_NUM_SNMPS_QUEUED,
NUM_SNMPS_QUEUED);
END IF;
IF NUM_JAVA_QUEUED > 0
THEN
mgmt_log.log_performance(EMD_NOTIFICATION.CHECK_MODULE_NAME, 0,
SYSDATE, 'N', PERF_NUM_JAVA_QUEUED,
NUM_JAVA_QUEUED);
END IF;
-- Log the stats for state changes handled and number of notifications queued
IF nStateChanges > 0
THEN
mgmt_log.log_performance(EMD_NOTIFICATION.CHECK_MODULE_NAME, get_millisec_from_interval(sev_duration),
SYSDATE, 'Y', PERF_NUM_JOBSTATES_CHECKED,
nStateChanges);
END IF;
total_queued := NUM_JOB_EMAILS_QUEUED + NUM_JOB_OSCMDS_QUEUED +
NUM_JOB_PLSQLS_QUEUED + NUM_JOB_SNMPS_QUEUED + NUM_JOB_JAVA_QUEUED;
IF total_queued > 0
THEN
mgmt_log.log_performance(EMD_NOTIFICATION.CHECK_MODULE_NAME,
(TOTAL_JOB_ENQUEUE_TIME * (24 * 60 * 60 * 1000)),
SYSDATE, 'Y', PERF_NUM_JOB_QUEUED,
total_queued);
END IF;
IF NUM_JOB_EMAILS_QUEUED > 0
THEN
mgmt_log.log_performance(EMD_NOTIFICATION.CHECK_MODULE_NAME, 0,
SYSDATE, 'N', PERF_NUM_JOB_EMAILS_QUEUED,
NUM_JOB_EMAILS_QUEUED);
END IF;
IF NUM_JOB_OSCMDS_QUEUED > 0
THEN
mgmt_log.log_performance(EMD_NOTIFICATION.CHECK_MODULE_NAME, 0,
SYSDATE, 'N', PERF_NUM_JOB_OSCMDS_QUEUED,
NUM_JOB_OSCMDS_QUEUED);
END IF;
IF NUM_JOB_PLSQLS_QUEUED > 0
THEN
mgmt_log.log_performance(EMD_NOTIFICATION.CHECK_MODULE_NAME, 0,
SYSDATE, 'N', PERF_NUM_JOB_PLSQLS_QUEUED,
NUM_JOB_PLSQLS_QUEUED);
END IF;
IF NUM_JOB_SNMPS_QUEUED > 0
THEN
mgmt_log.log_performance(EMD_NOTIFICATION.CHECK_MODULE_NAME, 0,
SYSDATE, 'N', PERF_NUM_JOB_SNMPS_QUEUED,
NUM_JOB_SNMPS_QUEUED);
END IF;
IF NUM_JOB_JAVA_QUEUED > 0
THEN
mgmt_log.log_performance(EMD_NOTIFICATION.CHECK_MODULE_NAME, 0,
SYSDATE, 'N', PERF_NUM_JOB_JAVA_QUEUED,
NUM_JOB_JAVA_QUEUED);
END IF;
COMMIT;
EXCEPTION
WHEN OTHERS
THEN
ROLLBACK;
-- If we got a snapshot too old error because the query to get the
-- severities ran for too long due to the amount of time spent
-- processing and queuing notifications. Just return and the job
-- will run again
IF SQLCODE <> -1555
THEN
mgmt_log.log_error(EMD_NOTIFICATION.CHECK_MODULE_NAME,
MGMT_GLOBAL.UNEXPECTED_ERR,
MGMT_GLOBAL.UNEXPECTED_ERR_M || 'CHECK_FOR_SEVERITIES. '
|| SQLERRM);
END IF;
END CHECK_FOR_SEVERITIES;
PROCEDURE CLEANUP_ADMIN_NOTIFICATIONS
IS
dq_options dbms_aq.dequeue_options_t;
qMsg_properties dbms_aq.message_properties_t;
admin_msgid RAW(16);
qMsg MGMT_NOTIFY_NOTIFICATION;
BEGIN
-- NOTE: This should only be run once the MGMT_NOTIFY_QUEUES has
-- been locked
IF G_RECURSIVE_CLEANUP
THEN
RETURN;
END IF;
-- Cleanup any old admin messages for OMSs that have gone away. This
-- should not be necessary if the failover callback is reliably issued
-- for each OMS that goes down
FOR n IN (SELECT DISTINCT msg_id, consumer_name FROM aq$mgmt_notify_qtable
WHERE msg_state = 'READY'
AND consumer_name LIKE 'ADM%'
AND consumer_name NOT IN (SELECT 'ADM'||failover_id
FROM MGMT_FAILOVER_TABLE))
LOOP
dq_options.consumer_name := n.consumer_name;
dq_options.msgid := n.msg_id;
BEGIN
DBMS_AQ.DEQUEUE(queue_name => G_QUEUE_NAME,
dequeue_options => dq_options,
message_properties => qMsg_properties,
payload => qMsg,
msgid => admin_msgid);
EXCEPTION
WHEN OTHERS
THEN
NULL;
END;
END LOOP;
-- Unassign any queues for OMSs not in the failover table
FOR oms IN (SELECT DISTINCT oms_id FROM MGMT_NOTIFY_QUEUES
WHERE oms_id <> 0
AND oms_id NOT IN (SELECT failover_id FROM MGMT_FAILOVER_TABLE))
LOOP
G_RECURSIVE_CLEANUP := TRUE;
UNREGISTER_OMS(oms.oms_id);
G_RECURSIVE_CLEANUP := FALSE;
END LOOP;
EXCEPTION
WHEN OTHERS
THEN
G_RECURSIVE_CLEANUP := FALSE;
raise;
END CLEANUP_ADMIN_NOTIFICATIONS;
PROCEDURE REGISTER_OMS(oms_id_in IN NUMBER,
admin_qname_out OUT VARCHAR2,
windows_in IN NUMBER DEFAULT 0)
IS
admin_qname VARCHAR2(30);
nqueues NUMBER;
nqueues_per_oms NUMBER;
noms NUMBER;
num_available NUMBER;
num_reassigned NUMBER := 0;
num_this_oms_reassigned NUMBER := 0;
old_qname VARCHAR2(30);
oms_ids SMP_EMD_INTEGER_ARRAY;
qs_handled SMP_EMD_INTEGER_ARRAY;
qMsg MGMT_NOTIFY_NOTIFICATION;
device_types SMP_EMD_STRING_ARRAY := SMP_EMD_STRING_ARRAY('EMAIL%', 'OSCMD%',
'PLSQL%', 'SNMP%',
'JAVA%');
BEGIN
admin_qname := 'ADM' || oms_id_in;
admin_qname_out := admin_qname;
-- Lock the queue table
LOCK TABLE MGMT_NOTIFY_QUEUES IN EXCLUSIVE MODE;
-- Cleanup any old admin messages for OMSs that have gone away. This
-- should not be necessary if the failover callback is reliably issued
-- for each OMS that goes down
CLEANUP_ADMIN_NOTIFICATIONS;
-- Get the OMS names and the number of queues they are handling
SELECT oms_id, count(qname) nqs_handled
BULK COLLECT INTO oms_ids, qs_handled
FROM MGMT_NOTIFY_QUEUES WHERE oms_id <> 0
GROUP BY oms_id
ORDER BY nqs_handled desc;
noms := oms_ids.COUNT;
-- If there are no OMSs registered then assign all the queues to this OMS
IF noms = 0
THEN
UPDATE MGMT_NOTIFY_QUEUES SET oms_id = oms_id_in,
windows = windows_in;
FOR q IN (SELECT qname FROM MGMT_NOTIFY_QUEUES)
LOOP
qMsg := MGMT_NOTIFY_NOTIFICATION(START_DEQUEUEING, 0, -1, NULL,
q.qname, oms_id_in, QUEUE_DEVICE_TYPE,
NULL, NULL, admin_qname, 0);
QUEUE(admin_qname, qMsg);
END LOOP;
COMMIT;
RETURN;
END IF;
-- Get the total number of queues
SELECT COUNT(qname) INTO nqueues FROM MGMT_NOTIFY_QUEUES;
-- Work out how many queues there should be per OMS
nqueues_per_oms := trunc(nqueues / (noms + 1));
IF nqueues_per_oms = 0
THEN
COMMIT;
RETURN;
END IF;
-- Go through each current OMS and update the queues it is handling
FOR i IN oms_ids.FIRST..oms_ids.LAST
LOOP
-- If enough queues have been reassigned then finish
IF num_reassigned >= nqueues_per_oms
THEN
COMMIT;
RETURN;
END IF;
-- Work out how many queues this OMS can reassign
num_available := qs_handled(i) - nqueues_per_oms;
-- If it can spare more than necessary then limit it so a queue is not
-- reassigned unnecessarily
IF num_available > nqueues_per_oms
THEN
num_available := nqueues_per_oms;
END IF;
-- Make sure there are some available for reassigning
IF num_available > 0
THEN
-- Try and spread the different queue types across OMSs so that each
-- one is handling a variety of device types
num_this_oms_reassigned := 0;
WHILE (num_this_oms_reassigned < num_available)
LOOP
FOR dt IN (SELECT column_value FROM
(TABLE(CAST(device_types AS SMP_EMD_STRING_ARRAY))))
LOOP
IF num_this_oms_reassigned = num_available
THEN
EXIT;
END IF;
BEGIN
-- Get the qname being ressigned
SELECT qname INTO old_qname FROM MGMT_NOTIFY_QUEUES
WHERE oms_id = oms_ids(i) AND qname LIKE dt.column_value
AND rownum < 2;
-- Reassign the names
UPDATE MGMT_NOTIFY_QUEUES SET oms_id = oms_id_in,
windows = windows_in
WHERE qname = old_qname;
-- Tell the OMS to stop monitoring the queue
qMsg := MGMT_NOTIFY_NOTIFICATION(STOP_DEQUEUEING, 0, -1, NULL,
old_qname, oms_ids(i),
QUEUE_DEVICE_TYPE, NULL, NULL,
'ADM' || oms_ids(i), 0);
QUEUE('ADM' || oms_ids(i), qMsg);
qMsg := MGMT_NOTIFY_NOTIFICATION(START_DEQUEUEING, 0, -1, NULL,
old_qname, oms_id_in,
QUEUE_DEVICE_TYPE, NULL, NULL,
admin_qname, 0);
QUEUE(admin_qname, qMsg);
-- Update total
num_reassigned := num_reassigned + 1;
num_this_oms_reassigned := num_this_oms_reassigned + 1;
EXCEPTION WHEN NO_DATA_FOUND THEN
NULL;
END;
END LOOP;
END LOOP;
END IF;
END LOOP;
COMMIT;
EXCEPTION
WHEN NO_DATA_FOUND
THEN
ROLLBACK;
END REGISTER_OMS;
-- PURPOSE
-- To unregister an OMS from the notification system so that its queues
-- can be reassigned
PROCEDURE UNREGISTER_OMS(oms_id_in IN NUMBER)
IS
BEGIN
OMS_FAILOVER(oms_id_in, SYSDATE);
END UNREGISTER_OMS;
-- PURPOSE
-- To handle failover when an OMS goes down
PROCEDURE OMS_FAILOVER(oms_id_in IN NUMBER,
last_timestamp_in IN DATE)
IS
noms NUMBER;
num_reassigned NUMBER := 0;
num_for_reassignment NUMBER := 0;
new_qname VARCHAR2(30);
oms_ids SMP_EMD_INTEGER_ARRAY;
qs_handled SMP_EMD_INTEGER_ARRAY;
is_windows SMP_EMD_INTEGER_ARRAY;
qMsg MGMT_NOTIFY_NOTIFICATION;
more_messages BOOLEAN := TRUE;
admin_msgid RAW(16);
BEGIN
-- Remove any messages in the queue for this OMS's admin queue
WHILE (more_messages)
LOOP
BEGIN
DEQUEUE('ADM' || oms_id_in, 1, admin_msgid, qMsg);
EXCEPTION
WHEN OTHERS
THEN
more_messages := FALSE;
END;
END LOOP;
-- Lock the queue table
LOCK TABLE MGMT_NOTIFY_QUEUES IN EXCLUSIVE MODE;
-- Unassign the queues for this OMS
UPDATE MGMT_NOTIFY_QUEUES SET oms_id = 0, windows = 0
WHERE oms_id = oms_id_in;
-- Cleanup any old admin messages for OMSs that have gone away. This
-- should not be necessary if the failover callback is reliably issued
-- for each OMS that goes down
CLEANUP_ADMIN_NOTIFICATIONS;
-- Get the OMS names and the number of queues they are handling
SELECT oms_id, count(qname) nqs_handled, sum(windows)
BULK COLLECT INTO oms_ids, qs_handled, is_windows
FROM MGMT_NOTIFY_QUEUES WHERE oms_id <> 0
GROUP BY oms_id
ORDER BY nqs_handled asc;
noms := oms_ids.COUNT;
-- If there are no OMSs registered then just return
IF noms = 0
THEN
RETURN;
END IF;
-- Get the total number of queues and the number for reassigment
SELECT COUNT(qname) INTO num_for_reassignment FROM MGMT_NOTIFY_QUEUES
WHERE oms_id = 0;
WHILE num_reassigned < num_for_reassignment
LOOP
-- Go through each current OMS and assign it some queues
FOR i IN oms_ids.FIRST..oms_ids.LAST
LOOP
IF num_reassigned = num_for_reassignment
THEN
RETURN;
END IF;
-- Get the qnames being ressigned
SELECT qname INTO new_qname
FROM MGMT_NOTIFY_QUEUES
WHERE oms_id = 0 AND rownum < 2;
-- Reassign the names
IF is_windows(i) > 0
THEN
UPDATE MGMT_NOTIFY_QUEUES SET oms_id = oms_ids(i), windows = 1
WHERE qname = new_qname;
ELSE
UPDATE MGMT_NOTIFY_QUEUES SET oms_id = oms_ids(i), windows = 0
WHERE qname = new_qname;
END IF;
-- Tell the OMS to start servicing the new queue by sending a message
-- on its admin queue
qMsg := MGMT_NOTIFY_NOTIFICATION(START_DEQUEUEING, 0, -1, NULL,
new_qname, oms_ids(i),
QUEUE_DEVICE_TYPE, NULL, NULL,
'ADM' || oms_ids(i), 0);
QUEUE('ADM' || oms_ids(i), qMsg);
-- Update total
num_reassigned := num_reassigned + 1;
END LOOP;
END LOOP;
EXCEPTION
WHEN OTHERS THEN
MGMT_LOG.log_error(DELIVER_MODULE_NAME, SQLCODE,
'Error during failover: ' || SQLERRM);
raise;
END OMS_FAILOVER;
-- PURPOSE
-- Set the number of notification queues
--
-- PARAMETERS
--
PROCEDURE SET_NUMBER_QUEUES(
v_num_email_qs IN NUMBER DEFAULT DEFAULT_NOTIFY_EMAIL_QUEUES,
v_num_oscmd_qs IN NUMBER DEFAULT DEFAULT_NOTIFY_OSCMD_QUEUES,
v_num_plsql_qs IN NUMBER DEFAULT DEFAULT_NOTIFY_PLSQL_QUEUES,
v_num_snmp_qs IN NUMBER DEFAULT DEFAULT_NOTIFY_SNMP_QUEUES,
v_num_java_qs IN NUMBER DEFAULT DEFAULT_NOTIFY_JAVA_QUEUES)
IS
BEGIN
NULL;
END SET_NUMBER_QUEUES;
FUNCTION GET_PARAMETER_FORMATS(v_device_name IN VARCHAR2,
v_device_owner IN VARCHAR2)
RETURN MGMT_NOTIFY_PARAMETER_FORMATS
IS
formats MGMT_NOTIFY_PARAMETER_FORMATS;
BEGIN
-- Get the parameters that should be included in the notifications
SELECT MGMT_NOTIFY_PARAMETER_FORMAT(parameter, abbreviated, timestamp_format)
BULK COLLECT INTO formats
FROM MGMT_NOTIFY_DEVICE_PARAMS
WHERE device_name = v_device_name AND profile_name = v_device_owner AND
parameter LIKE '$%'
ORDER BY position;
-- If no parameter customization has been done, then send all the parameters
IF formats.COUNT = 0
THEN
formats.extend(12);
formats(1) := MGMT_NOTIFY_PARAMETER_FORMAT('$TARGET_NAME', 0, NULL);
formats(2) := MGMT_NOTIFY_PARAMETER_FORMAT('$TARGET_TYPE', 0, NULL);
formats(3) := MGMT_NOTIFY_PARAMETER_FORMAT('$HOST', 0, NULL);
formats(4) := MGMT_NOTIFY_PARAMETER_FORMAT('$METRIC', 0, NULL);
formats(5) := MGMT_NOTIFY_PARAMETER_FORMAT('$METRIC_DESCRIPTION', 0, NULL);
formats(6) := MGMT_NOTIFY_PARAMETER_FORMAT('$KEY_VALUE', 0, NULL);
formats(7) := MGMT_NOTIFY_PARAMETER_FORMAT('$TIMESTAMP', 0, NULL);
formats(8) := MGMT_NOTIFY_PARAMETER_FORMAT('$SEVERITY', 0, NULL);
formats(9) := MGMT_NOTIFY_PARAMETER_FORMAT('$MESSAGE', 0, NULL);
formats(10) := MGMT_NOTIFY_PARAMETER_FORMAT('$RULE_NAME', 0, NULL);
formats(11) := MGMT_NOTIFY_PARAMETER_FORMAT('$RULE_OWNER', 0, NULL);
END IF;
RETURN formats;
END GET_PARAMETER_FORMATS;
-- PURPOSE
-- To get the label for a key column belonging to the metric in a severity
--
FUNCTION GET_KEYS(v_metric_guid IN RAW,
v_target_guid IN RAW,
v_key_value_in IN VARCHAR2)
RETURN MGMT_NOTIFY_COLUMNS
IS
kcol VARCHAR2(512);
key VARCHAR2(64);
pos NUMBER;
lpos NUMBER;
label VARCHAR2(64);
nlsid VARCHAR2(64);
nkeys NUMBER;
checking boolean;
keys MGMT_NOTIFY_COLUMNS := MGMT_NOTIFY_COLUMNS();
p1 VARCHAR2(256);
p2 VARCHAR2(256);
p3 VARCHAR2(256);
p4 VARCHAR2(256);
p5 VARCHAR2(256);
key_val VARCHAR2(256);
BEGIN
IF v_key_value_in = ' '
THEN
RETURN NULL;
END IF;
-- Get the metric name and column
SELECT key_column INTO kcol
FROM MGMT_TARGETS t, MGMT_METRICS m
WHERE t.target_guid = v_target_guid
AND m.metric_guid = v_metric_guid
AND t.target_type = m.target_type
AND m.type_meta_ver = t.type_meta_ver
AND (m.category_prop_1 = t.category_prop_1 or m.category_prop_1 = ' ')
AND (m.category_prop_2 = t.category_prop_2 or m.category_prop_2 = ' ')
AND (m.category_prop_3 = t.category_prop_3 or m.category_prop_3 = ' ')
AND (m.category_prop_4 = t.category_prop_4 or m.category_prop_4 = ' ')
AND (m.category_prop_5 = t.category_prop_5 or m.category_prop_5 = ' ');
BEGIN
-- Check it this is a composite key
SELECT key_part1_value, key_part2_value, key_part3_value,
key_part4_value, key_part5_value
INTO p1, p2, p3, p4, p5
FROM MGMT_METRICS_COMPOSITE_KEYS
WHERE composite_key = v_key_value_in
AND target_guid = v_target_guid;
EXCEPTION WHEN NO_DATA_FOUND
THEN
-- Not a composite key, so get the details of the key column
SELECT m1.column_label, m1.column_label_nlsid
INTO label, nlsid
FROM MGMT_TARGETS t, MGMT_METRICS m, MGMT_METRICS m1
WHERE t.target_guid = v_target_guid
AND m.metric_guid = v_metric_guid
AND t.target_type = m.target_type
AND m.type_meta_ver = t.type_meta_ver
AND (m.category_prop_1 = t.category_prop_1 or m.category_prop_1 = ' ')
AND (m.category_prop_2 = t.category_prop_2 or m.category_prop_2 = ' ')
AND (m.category_prop_3 = t.category_prop_3 or m.category_prop_3 = ' ')
AND (m.category_prop_4 = t.category_prop_4 or m.category_prop_4 = ' ')
AND (m.category_prop_5 = t.category_prop_5 or m.category_prop_5 = ' ')
AND t.target_type = m1.target_type
AND m1.type_meta_ver = t.type_meta_ver
AND (m1.category_prop_1 = t.category_prop_1 or m1.category_prop_1 = ' ')
AND (m1.category_prop_2 = t.category_prop_2 or m1.category_prop_2 = ' ')
AND (m1.category_prop_3 = t.category_prop_3 or m1.category_prop_3 = ' ')
AND (m1.category_prop_4 = t.category_prop_4 or m1.category_prop_4 = ' ')
AND (m1.category_prop_5 = t.category_prop_5 or m1.category_prop_5 = ' ')
AND m1.metric_name = m.metric_name
AND m1.metric_column = kcol;
IF label IS NULL OR label = ' '
THEN
label := key;
END IF;
keys.extend;
keys(1) := MGMT_NOTIFY_COLUMN(label, nlsid, v_key_value_in);
RETURN keys;
END;
nkeys := 1;
lpos := 0;
checking := true;
WHILE checking
LOOP
pos := INSTR(kcol,';', 1, nkeys);
IF pos = 0
THEN
checking := false;
pos := LENGTH(kcol) + 1;
END IF;
key := SUBSTR(kcol, lpos+1, pos-lpos-1);
SELECT m1.column_label, m1.column_label_nlsid
INTO label, nlsid
FROM MGMT_TARGETS t, MGMT_METRICS m, MGMT_METRICS m1
WHERE t.target_guid = v_target_guid
AND m.metric_guid = v_metric_guid
AND t.target_type = m.target_type
AND m.type_meta_ver = t.type_meta_ver
AND (m.category_prop_1 = t.category_prop_1 or m.category_prop_1 = ' ')
AND (m.category_prop_2 = t.category_prop_2 or m.category_prop_2 = ' ')
AND (m.category_prop_3 = t.category_prop_3 or m.category_prop_3 = ' ')
AND (m.category_prop_4 = t.category_prop_4 or m.category_prop_4 = ' ')
AND (m.category_prop_5 = t.category_prop_5 or m.category_prop_5 = ' ')
AND t.target_type = m1.target_type
AND m1.type_meta_ver = t.type_meta_ver
AND (m1.category_prop_1 = t.category_prop_1 or m1.category_prop_1 = ' ')
AND (m1.category_prop_2 = t.category_prop_2 or m1.category_prop_2 = ' ')
AND (m1.category_prop_3 = t.category_prop_3 or m1.category_prop_3 = ' ')
AND (m1.category_prop_4 = t.category_prop_4 or m1.category_prop_4 = ' ')
AND (m1.category_prop_5 = t.category_prop_5 or m1.category_prop_5 = ' ')
AND m1.metric_name = m.metric_name
AND m1.metric_column = key;
IF nkeys = 1 THEN key_val := p1;
ELSIF nkeys = 2 THEN key_val := p2;
ELSIF nkeys = 3 THEN key_val := p3;
ELSIF nkeys = 4 THEN key_val := p4;
ELSIF nkeys = 5 THEN key_val := p5;
END IF;
IF label IS NULL OR label = ' '
THEN
label := key;
END IF;
keys.extend;
keys(keys.COUNT) := MGMT_NOTIFY_COLUMN(label, nlsid, key_val);
lpos := pos;
nkeys := nkeys + 1;
END LOOP;
RETURN keys;
EXCEPTION WHEN NO_DATA_FOUND
THEN
RETURN NULL;
END GET_KEYS;
-- PURPOSE
-- Procedure to specify one or more SMTP gateways
--
PROCEDURE SET_EMAIL_GATEWAYS(v_gateways IN MGMT_MEDIUM_STRING_ARRAY,
v_smtp_ports IN MGMT_INTEGER_ARRAY,
v_email_address IN VARCHAR2,
v_email_name IN VARCHAR2,
v_smtp_user IN VARCHAR2 DEFAULT '',
v_smtp_pwd IN VARCHAR2 DEFAULT '')
IS
BEGIN
-- Make sure some gateways have been entered
IF v_gateways IS NULL OR v_gateways.COUNT = 0
THEN
raise_application_error(MGMT_GLOBAL.NOTIFICATION_NOGATEWAY_ERR,
MGMT_GLOBAL.NOTIFICATION_NOGATEWAY_ERR_MSG);
END IF;
DELETE FROM mgmt_notify_email_gateway;
FOR i IN v_gateways.FIRST..v_gateways.LAST
LOOP
INSERT INTO mgmt_notify_email_gateway (MAIL_HOST, SMTP_PORT, EMAIL_ADDRESS,
EMAIL_NAME, SMTP_USER, SMTP_PWD,
PRECEDENCE)
VALUES (v_gateways(i), v_smtp_ports(i), v_email_address, v_email_name,
v_smtp_user, ENCRYPT(v_smtp_pwd), i);
END LOOP;
END SET_EMAIL_GATEWAYS;
-- PURPOSE
-- Procedure to specify a number of email gateways.
--
PROCEDURE SET_EMAIL_GATEWAYS(v_gateways IN SMP_EMD_STRING_ARRAY,
v_email_address IN VARCHAR2,
v_email_name IN VARCHAR2)
IS
BEGIN
-- Make sure some gateways have been entered
IF v_gateways IS NULL OR v_gateways.COUNT = 0
THEN
raise_application_error(MGMT_GLOBAL.NOTIFICATION_NOGATEWAY_ERR,
MGMT_GLOBAL.NOTIFICATION_NOGATEWAY_ERR_MSG);
END IF;
DELETE FROM mgmt_notify_email_gateway;
FOR i IN v_gateways.FIRST..v_gateways.LAST
LOOP
INSERT INTO mgmt_notify_email_gateway (MAIL_HOST, EMAIL_ADDRESS,
EMAIL_NAME, PRECEDENCE)
VALUES (v_gateways(i), v_email_address, v_email_name, i);
END LOOP;
END SET_EMAIL_GATEWAYS;
-- Procedure to add an administrator profile. This will raise an exception
-- if there is already a profile with the same name
PROCEDURE ADD_ADMIN_PROFILE(v_profile_name IN VARCHAR2,
v_description IN VARCHAR2)
IS
BEGIN
INSERT INTO mgmt_notify_profiles (PROFILE_NAME, DESCRIPTION)
VALUES (UPPER(v_profile_name), v_description);
END ADD_ADMIN_PROFILE;
-- PURPOSE
-- Procedure to add the name of an administrator profile that will serve
-- as an escalation point.
PROCEDURE SET_ESCALATION_PROFILE(v_profile_name IN VARCHAR2,
v_escalation_profile_name IN VARCHAR2,
v_escalation_interval IN NUMBER)
IS
BEGIN
UPDATE MGMT_NOTIFY_PROFILES
SET escalation_profile_name = UPPER(v_escalation_profile_name),
escalation_interval = v_escalation_interval
WHERE profile_name = v_profile_name;
END SET_ESCALATION_PROFILE;
-- PURPOSE
-- Procedure to delete the name of an administrator profile that will serve
-- as an escalation point.
PROCEDURE DELETE_ESCALATION_PROFILE(v_profile_name IN VARCHAR2)
IS
BEGIN
UPDATE MGMT_NOTIFY_PROFILES
SET escalation_profile_name = '',
escalation_interval = ''
WHERE profile_name = UPPER(v_profile_name);
END DELETE_ESCALATION_PROFILE;
-- PURPOSE
-- Procedure to add an email notification device to an administrator profile
--
PROCEDURE ADD_EMAIL_DEVICE(v_device_name IN VARCHAR2,
v_profile_name IN VARCHAR2,
v_email_address IN VARCHAR2,
v_type IN NUMBER
DEFAULT LONG_EMAIL_DEVICE_TYPE,
v_description IN VARCHAR2 DEFAULT '')
IS
BEGIN
BEGIN
INSERT INTO mgmt_notify_devices (DEVICE_NAME, PROFILE_NAME, TYPE,
EMAIL_ADDRESS, DEVICE_DESCRIPTION)
VALUES (v_device_name, UPPER(v_profile_name), v_type, v_email_address,
v_description);
EXCEPTION
WHEN DUP_VAL_ON_INDEX
THEN
NULL;
END;
END ADD_EMAIL_DEVICE;
-- PURPOSE
-- Procedure to change the email address of an existing email notification
-- device that was added via ADD_EMAIL_DEVICE
--
PROCEDURE EDIT_EMAIL_DEVICE(v_device_name IN VARCHAR2,
v_profile_name IN VARCHAR2,
v_email_address IN VARCHAR2,
v_type IN NUMBER
DEFAULT LONG_EMAIL_DEVICE_TYPE,
v_description IN VARCHAR2 DEFAULT '')
IS
dname VARCHAR2(132);
BEGIN
UPDATE MGMT_NOTIFY_DEVICES SET EMAIL_ADDRESS = v_email_address,
DEVICE_DESCRIPTION = v_description,
TYPE = v_type
WHERE
DEVICE_NAME = v_device_name AND
PROFILE_NAME = UPPER(v_profile_name) AND
TYPE IN (LONG_EMAIL_DEVICE_TYPE, SHORT_EMAIL_DEVICE_TYPE)
RETURNING DEVICE_NAME INTO dname;
IF dname IS NULL
THEN
ROLLBACK;
raise_application_error(-20002, v_profile_name ||
' does not have an EMAIL device named ' ||
v_device_name || '!');
END IF;
END EDIT_EMAIL_DEVICE;
-- PURPOSE
-- Procedure to add a program/script notification device to an administrator
-- profile
--
PROCEDURE ADD_PROGRAM_DEVICE(v_device_name IN VARCHAR2,
v_profile_name IN VARCHAR2,
v_program IN VARCHAR2,
v_description IN VARCHAR2 DEFAULT '',
v_args IN EMDSYSTEM_ARGS DEFAULT NULL)
IS
BEGIN
INSERT INTO mgmt_notify_devices (DEVICE_NAME, PROFILE_NAME, TYPE, PROGRAM,
DEVICE_DESCRIPTION )
VALUES (v_device_name, UPPER(v_profile_name), PROGRAM_DEVICE_TYPE,
v_program, v_description);
If v_args IS NOT NULL and v_args.COUNT > 0
THEN
FOR i IN v_args.FIRST..v_args.LAST
LOOP
INSERT INTO mgmt_notify_device_params
(device_name, profile_name, parameter, position)
VALUES (v_device_name, v_profile_name, v_args(i), i);
END LOOP;
END IF;
END ADD_PROGRAM_DEVICE;
-- PURPOSE
-- Procedure to change the program/script of an existing notification device
-- device that was added via ADD_PROGRAM_DEVICE
--
PROCEDURE EDIT_PROGRAM_DEVICE(v_device_name IN VARCHAR2,
v_profile_name IN VARCHAR2,
v_program IN VARCHAR2,
v_description IN VARCHAR2 DEFAULT '',
v_args IN EMDSYSTEM_ARGS DEFAULT NULL)
IS
dname VARCHAR2(132);
BEGIN
UPDATE MGMT_NOTIFY_DEVICES SET PROGRAM = v_program,
DEVICE_DESCRIPTION = v_description
WHERE
DEVICE_NAME = v_device_name AND
PROFILE_NAME = UPPER(v_profile_name) AND
TYPE = PROGRAM_DEVICE_TYPE
RETURNING DEVICE_NAME INTO dname;
IF dname IS NULL
THEN
ROLLBACK;
raise_application_error(-20002, v_profile_name ||
' does not have a PROGRAM device named ' ||
v_device_name || '!');
END IF;
-- Always delete the parameters
DELETE FROM MGMT_NOTIFY_DEVICE_PARAMS
WHERE device_name = v_device_name AND profile_name = v_profile_name;
If v_args IS NOT NULL and v_args.COUNT > 0
THEN
FOR i IN v_args.FIRST..v_args.LAST
LOOP
INSERT INTO mgmt_notify_device_params
(device_name, profile_name, parameter, position)
VALUES (v_device_name, v_profile_name, v_args(i), i);
END LOOP;
END IF;
END EDIT_PROGRAM_DEVICE;
-- PURPOSE
-- Procedure to add a java callback notification device to an administrator
-- profile
-- PARAMETERS
-- V_DEVICE_NAME - the name of the device
-- V_PROFILE_NAME - the name of the admin profile
-- V_CLASS - this is the name of fully qualified class name that will be invoked
-- on delivering the notification. Can be used to integrate
-- other problem tracking systems
-- V_DESCRIPTION - the description of the device
PROCEDURE ADD_JAVA_DEVICE(v_device_name IN VARCHAR2,
v_profile_name IN VARCHAR2,
v_class IN VARCHAR2,
v_description IN VARCHAR2 DEFAULT '',
v_context IN MGMT_MEDIUM_STRING_TABLE DEFAULT NULL)
IS
l_current_user VARCHAR2(256) := MGMT_USER.GET_CURRENT_EM_USER;
BEGIN
-- Ensure that the caller is a super-user.
IF MGMT_USER.has_priv(l_current_user, MGMT_USER.SUPER_USER) = 0 THEN
raise_application_error(MGMT_GLOBAL.INSUFFICIENT_PRIVILEGES_ERR,
'Only superusers can call ADD_JAVA_DEVICE');
END IF;
INSERT INTO mgmt_notify_devices (DEVICE_NAME, PROFILE_NAME, TYPE, PROGRAM,
DEVICE_DESCRIPTION )
VALUES (v_device_name, UPPER(v_profile_name), JAVA_DEVICE_TYPE,
v_class, v_description);
IF v_context IS NOT NULL and v_context.COUNT > 0
THEN
FOR i IN v_context.FIRST..v_context.LAST
LOOP
INSERT INTO mgmt_notify_device_params
(device_name, profile_name, parameter, position)
VALUES (v_device_name, UPPER(v_profile_name), v_context(i), i);
END LOOP;
END IF;
END ADD_JAVA_DEVICE;
--
-- PROCEDURE: EDIT_JAVA_DEVICE
--
-- PURPOSE:
-- Modify the existing notification device of type Java.
-- Update p_class, p_description and context for the given p_device_name and p_profile_name
-- New context will override the previous context
--
-- IN Parameters:
-- v_device_name : Name of the notification device
-- v_profile_name : The name of the admin profile
-- v_class : Fully qualified name of the class implementing the notification interface
-- v_description : Description for this device
-- v_context : String array of context that will be passed to the notify method while delivering the notification.
--
-- OUT Parameters:
-- NONE
--
PROCEDURE EDIT_JAVA_DEVICE(v_device_name IN VARCHAR2,
v_profile_name IN VARCHAR2,
v_class IN VARCHAR2,
v_description IN VARCHAR2 DEFAULT '',
v_context IN MGMT_MEDIUM_STRING_TABLE DEFAULT NULL)
IS
dname VARCHAR2(132);
l_current_user VARCHAR2(256) := MGMT_USER.GET_CURRENT_EM_USER;
BEGIN
-- Ensure that the caller is a super-user.
IF MGMT_USER.has_priv(l_current_user, MGMT_USER.SUPER_USER) = 0 THEN
raise_application_error(MGMT_GLOBAL.INSUFFICIENT_PRIVILEGES_ERR,
'Only superusers can call MODIFY_JAVA_DEVICE');
END IF;
UPDATE MGMT_NOTIFY_DEVICES SET PROGRAM = v_class,
DEVICE_DESCRIPTION = v_description
WHERE
DEVICE_NAME = v_device_name AND
PROFILE_NAME = UPPER(v_profile_name) AND
TYPE = JAVA_DEVICE_TYPE
RETURNING DEVICE_NAME INTO dname;
IF dname IS NULL
THEN
ROLLBACK;
raise_application_error(-20002, v_profile_name ||
' does not have a JAVA device named ' ||
v_device_name || '!');
END IF;
-- Always delete the parameters
DELETE FROM MGMT_NOTIFY_DEVICE_PARAMS
WHERE device_name = v_device_name
AND profile_name = UPPER(v_profile_name);
IF v_context IS NOT NULL and v_context.COUNT > 0
THEN
FOR i IN v_context.FIRST..v_context.LAST
LOOP
INSERT INTO mgmt_notify_device_params
(device_name, profile_name, parameter, position)
VALUES (v_device_name, UPPER(v_profile_name), v_context(i), i);
END LOOP;
END IF;
END EDIT_JAVA_DEVICE;
-- PURPOSE
-- Function to test a PL/SQL notification device to see if it can be
-- called
FUNCTION TEST_PLSQL_DEVICE(v_plsql_proc IN VARCHAR2, v_err_msg OUT VARCHAR2)
RETURN NUMBER
IS
sev MGMT_NOTIFY_SEVERITY;
jsc MGMT_NOTIFY_JOB;
casc MGMT_NOTIFY_CORRECTIVE_ACTION;
BEGIN
-- Make sure the procedure is valid before trying to execute it
IF NOT em_check.is_valid_signature(v_plsql_proc,
mgmt_short_string_array('MGMT_NOTIFY_SEVERITY'),
v_err_msg)
AND
NOT em_check.is_valid_signature(v_plsql_proc,
mgmt_short_string_array('MGMT_NOTIFY_JOB'),
v_err_msg)
AND
NOT em_check.is_valid_signature(v_plsql_proc,
mgmt_short_string_array('MGMT_NOTIFY_CORRECTIVE_ACTION'),
v_err_msg)
THEN
-- The procedure is not valid so return failure
RETURN 0;
END IF;
BEGIN
-- Try a severity first
sev := MGMT_NOTIFY_SEVERITY('Filesystem Rule','SYSMAN',
'myhost.com', 'host', '-07:00', 'myhost.com',
'Filesystems', 'Size of the filesystem',
'Filesystem Size (MB)', '94', 'Mount Point',
'/usr', SYS_GUID(), SYSDATE, 20,
MGMT_GLOBAL.NOTIFICATION_PLSQL_TEST_MSG,
SYS_GUID(), SYS_GUID(), SYS_GUID(),
NULL);
EXECUTE IMMEDIATE 'CALL ' ||
EM_CHECK.QUALIFIED_SQL_NAME(v_plsql_proc) || '(:s)'
USING sev;
RETURN 1;
EXCEPTION WHEN OTHERS
THEN
-- If the error is ORA-06576: not a valid function or procedure name
IF SQLCODE = -6576
THEN
v_err_msg := SQLERRM;
RETURN 0;
END IF;
END;
BEGIN
-- Try a job notification
jsc := MGMT_NOTIFY_JOB('Job Rule', 'SYSMAN', 'My Job', 'SYSMAN',
'OSCommand', 1, SYSDATE, SYS_GUID(),
SYS_GUID(), SYS_GUID(),
SMP_EMD_NVPAIR_ARRAY(SMP_EMD_NVPAIR('myhost.com',
'host')));
EXECUTE IMMEDIATE 'CALL ' ||
EM_CHECK.QUALIFIED_SQL_NAME(v_plsql_proc) || '(:s)'
USING jsc;
RETURN 1;
EXCEPTION WHEN OTHERS
THEN
NULL;
END;
BEGIN
-- Try a corrective action notification
casc := MGMT_NOTIFY_CORRECTIVE_ACTION
('Filesystem Rule', 'SYSMAN', 'Fix Filesystem', 'SYSMAN',
'OSCommand', 1, SYSDATE, SYS_GUID(), SYS_GUID(), SYS_GUID(),
SMP_EMD_NVPAIR_ARRAY(SMP_EMD_NVPAIR('myhost.com', 'host')),
'Filesystems', 'Filesystem Size (MB)', '94', 25,
'Mount Point', '/usr', SYS_GUID(), NULL);
EXECUTE IMMEDIATE 'CALL ' ||
EM_CHECK.QUALIFIED_SQL_NAME(v_plsql_proc) || '(:s)'
USING casc;
RETURN 1;
EXCEPTION
WHEN OTHERS
THEN
v_err_msg := SQLERRM;
RETURN 0;
END;
END TEST_PLSQL_DEVICE;
-- PURPOSE
-- Procedure to add a PL/SQL notification device to an administrator
-- profile
PROCEDURE ADD_PLSQL_DEVICE(v_device_name IN VARCHAR2,
v_profile_name IN VARCHAR2,
v_plsql_proc IN VARCHAR2,
v_description IN VARCHAR2 DEFAULT '')
IS
l_err_msg VARCHAR2(1024);
BEGIN
-- Make sure the procedure is valid before saving it
IF NOT em_check.is_valid_signature(v_plsql_proc,
mgmt_short_string_array('MGMT_NOTIFY_SEVERITY'),
l_err_msg)
AND
NOT em_check.is_valid_signature(v_plsql_proc,
mgmt_short_string_array('MGMT_NOTIFY_JOB'),
l_err_msg)
AND
NOT em_check.is_valid_signature(v_plsql_proc,
mgmt_short_string_array('MGMT_NOTIFY_CORRECTIVE_ACTION'),
l_err_msg)
THEN
-- The procedure is not valid so raise an exception
RAISE_APPLICATION_ERROR(MGMT_GLOBAL.INVALID_PARAMS_ERR, l_err_msg);
END IF;
INSERT INTO mgmt_notify_devices (DEVICE_NAME, PROFILE_NAME, TYPE, PROGRAM,
DEVICE_DESCRIPTION)
VALUES (v_device_name, UPPER(v_profile_name), PLSQL_DEVICE_TYPE,
v_plsql_proc, v_description);
END ADD_PLSQL_DEVICE;
-- PURPOSE
-- Procedure to change the name of the PL/SQL procedure of an existing
-- notification device that was added via ADD_PLSQL_DEVICE
PROCEDURE EDIT_PLSQL_DEVICE(v_device_name IN VARCHAR2,
v_profile_name IN VARCHAR2,
v_plsql_proc IN VARCHAR2,
v_description IN VARCHAR2 DEFAULT '')
IS
dname VARCHAR2(132);
l_err_msg VARCHAR2(1024);
BEGIN
-- Make sure the procedure is valid before saving it
IF NOT em_check.is_valid_signature(v_plsql_proc,
mgmt_short_string_array('MGMT_NOTIFY_SEVERITY'),
l_err_msg)
AND
NOT em_check.is_valid_signature(v_plsql_proc,
mgmt_short_string_array('MGMT_NOTIFY_JOB'),
l_err_msg)
AND
NOT em_check.is_valid_signature(v_plsql_proc,
mgmt_short_string_array('MGMT_NOTIFY_CORRECTIVE_ACTION'),
l_err_msg)
THEN
-- The procedure is not valid so raise an exception
RAISE_APPLICATION_ERROR(MGMT_GLOBAL.INVALID_PARAMS_ERR, l_err_msg);
END IF;
UPDATE MGMT_NOTIFY_DEVICES SET PROGRAM = v_plsql_proc,
DEVICE_DESCRIPTION = v_description
WHERE
DEVICE_NAME = v_device_name AND
PROFILE_NAME = UPPER(v_profile_name) AND
TYPE = PLSQL_DEVICE_TYPE
RETURNING DEVICE_NAME INTO dname;
IF dname IS NULL
THEN
ROLLBACK;
raise_application_error(-20002, v_profile_name ||
' does not have a PL/SQL device named ' ||
v_device_name || '!');
END IF;
END EDIT_PLSQL_DEVICE;
-- PURPOSE
-- Procedure to add an SNMP notification device to an administrator profile
PROCEDURE ADD_SNMP_DEVICE(v_device_name IN VARCHAR2,
v_profile_name IN VARCHAR2,
v_snmp_host IN VARCHAR2,
v_snmp_port IN NUMBER DEFAULT 162,
v_community IN VARCHAR2 DEFAULT 'public',
v_description IN VARCHAR2 DEFAULT '')
IS
BEGIN
INSERT INTO mgmt_notify_devices (DEVICE_NAME, PROFILE_NAME, TYPE, SNMP_HOST,
SNMP_PORT, SNMP_COMMUNITY,
DEVICE_DESCRIPTION)
VALUES (v_device_name, UPPER(v_profile_name), SNMP_DEVICE_TYPE, v_snmp_host,
v_snmp_port, v_community, v_description);
END ADD_SNMP_DEVICE;
-- PURPOSE
-- Procedure to change the snmp host of an existing SNMP notification
-- device that was added via ADD_SNMP_DEVICE
-- PARAMETERS
-- V_DEVICE_NAME - the name of the device
-- V_PROFILE_NAME - the name of the admin profile
-- V_SNMP_HOST - the new name of the snmp host
PROCEDURE EDIT_SNMP_DEVICE(v_device_name IN VARCHAR2,
v_profile_name IN VARCHAR2,
v_snmp_host IN VARCHAR2,
v_snmp_port IN NUMBER DEFAULT 162,
v_community IN VARCHAR2 DEFAULT 'public',
v_description IN VARCHAR2 DEFAULT '')
IS
dname VARCHAR2(132);
BEGIN
UPDATE MGMT_NOTIFY_DEVICES SET SNMP_HOST = v_snmp_host,
SNMP_PORT = v_snmp_port,
SNMP_COMMUNITY = v_community,
DEVICE_DESCRIPTION = v_description
WHERE
DEVICE_NAME = v_device_name AND
PROFILE_NAME = UPPER(v_profile_name) AND
TYPE = SNMP_DEVICE_TYPE
RETURNING DEVICE_NAME INTO dname;
IF dname IS NULL
THEN
ROLLBACK;
raise_application_error(-20002, v_profile_name ||
' does not have an SNMP device named ' ||
v_device_name || '!');
END IF;
END EDIT_SNMP_DEVICE;
-- PURPOSE
-- Get the device owner for device - v_device_name of type v_type
-- PARAMETERS
-- V_DEVICE_NAME - the name of the device
-- V_TYPE - the type of the device
FUNCTION GET_DEVICE_OWNER(v_device_name IN VARCHAR2,
v_type IN INTEGER)
RETURN VARCHAR2
IS
CURSOR dOwnerCursor IS
SELECT profile_name
FROM mgmt_notify_devices
WHERE device_name=v_device_name
AND type=v_type;
deviceOwner VARCHAR2(256) := '';
BEGIN
FOR record IN dOwnerCursor
LOOP
deviceOwner := record.profile_name;
exit;
END LOOP;
IF( deviceOwner IS NULL )
THEN
deviceOwner := '';
END IF;
RETURN deviceOwner;
END GET_DEVICE_OWNER;
-- PURPOSE
-- Procedure to set the start date of a user's notification schedule
-- PARAMETERS
-- V_SCHEDULE_OWNER - the owner of the schedule
-- V_SCHEDULE_NAME - the name of the schedule
-- V_START_DATE - the date on which the schedule starts. Note that the hour
-- and minutes are ignored since the schedule starts at 12:00
-- V_NUM_WEEKS - the number of weeks after which the schedule repeats
-- V_TIMEZONE_REGION - the timezone region of the schedule owner
--
PROCEDURE SET_SCHEDULE(v_schedule_owner IN VARCHAR2,
v_schedule_name IN VARCHAR2 DEFAULT ' ',
v_start_date IN DATE,
v_num_weeks IN NUMBER DEFAULT 1,
v_timezone_region IN VARCHAR2 DEFAULT
TO_CHAR(SYSTIMESTAMP,'TZR'))
IS
sowner VARCHAR2(256);
owner VARCHAR2(256);
cuser VARCHAR2(256);
email VARCHAR2(128);
err_msg VARCHAR2(1024);
r BOOLEAN;
BEGIN
sowner := UPPER(v_schedule_owner);
cuser := MGMT_USER.GET_CURRENT_EM_USER();
-- In general the schedule will be updated, so try updating first. If the
-- schedule does not exist then create it
UPDATE MGMT_NOTIFY_SCHEDULES
SET start_date = TRUNC(v_start_date),
num_weeks = v_num_weeks,
updated_by = cuser,
updated = SYSDATE,
timezone_region = v_timezone_region
WHERE schedule_owner = sowner AND
schedule_name = v_schedule_name
RETURNING schedule_owner INTO owner;
-- Check to make sure the update succeeded
IF owner IS NULL
THEN
INSERT INTO MGMT_NOTIFY_SCHEDULES
(schedule_owner, schedule_name, start_date, num_weeks,
updated_by, updated, timezone_region)
VALUES (sowner, v_schedule_name, TRUNC(v_start_date),
v_num_weeks, cuser, SYSDATE, v_timezone_region);
END IF;
END SET_SCHEDULE;
-- PURPOSE
-- Procedure to get the user who last updated a notification schedule
-- PARAMETERS
-- V_SCHEDULE_OWNER - the owner of the schedule
-- V_SCHEDULE_NAME - the name of the schedule
-- V_UPDATED_BY - the user who updated the schedule
-- V_UPDATED - when the update took place
--
PROCEDURE WHO_UPDATED_SCHEDULE(v_schedule_owner IN VARCHAR2,
v_schedule_name IN VARCHAR2 DEFAULT ' ',
v_updated_by OUT VARCHAR2,
v_updated OUT DATE)
IS
sowner VARCHAR2(256);
BEGIN
sowner := UPPER(v_schedule_owner);
SELECT updated_by, updated INTO v_updated_by, v_updated
FROM MGMT_NOTIFY_SCHEDULES
WHERE schedule_owner = sowner AND
schedule_name = v_schedule_name;
END WHO_UPDATED_SCHEDULE;
-- PURPOSE
-- Procedure to disable a user's notification schedule for a period of time
-- PARAMETERS
-- V_SCHEDULE_OWNER - the owner of the schedule
-- V_SCHEDULE_NAME - the name of the schedule
-- V_DISABLE_START - the date on which the disabling period starts
-- V_DISABLE_END - the date on which the disabling period ends
--
-- NOTES
-- To clear a disabling period pass NULL in for both v_disable_start and
-- v_disable_end
--
PROCEDURE DISABLE_SCHEDULE(v_schedule_owner IN VARCHAR2,
v_schedule_name IN VARCHAR2 DEFAULT ' ',
v_disable_start IN DATE,
v_disable_end IN DATE)
IS
sowner VARCHAR2(256);
cuser VARCHAR2(256);
email VARCHAR2(128);
err_msg VARCHAR2(1024);
r BOOLEAN;
BEGIN
sowner := UPPER(v_schedule_owner);
cuser := MGMT_USER.GET_CURRENT_EM_USER();
-- Keep track of who did the update
UPDATE MGMT_NOTIFY_SCHEDULES
SET disable_start = v_disable_start,
disable_end = v_disable_end,
updated_by = cuser,
updated = SYSDATE
WHERE schedule_owner = sowner AND
schedule_name = v_schedule_name;
END DISABLE_SCHEDULE;
-- PURPOSE
-- Procedure to set the notification schedule of a notification device
-- PARAMETERS
-- V_SCHEDULE_OWNER - the owner of the schedule
-- V_SCHEDULE_NAME - the name of the schedule
-- V_DEVICE_NAME - the name of the device
-- V_DEVICE_OWNER - the name of the admin profile
-- V_SCHEDULE - the hours in this schedule when the device is available.
-- This must be an array of 1344 characters
PROCEDURE SET_DEVICE_SCHEDULE(v_schedule_owner IN VARCHAR2,
v_schedule_name IN VARCHAR2 DEFAULT ' ',
v_device_name IN VARCHAR2,
v_device_owner IN VARCHAR2,
v_schedule IN VARCHAR2)
IS
sowner VARCHAR2(256);
downer VARCHAR2(256);
cuser VARCHAR2(256);
email VARCHAR2(128);
err_msg VARCHAR2(1024);
r BOOLEAN;
BEGIN
sowner := UPPER(v_schedule_owner);
downer := UPPER(v_device_owner);
cuser := MGMT_USER.GET_CURRENT_EM_USER();
-- Delete the current schedule
DELETE FROM MGMT_NOTIFY_DEV_SCHEDULES
WHERE schedule_owner = sowner
AND schedule_name = v_schedule_name
AND device_owner = downer
AND device_name = v_device_name;
IF v_schedule IS NOT NULL AND (LENGTH(v_schedule) > 0)
THEN
INSERT INTO mgmt_notify_dev_schedules
(SCHEDULE_OWNER, SCHEDULE_NAME, DEVICE_NAME, DEVICE_OWNER, SCHEDULE)
VALUES (sowner, v_schedule_name, v_device_name, downer, v_schedule);
END IF;
-- Keep track of who did the update
UPDATE MGMT_NOTIFY_SCHEDULES
SET updated_by = cuser,
updated = SYSDATE
WHERE schedule_owner = sowner AND
schedule_name = v_schedule_name;
END SET_DEVICE_SCHEDULE;
-- PURPOSE
-- Procedure to clear a user's schedule
-- PARAMETERS
-- V_SCHEDULE_OWNER - the owner of the schedule
-- V_SCHEDULE_NAME - the name of the schedule
PROCEDURE CLEAR_SCHEDULE(v_schedule_owner IN VARCHAR2,
v_schedule_name IN VARCHAR2 DEFAULT ' ')
IS
BEGIN
-- Delete the device schedules
DELETE FROM MGMT_NOTIFY_DEV_SCHEDULES
WHERE schedule_owner = v_schedule_owner
AND schedule_name = v_schedule_name;
-- Delete the schedule
DELETE FROM MGMT_NOTIFY_SCHEDULES
WHERE schedule_owner = v_schedule_owner
AND schedule_name = v_schedule_name;
END CLEAR_SCHEDULE;
-- PURPOSE
-- Function to check if a user has a schedule set
-- PARAMETERS
-- V_SCHEDULE_OWNER - the owner of the schedule
-- V_SCHEDULE_NAME - the name of the schedule
FUNCTION USER_SCHEDULE_SET(v_schedule_owner IN VARCHAR2,
v_schedule_name IN VARCHAR2 DEFAULT ' ')
RETURN NUMBER
IS
cnt NUMBER;
BEGIN
-- Check if a schedule exists
SELECT COUNT(schedule_owner) INTO cnt FROM MGMT_NOTIFY_SCHEDULES
WHERE schedule_owner = v_schedule_owner
AND schedule_name = v_schedule_name
AND EXISTS (SELECT schedule_name FROM MGMT_NOTIFY_DEV_SCHEDULES
WHERE schedule_owner = v_schedule_owner
AND schedule_name = v_schedule_name);
IF cnt = 0
THEN
RETURN 0;
END IF;
RETURN 1;
END USER_SCHEDULE_SET;
-- Procedure to add a notification rule
PROCEDURE ADD_NOTIFICATION_RULE(v_rule_name IN VARCHAR2,
v_owner IN VARCHAR2,
v_description IN VARCHAR2,
v_public_rule IN NUMBER DEFAULT 0,
v_repeat_enabled IN NUMBER DEFAULT 0)
IS
BEGIN
-- Note that the owner column is not in use yet
INSERT INTO mgmt_notify_rules (rule_name, owner, description, public_rule, repeat)
VALUES (v_rule_name, v_owner, v_description, v_public_rule, v_repeat_enabled);
END ADD_NOTIFICATION_RULE;
--
-- PURPOSE
-- Procedure to add a configuration to a rule. This allows the specification of
-- the severity properties to which the rule applies.
--
-- NOTES
-- For composite keys v_is_composite_key must be set to 1, the v_key_value
-- parameter must contain the composite GUID, the associated key parts
-- must be specified in v_key_part1..v_key_part5 and the target type must
-- be specified in v_target_guid
--
PROCEDURE ADD_CONFIGURATION_TO_RULE
(v_rule_name IN VARCHAR2,
v_owner IN VARCHAR2,
v_target_type IN VARCHAR2 DEFAULT '%',
v_target_name IN VARCHAR2 DEFAULT '%',
v_group_guid IN VARCHAR2 DEFAULT NULL,
v_metric_name IN VARCHAR2 DEFAULT '%',
v_metric_column IN VARCHAR2 DEFAULT '%',
v_key_value IN VARCHAR2 DEFAULT '%',
v_is_composite_key IN NUMBER DEFAULT 0,
v_target_guid IN RAW DEFAULT NULL,
v_key_part1 IN VARCHAR2 DEFAULT '',
v_key_part2 IN VARCHAR2 DEFAULT '',
v_key_part3 IN VARCHAR2 DEFAULT '',
v_key_part4 IN VARCHAR2 DEFAULT '',
v_key_part5 IN VARCHAR2 DEFAULT '',
v_want_clears IN NUMBER DEFAULT 0,
v_want_warnings IN NUMBER DEFAULT 0,
v_want_critical_alerts IN NUMBER DEFAULT 0,
v_want_target_up IN NUMBER DEFAULT 0,
v_want_target_down IN NUMBER DEFAULT 0,
v_want_target_unreachable_st IN NUMBER DEFAULT 0,
v_want_target_unreachable_end IN NUMBER DEFAULT 0,
v_want_target_metric_err_start IN NUMBER DEFAULT 0,
v_want_target_metric_err_end IN NUMBER DEFAULT 0,
v_want_target_blackout_start IN NUMBER DEFAULT 0,
v_want_target_blackout_end IN NUMBER DEFAULT 0,
v_want_policy_clears IN NUMBER DEFAULT 0,
v_want_policy_violations IN NUMBER DEFAULT 0,
v_want_warning_job_succeeded IN NUMBER DEFAULT 0,
v_want_warning_job_problems IN NUMBER DEFAULT 0,
v_want_critical_job_succeeded IN NUMBER DEFAULT 0,
v_want_critical_job_problems IN NUMBER DEFAULT 0,
v_want_policy_job_succeeded IN NUMBER DEFAULT 0,
v_want_policy_job_problems IN NUMBER DEFAULT 0,
v_ignore_rca IN NUMBER DEFAULT 0
)
IS
BEGIN
-- This is a composite key match with wildcards
INSERT INTO mgmt_notify_rule_configs
(RULE_NAME, OWNER, TARGET_TYPE, TARGET_NAME, TARGET_GUID, METRIC_NAME,
METRIC_COLUMN, KEY_VALUE, KEY_PART_1, KEY_PART_2, KEY_PART_3,
KEY_PART_4, KEY_PART_5, WANT_CLEARS, WANT_WARNINGS, WANT_CRITICAL_ALERTS,
WANT_TARGET_UP, WANT_TARGET_DOWN, WANT_TARGET_UNREACHABLE_START,
WANT_TARGET_UNREACHABLE_END, WANT_TARGET_METRIC_ERR_START,
WANT_TARGET_METRIC_ERR_END, WANT_TARGET_BLACKOUT_START,
WANT_TARGET_BLACKOUT_END, WANT_POLICY_CLEARS, WANT_POLICY_VIOLATIONS,
WANT_WARNING_JOB_SUCCEEDED, WANT_WARNING_JOB_PROBLEMS,
WANT_CRITICAL_JOB_SUCCEEDED, WANT_CRITICAL_JOB_PROBLEMS,
WANT_POLICY_JOB_SUCCEEDED, WANT_POLICY_JOB_PROBLEMS, IGNORE_RCA)
VALUES
(v_rule_name, v_owner, v_target_type, v_target_name, v_group_guid,
v_metric_name, v_metric_column, v_key_value, NVL(v_key_part1, ' '),
NVL(v_key_part2, ' '),NVL(v_key_part3, ' '), NVL(v_key_part4, ' '),
NVL(v_key_part5, ' '), v_want_clears, v_want_warnings,
v_want_critical_alerts, v_want_target_up, v_want_target_down,
v_want_target_unreachable_st, v_want_target_unreachable_end,
v_want_target_metric_err_start, v_want_target_metric_err_end,
v_want_target_blackout_start, v_want_target_blackout_end,
v_want_policy_clears, v_want_policy_violations,
v_want_warning_job_succeeded, v_want_warning_job_problems,
v_want_critical_job_succeeded, v_want_critical_job_problems,
v_want_policy_job_succeeded, v_want_policy_job_problems, v_ignore_rca);
-- Check if this is a composite key
IF v_is_composite_key = 1
THEN
BEGIN
-- Store the key and its associated key parts
INSERT INTO MGMT_METRICS_COMPOSITE_KEYS
(composite_key, target_guid, key_part1_value, key_part2_value,
key_part3_value, key_part4_value, key_part5_value)
VALUES (v_key_value, v_target_guid, v_key_part1, v_key_part2,
v_key_part3, v_key_part4, v_key_part5);
EXCEPTION WHEN DUP_VAL_ON_INDEX
THEN
-- The key already exists to ignore the error
NULL;
END;
END IF;
END ADD_CONFIGURATION_TO_RULE;
-- PURPOSE
-- Procedure to add a configuration to a job rule. This allows the
-- specification of the job properties to which the rule applies. This is also
-- used for corrective actions in which case the metric details are also
-- supplied
PROCEDURE ADD_CONFIGURATION_TO_JOB_RULE
(v_rule_name IN VARCHAR2,
v_owner IN VARCHAR2,
v_target_type IN VARCHAR2 DEFAULT '%',
v_target_name IN VARCHAR2 DEFAULT '%',
v_group_guid IN VARCHAR2 DEFAULT NULL,
v_job_name IN VARCHAR2 DEFAULT '%',
v_job_owner IN VARCHAR2 DEFAULT '%',
v_job_type IN VARCHAR2 DEFAULT '%',
v_want_job_scheduled IN NUMBER DEFAULT 0,
v_want_job_running IN NUMBER DEFAULT 0,
v_want_job_succeeded IN NUMBER DEFAULT 0,
v_want_job_suspended IN NUMBER DEFAULT 0,
v_want_job_problems IN NUMBER DEFAULT 0
)
IS
BEGIN
INSERT INTO mgmt_notify_job_rule_configs
(RULE_NAME, OWNER, TARGET_TYPE, TARGET_NAME, TARGET_GUID,
JOB_NAME, JOB_OWNER, JOB_TYPE,
WANT_JOB_SCHEDULED, WANT_JOB_RUNNING, WANT_JOB_SUCCEEDED,
WANT_JOB_SUSPENDED, WANT_JOB_PROBLEMS)
VALUES
(v_rule_name, v_owner, v_target_type, v_target_name, v_group_guid,
UPPER(v_job_name), UPPER(v_job_owner), v_job_type,
v_want_job_scheduled, v_want_job_running,
v_want_job_succeeded, v_want_job_suspended, v_want_job_problems);
END ADD_CONFIGURATION_TO_JOB_RULE;
-- PURPOSE
-- Procedure to set the properties of a rule
PROCEDURE SET_RULE_PROPERTIES
(v_rule_name IN VARCHAR2,
v_owner IN VARCHAR2,
v_description IN VARCHAR2,
v_public_rule IN NUMBER DEFAULT 0,
v_repeat_enabled IN NUMBER DEFAULT 0)
IS
rname VARCHAR2(64);
BEGIN
UPDATE mgmt_notify_rules p
SET p.public_rule = v_public_rule,
p.description = v_description,
p.repeat = v_repeat_enabled
WHERE p.rule_name = v_rule_name
AND p.owner = v_owner;
END SET_RULE_PROPERTIES;
-- PURPOSE
-- Procedure to make a rule public
-- PARAMETERS
PROCEDURE MAKE_RULE_PUBLIC(v_rule_name IN VARCHAR2,
v_owner IN VARCHAR2,
v_make_public IN NUMBER)
IS
BEGIN
UPDATE MGMT_NOTIFY_RULES SET public_rule = v_make_public
WHERE rule_name = v_rule_name AND owner = v_owner;
END MAKE_RULE_PUBLIC;
-- PURPOSE
-- Procedure to enable/disable repeat setting for a rule
-- PARAMETERS
-- P_RULE_NAME - name of the notification rule
-- P_OWNER - the owner of the notification rule
-- P_ENABLE_REPEAT - whether to enable or disable the repeat.
PROCEDURE SET_RULE_REPEAT(p_rule_name IN VARCHAR2,
p_owner IN VARCHAR2,
p_enable_repeat IN NUMBER)
IS
l_rule_name mgmt_notify_rules.rule_name%type := NULL;
BEGIN
UPDATE MGMT_NOTIFY_RULES SET repeat = p_enable_repeat
WHERE rule_name = p_rule_name AND owner = p_owner
returning rule_name INTO l_rule_name;
IF(l_rule_name IS NULL)
THEN
raise_application_error(MGMT_GLOBAL.INVALID_PARAMS_ERR,
' No Notification Rule exists for the combination of rule_name = ' || p_rule_name ||
' and owner = ' || p_owner) ;
END IF;
END SET_RULE_REPEAT;
-- Procedure to assign notification devices to a notification rule
PROCEDURE ADD_DEVICE_TO_RULE(v_rule_name IN VARCHAR2,
v_owner IN VARCHAR2,
v_device_name IN VARCHAR2,
v_profile_name IN VARCHAR2)
IS
BEGIN
INSERT INTO mgmt_notify_notifyees (RULE_NAME, OWNER, DEVICE_NAME,
PROFILE_NAME)
VALUES (v_rule_name, v_owner, v_device_name, UPPER(v_profile_name));
END ADD_DEVICE_TO_RULE;
-- PURPOSE
-- Function to check if a notification rule exists
-- PARAMETERS
-- V_RULE_NAME - name of the notification rule
-- V_OWNER - the owner of the notification rule
FUNCTION RULE_EXISTS(v_rule_name IN VARCHAR2,
v_owner IN VARCHAR2)
RETURN INTEGER
IS
rname VARCHAR2(64);
BEGIN
SELECT rule_name INTO rname FROM MGMT_NOTIFY_RULES
WHERE rule_name = v_rule_name AND owner = v_owner;
IF rname IS NOT NULL
THEN
RETURN 1;
END IF;
RETURN 0;
EXCEPTION
WHEN NO_DATA_FOUND
THEN
RETURN 0;
END RULE_EXISTS;
-- PURPOSE
-- Function to find out if the email gateway has been setup
-- by the super user
--
-- NOTES
-- 0 is returned if no gateway has been set up, 1 is returned if a
-- gateway has been set up
--
FUNCTION IS_MAIL_GATEWAY_SETUP
RETURN NUMBER
IS
cnt NUMBER := 0;
BEGIN
SELECT COUNT(mail_host) INTO cnt FROM MGMT_NOTIFY_EMAIL_GATEWAY;
IF cnt > 0
THEN
RETURN 1;
ELSE
RETURN 0;
END IF;
END IS_MAIL_GATEWAY_SETUP;
-- PURPOSE
-- Procedure to delete the configurations of a notification rule.
PROCEDURE DELETE_RULE_CONFIGURATIONS(v_rule_name IN VARCHAR2,
v_owner IN VARCHAR2)
IS
BEGIN
DELETE FROM MGMT_NOTIFY_RULE_CONFIGS
WHERE RULE_NAME = v_rule_name AND OWNER = UPPER(v_owner);
DELETE FROM MGMT_NOTIFY_JOB_RULE_CONFIGS
WHERE RULE_NAME = v_rule_name AND OWNER = UPPER(v_owner);
END DELETE_RULE_CONFIGURATIONS;
-- PURPOSE
-- Procedure to delete a specific configuration of a notification rule
-- PARAMETERS
-- V_RULE_NAME - name of the notification rule
-- V_OWNER - the owner of the notification rule
-- V_TARGET_NAME - the name of the target
-- V_TARGET_TYPE - the type of the target
-- V_TARGET_NAME - the name of the metric
-- V_TARGET_NAME - the name of the metric column
-- V_TARGET_NAME - the key value
--
-- NOTES
-- This is used to delete rule configurations when a UDM or transposed
-- metric is deleted. Only configurations that exactly match all input
-- parameters will be deleted
PROCEDURE DELETE_RULE_CONFIGURATION(v_rule_name IN VARCHAR2,
v_owner IN VARCHAR2,
v_target_name IN VARCHAR2,
v_target_type IN VARCHAR2,
v_metric_name IN VARCHAR2,
v_metric_column IN VARCHAR2,
v_key_value IN VARCHAR2)
IS
BEGIN
DELETE FROM MGMT_NOTIFY_RULE_CONFIGS
WHERE RULE_NAME = v_rule_name
AND OWNER = UPPER(v_owner)
AND TARGET_NAME = v_target_name
AND TARGET_TYPE = v_target_type
AND METRIC_NAME = v_metric_name
AND METRIC_COLUMN = v_metric_column
AND KEY_VALUE = v_key_value;
END DELETE_RULE_CONFIGURATION;
-- PURPOSE
-- Procedure to remove notification devices from a notification rule
-- PARAMETERS
-- V_RULE_NAME - name of the notification rule
-- V_DEVICE_NAME - the name of the device
-- V_PROFILE_NAME - the name of the admin profile
PROCEDURE DELETE_DEVICE_FROM_RULE(v_rule_name IN VARCHAR2,
v_owner IN VARCHAR2,
v_device_name IN VARCHAR2,
v_profile_name IN VARCHAR2)
IS
rname VARCHAR2(64);
BEGIN
DELETE FROM MGMT_NOTIFY_NOTIFYEES
WHERE RULE_NAME = v_rule_name AND
OWNER = v_owner AND
DEVICE_NAME = v_device_name AND
PROFILE_NAME = UPPER(v_profile_name)
RETURNING RULE_NAME INTO rname;
END DELETE_DEVICE_FROM_RULE;
-- PURPOSE
-- Procedure to remove notification devices from a notification rule
-- Note that this procedure does not take in a profile_name. This is needed
-- for deleting snmp device or program command device
-- PARAMETERS
-- V_RULE_NAME - name of the notification rule
-- V_OWNER - the owner of the notification rule
-- V_DEVICE_NAME - the name of the device
PROCEDURE DELETE_DEVICE_FROM_RULE(v_rule_name IN VARCHAR2,
v_owner IN VARCHAR2,
v_device_name IN VARCHAR2)
IS
rname VARCHAR2(64);
BEGIN
DELETE FROM MGMT_NOTIFY_NOTIFYEES
WHERE RULE_NAME = v_rule_name AND
OWNER = v_owner AND
DEVICE_NAME = v_device_name
RETURNING RULE_NAME INTO rname;
END DELETE_DEVICE_FROM_RULE;
-- PURPOSE
-- Procedure to delete an administrator profile
PROCEDURE DELETE_ADMIN_PROFILE(v_profile_name IN VARCHAR2)
IS
log_msg VARCHAR2(512);
pname VARCHAR2(64);
BEGIN
DELETE FROM MGMT_NOTIFY_PROFILES WHERE PROFILE_NAME = UPPER(v_profile_name)
RETURNING PROFILE_NAME INTO pname;
IF pname IS NULL
THEN
raise_application_error(-20001, 'There is no administrator profile named '
|| v_profile_name || '!');
END IF;
END DELETE_ADMIN_PROFILE;
-- PURPOSE
-- Procedure to delete a notification device associated with an administrator
-- profile
PROCEDURE DELETE_DEVICE(v_profile_name IN VARCHAR2,
v_device_name IN VARCHAR2)
IS
dname VARCHAR2(132);
dev_type NUMBER;
BEGIN
DELETE FROM MGMT_NOTIFY_DEVICES
WHERE PROFILE_NAME = UPPER(v_profile_name) AND
DEVICE_NAME = v_device_name
RETURNING DEVICE_NAME INTO dname;
DELETE FROM MGMT_NOTIFY_NOTIFYEES
WHERE DEVICE_NAME = v_device_name
AND PROFILE_NAME = v_profile_name;
END DELETE_DEVICE;
-- PURPOSE
-- Procedure to delete a notification program device associated with an
-- administrator profile
-- NOTE: This is a UI specific API and could change depending on the
-- UI design.
-- PARAMETERS
-- V_PROFILE_NAME - name of the notification rule
-- V_DEVICE_NAME - name of the device
PROCEDURE DELETE_PROGRAM_DEVICE(v_profile_name IN VARCHAR2,
v_device_name IN VARCHAR2)
IS
pname VARCHAR2(64);
BEGIN
DELETE FROM MGMT_NOTIFY_DEVICES
WHERE PROFILE_NAME = UPPER(v_profile_name) AND
DEVICE_NAME = v_device_name AND
(TYPE = PROGRAM_DEVICE_TYPE OR TYPE = PLSQL_DEVICE_TYPE )
RETURNING PROFILE_NAME INTO pname;
DELETE FROM MGMT_NOTIFY_NOTIFYEES
WHERE DEVICE_NAME = v_device_name
AND PROFILE_NAME = v_profile_name;
END DELETE_PROGRAM_DEVICE;
-- PURPOSE
-- Procedure to delete a notification rule
PROCEDURE DELETE_NOTIFICATION_RULE(v_rule_name IN VARCHAR2,
v_owner IN VARCHAR2,
v_super_user IN VARCHAR2)
IS
rname VARCHAR2(64);
dName VARCHAR2(132) := '';
BEGIN
DELETE FROM MGMT_NOTIFY_RULES
WHERE rule_name = v_rule_name AND owner = UPPER(v_owner)
RETURNING RULE_NAME INTO rname;
IF rname IS NULL
THEN
raise_application_error(-20000, v_owner ||
' has no notification rule name d ' ||
v_rule_name || '!');
END IF;
END DELETE_NOTIFICATION_RULE;
-- PURPOSE
-- Get the details of a violation for sending in a notification
PROCEDURE GET_VIOLATION_DETAILS(violation_guid_in IN RAW,
language_in IN VARCHAR2,
country_in IN VARCHAR2,
details_out OUT MGMT_MAX_STRING_ARRAY,
collection_timestamp_out OUT DATE,
logged_timestamp_out OUT DATE,
keys_out OUT MGMT_NOTIFY_COLUMNS,
ctxt_list_out OUT MGMT_NOTIFY_COLUMNS,
is_plsql_notification IN BOOLEAN DEFAULT FALSE)
IS
hname VARCHAR2(256);
kval VARCHAR2(256);
coll_time VARCHAR2(64);
tz_region VARCHAR2(64);
tguid RAW(16);
mguid RAW(16);
pguid RAW(16);
tgt_lt DATE;
ctime DATE;
ltime DATE;
l_violation_type NUMBER;
l_value NUMBER;
l_metric_label VARCHAR2(64);
l_column_label VARCHAR2(64);
l_label VARCHAR2(64);
l_nlsid VARCHAR2(64);
l_policy_nlsid VARCHAR2(64);
BEGIN
details_out := MGMT_MAX_STRING_ARRAY();
details_out.extend(17);
-- note: use target_name as display_name because we don't expose
-- target display_name
BEGIN
SELECT tgt.target_name, tgt.target_type, tgt.target_name,
tgt.type_display_name, tgt.timezone_region,
tgt.host_name, tgt.target_guid, tgt.last_load_time,
s.violation_level, s.message, s.message_nlsid, s.message_params,
s.key_value, s.collection_timestamp,
s.load_timestamp, s.violation_type
INTO details_out(1), details_out(2), details_out(3), details_out(4),
details_out(5), hname, tguid, tgt_lt, details_out(12),
details_out(13), details_out(14), details_out(15),
kval, ctime, ltime, l_violation_type
FROM MGMT_TARGETS tgt, MGMT_VIOLATIONS s
WHERE s.violation_guid = violation_guid_in
AND tgt.target_guid = s.target_guid;
EXCEPTION
WHEN NO_DATA_FOUND
THEN
details_out := NULL;
IF emdw_log.p_is_debug_set
THEN
emdw_log.debug('GVD: invalid target: violation_guid = '
|| violation_guid_in,
DELIVER_MODULE_NAME) ;
END IF;
RETURN;
END;
-- note: use target_name as display_name because we don't expose
-- target display_name
details_out(6) := hname;
-- BEGIN
-- SELECT display_name INTO details_out(6) FROM MGMT_TARGETS
-- WHERE target_name = hname
-- AND target_type = MGMT_GLOBAL.G_HOST_TARGET_TYPE
-- AND rownum < 2;
-- EXCEPTION
-- WHEN NO_DATA_FOUND
-- THEN
-- details_out(6) := hname;
-- END;
IF l_violation_type = MGMT_GLOBAL.G_SEVERITY_TYPE_POLICY
THEN
BEGIN
SELECT p.policy_name, '', p.policy_label_nlsid, '',
p.description, p.policy_guid, p.metric_guid
INTO details_out(7), details_out(8), l_policy_nlsid,
details_out(10), details_out(11), pguid, mguid
FROM MGMT_POLICIES p, MGMT_VIOLATIONS v
WHERE v.violation_guid = violation_guid_in
AND p.policy_guid = v.policy_guid;
details_out(9) := MGMT_MESSAGE.GET_MESSAGE(l_policy_nlsid, 'POLICY',
language_in, country_in,
details_out(7));
EXCEPTION
WHEN NO_DATA_FOUND
THEN
details_out := NULL;
IF emdw_log.p_is_debug_set
THEN
emdw_log.debug('GVD: invalid policy: violation_guid = '
|| violation_guid_in,
DELIVER_MODULE_NAME) ;
END IF;
RETURN;
END;
ELSE
BEGIN
-- Get the metric details_out
SELECT m.metric_name, m.metric_column,
m.metric_label_nlsid, m.column_label_nlsid,
m.description, m.metric_label, m.column_label,
v.policy_guid, m.metric_guid
INTO details_out(7), details_out(8), details_out(9),
details_out(10), details_out(11), l_metric_label, l_column_label,
pguid, mguid
FROM MGMT_TARGETS t, MGMT_METRICS m, MGMT_VIOLATIONS v
WHERE v.violation_guid = violation_guid_in
AND t.target_guid = tguid
-- Apparently v.policy_guid should be used to lookup mgmt_policies
-- from where the metric_guid can be taken. This means joining on
-- mgmt_policies rather than going straight to mgmt_metrics
AND m.metric_guid = v.policy_guid
AND t.target_type = m.target_type
AND m.type_meta_ver = t.type_meta_ver
AND (m.category_prop_1 = t.category_prop_1 or m.category_prop_1 = ' ')
AND (m.category_prop_2 = t.category_prop_2 or m.category_prop_2 = ' ')
AND (m.category_prop_3 = t.category_prop_3 or m.category_prop_3 = ' ')
AND (m.category_prop_4 = t.category_prop_4 or m.category_prop_4 = ' ')
AND (m.category_prop_5 = t.category_prop_5 or m.category_prop_5 = ' ');
IF is_plsql_notification
THEN
details_out(9) := l_metric_label;
details_out(10) := l_column_label;
END IF;
EXCEPTION
WHEN NO_DATA_FOUND
THEN
details_out := NULL;
IF emdw_log.p_is_debug_set
THEN
emdw_log.debug('GVD: invalid metric: violation_guid = '
|| violation_guid_in,
DELIVER_MODULE_NAME) ;
END IF;
RETURN;
END;
END IF;
-- Get the context
ctxt_list_out := MGMT_NOTIFY_COLUMNS();
FOR ctx IN (SELECT column_name, column_type,
decode(column_type, 0, to_char(column_value),
1, column_str_value) col_value
FROM mgmt_violation_context
WHERE target_guid = tguid
AND policy_guid = pguid
AND key_value = kval
AND collection_timestamp = ctime)
LOOP
SELECT m1.column_label, m1.column_label_nlsid
INTO l_label, l_nlsid
FROM MGMT_TARGETS t, MGMT_METRICS m, MGMT_METRICS m1
WHERE t.target_guid = tguid
AND m.metric_guid = mguid
AND t.target_type = m.target_type
AND m.type_meta_ver = t.type_meta_ver
AND (m.category_prop_1 = t.category_prop_1 or m.category_prop_1 = ' ')
AND (m.category_prop_2 = t.category_prop_2 or m.category_prop_2 = ' ')
AND (m.category_prop_3 = t.category_prop_3 or m.category_prop_3 = ' ')
AND (m.category_prop_4 = t.category_prop_4 or m.category_prop_4 = ' ')
AND (m.category_prop_5 = t.category_prop_5 or m.category_prop_5 = ' ')
AND t.target_type = m1.target_type
AND m1.type_meta_ver = t.type_meta_ver
AND (m1.category_prop_1 = t.category_prop_1 or m1.category_prop_1 = ' ')
AND (m1.category_prop_2 = t.category_prop_2 or m1.category_prop_2 = ' ')
AND (m1.category_prop_3 = t.category_prop_3 or m1.category_prop_3 = ' ')
AND (m1.category_prop_4 = t.category_prop_4 or m1.category_prop_4 = ' ')
AND (m1.category_prop_5 = t.category_prop_5 or m1.category_prop_5 = ' ')
AND m1.metric_name = m.metric_name
AND m1.metric_column = ctx.column_name;
ctxt_list_out.extend;
ctxt_list_out(ctxt_list_out.COUNT) :=
MGMT_NOTIFY_COLUMN(l_label, l_nlsid, ctx.col_value);
END LOOP;
-- Get the metric value
SELECT value, string_value INTO l_value, details_out(16)
FROM MGMT_VIOLATIONS WHERE violation_guid = violation_guid_in;
IF details_out(16) IS NULL
THEN
details_out(16) := l_value;
END IF;
keys_out := GET_KEYS(mguid, tguid, kval);
-- Convert to centiseconds to represent the uptime of the target
details_out(17) := TRUNC((SYSDATE - tgt_lt) * (24*60*60*100));
-- pass out the collection timestamp as a date
collection_timestamp_out := ctime;
logged_timestamp_out := ltime;
END GET_VIOLATION_DETAILS;
FUNCTION GET_KEY_VALUE_NAME(keys_in IN MGMT_NOTIFY_COLUMNS)
RETURN VARCHAR2
IS
key_value_name VARCHAR2(512);
BEGIN
IF keys_in IS NULL OR keys_in.COUNT = 0
THEN
RETURN NULL;
END IF;
FOR i in keys_in.FIRST..keys_in.LAST
LOOP
IF i > 1
THEN
key_value_name := key_value_name || ';';
END IF;
key_value_name := key_value_name || keys_in(i).column_label;
END LOOP;
RETURN key_value_name;
END GET_KEY_VALUE_NAME;
FUNCTION GET_KEY_VALUE(keys_in IN MGMT_NOTIFY_COLUMNS)
RETURN VARCHAR2
IS
key_value VARCHAR2(1290);
BEGIN
IF keys_in IS NULL OR keys_in.COUNT = 0
THEN
RETURN NULL;
END IF;
FOR i in keys_in.FIRST..keys_in.LAST
LOOP
IF i > 1
THEN
key_value := key_value || ';';
END IF;
key_value := key_value || keys_in(i).value;
END LOOP;
RETURN key_value;
END GET_KEY_VALUE;
-- PURPOSE
-- To send a metric severity notification to a PL/SQL procedure
PROCEDURE METRIC_SEVERITY_FOR_PLSQL(violation_guid_in IN RAW,
language_in IN VARCHAR2,
country_in IN VARCHAR2,
device_owner_in IN VARCHAR2,
device_name_in IN VARCHAR2,
rule_owner_in IN VARCHAR2,
rule_name_in IN VARCHAR2,
procedure_name_out OUT VARCHAR2,
error_code_out OUT NUMBER,
error_out OUT VARCHAR2)
IS
pname VARCHAR2(512);
sev MGMT_NOTIFY_SEVERITY;
details MGMT_MAX_STRING_ARRAY;
cs DATE;
ls DATE;
mguid RAW(16);
tguid RAW(16);
kguid VARCHAR2(256);
keys MGMT_NOTIFY_COLUMNS;
ctxt_list MGMT_NOTIFY_COLUMNS;
BEGIN
BEGIN
-- Get the name of the procedure
SELECT program INTO pname FROM MGMT_NOTIFY_DEVICES
WHERE profile_name = device_owner_in AND device_name = device_name_in;
EXCEPTION WHEN NO_DATA_FOUND
THEN
error_code_out := NO_DEVICE_ERR;
procedure_name_out := NULL;
RETURN;
END;
error_code_out := 0;
procedure_name_out := pname;
-- Get the details of the severity
GET_VIOLATION_DETAILS(violation_guid_in, language_in, country_in, details,
cs, ls, keys, ctxt_list, TRUE);
IF details IS NULL
THEN
error_code_out := NO_SEVERITY_ERR;
RETURN;
END IF;
SELECT target_guid, policy_guid, key_value
INTO tguid, mguid, kguid FROM MGMT_VIOLATIONS
WHERE violation_guid = violation_guid_in;
sev := MGMT_NOTIFY_SEVERITY(rule_name_in, rule_owner_in,
details(3), details(4), details(5), details(6),
details(9), details(11), details(10), details(14),
GET_KEY_VALUE_NAME(keys), GET_KEY_VALUE(keys),
kguid, cs, details(12),
details(13), violation_guid_in, tguid, mguid,
ctxt_list);
-- Set the module and action
DBMS_APPLICATION_INFO.SET_MODULE(pname, violation_guid_in);
EXECUTE IMMEDIATE 'CALL ' || EM_CHECK.QUALIFIED_SQL_NAME(pname)
|| '(:s)' USING sev;
LOG_DELIVERY_TIME(cs, ls, details(5), PLSQL_DEVICE_TYPE);
-- Clear the module and action
DBMS_APPLICATION_INFO.SET_MODULE(NULL, NULL);
EXCEPTION
WHEN OTHERS
THEN
-- Clear the module and action
DBMS_APPLICATION_INFO.SET_MODULE(NULL, NULL);
error_code_out := SQLCODE;
error_out := SQLERRM;
procedure_name_out := pname;
END METRIC_SEVERITY_FOR_PLSQL;
-- PURPOSE
-- Get the details of a job state change for sending in a notification
PROCEDURE GET_JOB_STATE_CHANGE_DETAILS(state_change_guid_in IN RAW,
language_in IN VARCHAR2,
country_in IN VARCHAR2,
details_out OUT MGMT_NOTIFY_JOB_SC)
IS
target_names MGMT_MEDIUM_STRING_ARRAY;
target_types MGMT_MEDIUM_STRING_ARRAY;
timezones MGMT_SHORT_STRING_ARRAY;
stat NUMBER(2);
tguid RAW(16);
mguid RAW(16);
pguid RAW(16);
coll_ts DATE;
metric_name VARCHAR2(64);
metric_column VARCHAR2(64);
label VARCHAR2(64);
label_nlsid VARCHAR2(64);
policy VARCHAR2(64);
mtype NUMBER;
str_val VARCHAR2(1024);
val NUMBER;
vl NUMBER;
kval VARCHAR2(256);
keys MGMT_NOTIFY_COLUMNS;
ctxt_list MGMT_NOTIFY_COLUMNS;
l_label VARCHAR2(64);
l_nlsid VARCHAR2(64);
l_policy_name VARCHAR2(128);
l_policy_nlsid VARCHAR2(64);
l_job_type MGMT_JOB_TYPE_INFO.job_type_default%TYPE;
l_job_type_nlsid MGMT_JOB_TYPE_INFO.job_type_nlsid%TYPE;
l_job_type_id MGMT_JOB_TYPE_INFO.job_type_id%TYPE;
l_tz_rgn MGMT_TARGETS.timezone_region%TYPE;
BEGIN
-- There will only be one record
FOR sc IN (SELECT sc.*, j.job_name, j.job_owner
FROM MGMT_JOB_STATE_CHANGES sc, MGMT_JOB j
WHERE sc.state_change_guid = state_change_guid_in
AND j.job_id = sc.job_id
AND j.job_status != MGMT_JOBS.JOB_STATUS_DELETE_PENDING)
LOOP
-- Get the target details
SELECT DISTINCT tgt.target_name, tgt.target_type, tgt.timezone_region
BULK COLLECT INTO target_names, target_types, timezones
FROM MGMT_JOB_EXT_TARGETS jobtgt, MGMT_TARGETS tgt
WHERE jobtgt.job_id = sc.job_id
AND jobtgt.execution_id = sc.execution_id
AND tgt.target_guid = jobtgt.target_guid;
IF target_names IS NULL OR target_names.COUNT = 0
THEN
details_out := NULL;
IF emdw_log.p_is_debug_set
THEN
emdw_log.debug('GJD: targetless : job_id = '
|| sc.job_id,
DELIVER_MODULE_NAME) ;
END IF;
-- Targetless Job, use emdrep timezone
BEGIN
select TIMEZONE_REGION into l_tz_rgn from MGMT_TARGETS where target_type='oracle_emrep';
EXCEPTION
WHEN NO_DATA_FOUND THEN
l_tz_rgn := TO_CHAR(SYSTIMESTAMP,'TZR');
END;
ELSE
-- Job with target, use target's timezone
l_tz_rgn := timezones(1);
END IF;
-- Get the job type
BEGIN
l_job_type_id := MGMT_JOB_ENGINE.get_job_type_id(sc.job_id);
SELECT NVL(job_type_default, job_type), job_type_nlsid
INTO l_job_type, l_job_type_nlsid
FROM MGMT_JOB_TYPE_INFO
WHERE job_type_id = l_job_type_id;
EXCEPTION
WHEN NO_DATA_FOUND
THEN
IF emdw_log.p_is_debug_set
THEN
emdw_log.debug('GJD: GET_JOB_STATE_CHANGE_DETAILS: Job type not ' ||
'found for this job_id = ' || sc.job_id ||
', job_type_id = ' || l_job_type_id,
DELIVER_MODULE_NAME);
END IF;
END;
-- Check if this is for a job
IF sc.type = JOB_STATE_CHANGE
THEN
details_out := MGMT_NOTIFY_JOB_SC(sc.job_name, l_job_type,
l_job_type_nlsid, sc.job_owner,
target_names, target_types,
l_tz_rgn, sc.logged,
sc.occurred, sc.newstate,
sc.job_id, sc.execution_id,
sc.step_id, NULL, NULL, NULL, NULL,
NULL,0, NULL, NULL);
-- Check if it is for a CA run as a result of a metric severity
ELSIF sc.type = METRIC_CA_STATE_CHANGE
THEN
-- Get the severity details
SELECT target_guid, policy_guid, key_value, collection_timestamp,
value, string_value, violation_level
INTO tguid, pguid, kval, coll_ts, val, str_val, vl
FROM MGMT_VIOLATIONS
WHERE violation_guid = sc.violation_guid;
mguid := pguid;
-- Get the details of the metric
SELECT m.metric_name, m.metric_column, m.column_label,
m.column_label_nlsid, m.metric_type
INTO metric_name, metric_column, label, label_nlsid, mtype
FROM MGMT_TARGETS t, MGMT_METRICS m
WHERE t.target_guid = tguid
AND m.metric_guid = mguid
AND t.target_type = m.target_type
AND m.type_meta_ver = t.type_meta_ver
AND (m.category_prop_1 = t.category_prop_1 or m.category_prop_1 = ' ')
AND (m.category_prop_2 = t.category_prop_2 or m.category_prop_2 = ' ')
AND (m.category_prop_3 = t.category_prop_3 or m.category_prop_3 = ' ')
AND (m.category_prop_4 = t.category_prop_4 or m.category_prop_4 = ' ')
AND (m.category_prop_5 = t.category_prop_5 or m.category_prop_5 = ' ');
IF mtype = 0
THEN
str_val := val;
END IF;
-- Get the context
ctxt_list := MGMT_NOTIFY_COLUMNS();
FOR ctx IN (SELECT column_name, column_type,
decode(column_type, 0, to_char(column_value),
1, column_str_value) col_value
FROM mgmt_violation_context
WHERE target_guid = tguid
AND policy_guid = pguid
AND key_value = kval
AND collection_timestamp = coll_ts)
LOOP
SELECT m1.column_label, m1.column_label_nlsid
INTO l_label, l_nlsid
FROM MGMT_TARGETS t, MGMT_METRICS m, MGMT_METRICS m1
WHERE t.target_guid = tguid
AND m.metric_guid = mguid
AND t.target_type = m.target_type
AND m.type_meta_ver = t.type_meta_ver
AND (m.category_prop_1 = t.category_prop_1 or m.category_prop_1 = ' ')
AND (m.category_prop_2 = t.category_prop_2 or m.category_prop_2 = ' ')
AND (m.category_prop_3 = t.category_prop_3 or m.category_prop_3 = ' ')
AND (m.category_prop_4 = t.category_prop_4 or m.category_prop_4 = ' ')
AND (m.category_prop_5 = t.category_prop_5 or m.category_prop_5 = ' ')
AND t.target_type = m1.target_type
AND m1.type_meta_ver = t.type_meta_ver
AND (m1.category_prop_1 = t.category_prop_1 or
m1.category_prop_1 = ' ')
AND (m1.category_prop_2 = t.category_prop_2 or
m1.category_prop_2 = ' ')
AND (m1.category_prop_3 = t.category_prop_3 or
m1.category_prop_3 = ' ')
AND (m1.category_prop_4 = t.category_prop_4 or
m1.category_prop_4 = ' ')
AND (m1.category_prop_5 = t.category_prop_5 or
m1.category_prop_5 = ' ')
AND m1.metric_name = m.metric_name
AND m1.metric_column = ctx.column_name;
ctxt_list.extend;
ctxt_list(ctxt_list.COUNT) :=
MGMT_NOTIFY_COLUMN(l_label, l_nlsid, ctx.col_value);
END LOOP;
details_out := MGMT_NOTIFY_JOB_SC(sc.job_name, l_job_type,
l_job_type_nlsid, sc.job_owner,
target_names, target_types,
timezones(1), sc.logged,
sc.occurred, sc.newstate,
sc.job_id, sc.execution_id, sc.step_id,
label, label_nlsid,
metric_name, metric_column,
str_val, vl,
GET_KEYS(mguid, tguid, kval),
ctxt_list);
-- Check if it is for a CA run as a result of a policy violation
ELSIF sc.type = POLICY_CA_STATE_CHANGE
THEN
-- Get the violation details
SELECT target_guid, policy_guid, key_value, collection_timestamp,
value, string_value, violation_level
INTO tguid, pguid, kval, coll_ts, val, str_val, vl
FROM MGMT_VIOLATIONS
WHERE violation_guid = sc.violation_guid;
-- Get the details of the policy
SELECT policy_name, policy_label_nlsid, metric_guid
INTO l_policy_name, l_policy_nlsid, mguid
FROM MGMT_POLICIES
WHERE policy_guid = pguid;
policy := MGMT_MESSAGE.GET_MESSAGE(l_policy_nlsid, 'POLICY',
language_in, country_in,
l_policy_name);
IF str_val IS NULL
THEN
str_val := val;
END IF;
-- Get the context
ctxt_list := MGMT_NOTIFY_COLUMNS();
FOR ctx IN (SELECT column_name, column_type,
decode(column_type, 0, to_char(column_value),
1, column_str_value) col_value
FROM mgmt_violation_context
WHERE target_guid = tguid
AND policy_guid = pguid
AND key_value = kval
AND collection_timestamp = coll_ts)
LOOP
SELECT m1.column_label, m1.column_label_nlsid
INTO l_label, l_nlsid
FROM MGMT_TARGETS t, MGMT_METRICS m, MGMT_METRICS m1
WHERE t.target_guid = tguid
AND m.metric_guid = mguid
AND t.target_type = m.target_type
AND m.type_meta_ver = t.type_meta_ver
AND (m.category_prop_1 = t.category_prop_1 or m.category_prop_1 = ' ')
AND (m.category_prop_2 = t.category_prop_2 or m.category_prop_2 = ' ')
AND (m.category_prop_3 = t.category_prop_3 or m.category_prop_3 = ' ')
AND (m.category_prop_4 = t.category_prop_4 or m.category_prop_4 = ' ')
AND (m.category_prop_5 = t.category_prop_5 or m.category_prop_5 = ' ')
AND t.target_type = m1.target_type
AND m1.type_meta_ver = t.type_meta_ver
AND (m1.category_prop_1 = t.category_prop_1 or
m1.category_prop_1 = ' ')
AND (m1.category_prop_2 = t.category_prop_2 or
m1.category_prop_2 = ' ')
AND (m1.category_prop_3 = t.category_prop_3 or
m1.category_prop_3 = ' ')
AND (m1.category_prop_4 = t.category_prop_4 or
m1.category_prop_4 = ' ')
AND (m1.category_prop_5 = t.category_prop_5 or
m1.category_prop_5 = ' ')
AND m1.metric_name = m.metric_name
AND m1.metric_column = ctx.column_name;
ctxt_list.extend;
ctxt_list(ctxt_list.COUNT) :=
MGMT_NOTIFY_COLUMN(l_label, l_nlsid, ctx.col_value);
END LOOP;
details_out := MGMT_NOTIFY_JOB_SC(sc.job_name, l_job_type,
l_job_type_nlsid, sc.job_owner,
target_names, target_types,
timezones(1), sc.logged,
sc.occurred, sc.newstate,
sc.job_id, sc.execution_id, sc.step_id,
policy, l_policy_nlsid,
policy, ' ', str_val, vl,
GET_KEYS(mguid, tguid, kval),
ctxt_list);
END IF;
END LOOP;
EXCEPTION
WHEN NO_DATA_FOUND
THEN
IF emdw_log.p_is_debug_set
THEN
emdw_log.debug('GJD: unexpected error ' || SQLERRM,
DELIVER_MODULE_NAME) ;
END IF;
details_out := NULL;
END GET_JOB_STATE_CHANGE_DETAILS;
-- PURPOSE
-- To send a job/ca state change notification to a PL/SQL procedure
PROCEDURE STATE_CHANGE_FOR_PLSQL(state_change_guid_in IN RAW,
language_in IN VARCHAR2,
country_in IN VARCHAR2,
device_owner_in IN VARCHAR2,
device_name_in IN VARCHAR2,
rule_owner_in IN VARCHAR2,
rule_name_in IN VARCHAR2,
procedure_name_out OUT VARCHAR2,
error_code_out OUT NUMBER,
error_out OUT VARCHAR2)
IS
pname VARCHAR2(512);
change MGMT_NOTIFY_JOB;
ca_change MGMT_NOTIFY_CORRECTIVE_ACTION;
details MGMT_NOTIFY_JOB_SC;
targets SMP_EMD_NVPAIR_ARRAY := SMP_EMD_NVPAIR_ARRAY();
is_ca NUMBER;
kguid RAW(16);
BEGIN
BEGIN
-- Get the name of the procedure
SELECT program INTO pname FROM MGMT_NOTIFY_DEVICES
WHERE profile_name = device_owner_in AND device_name = device_name_in;
EXCEPTION WHEN NO_DATA_FOUND
THEN
error_code_out := NO_DEVICE_ERR;
procedure_name_out := NULL;
RETURN;
END;
error_code_out := 0;
procedure_name_out := pname;
-- Get the details of the state change
GET_JOB_STATE_CHANGE_DETAILS(state_change_guid_in, language_in, country_in,
details);
IF details IS NULL
THEN
error_code_out := NO_STATE_CHANGE_ERR;
RETURN;
END IF;
IF details.target_names IS NOT NULL AND details.target_names.COUNT > 0
THEN
targets.extend(details.target_names.COUNT);
FOR i IN details.target_names.FIRST..details.target_names.LAST
LOOP
targets(i) := SMP_EMD_NVPAIR(details.target_names(i),
details.target_types(i));
END LOOP;
END IF;
SELECT is_corrective_action INTO is_ca FROM MGMT_JOB
WHERE job_id = details.job_id
AND job_status != MGMT_JOBS.JOB_STATUS_DELETE_PENDING;
IF is_ca = 0
THEN
change := MGMT_NOTIFY_JOB(rule_name_in, rule_owner_in, details.job_name,
details.job_owner, details.job_type,
details.status, details.occurred,
state_change_guid_in,
details.job_id, details.execution_id, targets);
-- Set the module and action
DBMS_APPLICATION_INFO.SET_MODULE(pname, state_change_guid_in);
EXECUTE IMMEDIATE 'CALL ' || EM_CHECK.QUALIFIED_SQL_NAME(pname)
|| '(:s)' USING change;
ELSE
BEGIN
SELECT v.key_value INTO kguid
FROM MGMT_JOB_STATE_CHANGES sc, MGMT_VIOLATIONS v
WHERE sc.state_change_guid = state_change_guid_in
AND v.violation_guid = sc.violation_guid;
EXCEPTION WHEN OTHERS THEN NULL; END;
ca_change := MGMT_NOTIFY_CORRECTIVE_ACTION
(rule_name_in, rule_owner_in, details.job_name,
details.job_owner, details.job_type,
details.status, details.occurred, state_change_guid_in,
details.job_id, details.execution_id, targets,
details.metric_name, details.metric_column,
details.metric_value, details.violation_level,
GET_KEY_VALUE_NAME(details.keys),
GET_KEY_VALUE(details.keys),
kguid, details.ctxt_list);
-- Set the module and action
DBMS_APPLICATION_INFO.SET_MODULE(pname, state_change_guid_in);
EXECUTE IMMEDIATE 'CALL ' || EM_CHECK.QUALIFIED_SQL_NAME(pname)
|| '(:s)' USING ca_change;
END IF;
-- Clear the module and action
DBMS_APPLICATION_INFO.SET_MODULE(NULL, NULL);
EXCEPTION
WHEN OTHERS
THEN
dbms_output.put_line(sqlerrm);
error_code_out := SQLCODE;
error_out := SQLERRM;
procedure_name_out := pname;
END STATE_CHANGE_FOR_PLSQL;
-- PURPOSE
-- To set a notification up to be retried
PROCEDURE SETUP_FOR_RETRY(notification_in IN MGMT_NOTIFY_NOTIFICATION,
error_in IN VARCHAR2)
IS
BEGIN
-- If this was already a retry then update the stats
IF notification_in.notification_type = RETRY_NOTIFICATION
THEN
UPDATE MGMT_NOTIFY_REQUEUE SET last_timestamp = SYSDATE,
num_requeues = num_requeues + 1
WHERE device_name = notification_in.device_name
AND device_owner = notification_in.device_owner
AND source_guid = notification_in.source_guid
AND rule_name = notification_in.rule_name
AND rule_owner = notification_in.rule_owner;
ELSE
INSERT INTO MGMT_NOTIFY_REQUEUE
(source_guid, source_type, notification_type, device_name,
device_owner, device_type, rule_name, rule_owner)
VALUES (notification_in.source_guid, notification_in.source_type,
RETRY_NOTIFICATION, notification_in.device_name,
notification_in.device_owner, notification_in.device_type,
notification_in.rule_name, notification_in.rule_owner);
END IF;
-- Set the device to be down
UPDATE MGMT_NOTIFY_DEVICES SET STATUS = DEVICE_DOWN,
STATUS_MESSAGE = substr(error_in,1,512),
CONTACT_TIMESTAMP = SYSDATE
WHERE device_name = notification_in.device_name
AND profile_name = notification_in.device_owner;
END;
-- PURPOSE
-- Called when a device has been successfully pinged
PROCEDURE PING_SUCCEEDED(notification_in IN MGMT_NOTIFY_NOTIFICATION)
IS
BEGIN
-- Delete the requeue record
DELETE FROM MGMT_NOTIFY_REQUEUE
WHERE device_name = notification_in.device_name
AND device_owner = notification_in.device_owner
AND source_guid = notification_in.source_guid
AND rule_name = notification_in.rule_name
AND rule_owner = notification_in.rule_owner;
-- Set the device to be up
UPDATE MGMT_NOTIFY_DEVICES SET STATUS = DEVICE_UP,
STATUS_MESSAGE = '',
CONTACT_TIMESTAMP = SYSDATE
WHERE device_name = notification_in.device_name
AND profile_name = notification_in.device_owner;
-- Requeue any pending notifications
REQUEUE(notification_in.device_name, notification_in.device_owner);
END PING_SUCCEEDED;
-- PURPOSE
-- Log the delivery time for a severity;
PROCEDURE LOG_DELIVERY_TIME(collection_time_in IN DATE,
load_time_in IN DATE,
tz_region_in IN VARCHAR2,
device_type_in IN NUMBER,
oms_name_in IN VARCHAR2 DEFAULT NULL)
IS
now DATE;
delivery_time NUMBER := 0;
dt VARCHAR2(32);
tdt VARCHAR2(32);
errmsg VARCHAR2(256);
err NUMBER;
BEGIN
dt := PERF_DELIVERY_TIME;
tdt := PERF_TOTAL_DELIVERY_TIME;
BEGIN
IF device_type_in IN (EMAIL_DEVICE_TYPE, LONG_EMAIL_DEVICE_TYPE,
SHORT_EMAIL_DEVICE_TYPE)
THEN
dt := PERF_EMAIL_DELIVERY_TIME;
tdt := PERF_EMAIL_TOTAL_DELIVERY_TIME;
ELSIF device_type_in = PROGRAM_DEVICE_TYPE
THEN
dt := PERF_OSCMD_DELIVERY_TIME;
tdt := PERF_OSCMD_TOTAL_DELIVERY_TIME;
ELSIF device_type_in = PLSQL_DEVICE_TYPE
THEN
dt := PERF_PLSQL_DELIVERY_TIME;
tdt := PERF_PLSQL_TOTAL_DELIVERY_TIME;
ELSIF device_type_in = JAVA_DEVICE_TYPE
THEN
dt := PERF_JAVA_DELIVERY_TIME;
tdt := PERF_JAVA_TOTAL_DELIVERY_TIME;
ELSIF device_type_in = SNMP_DEVICE_TYPE
THEN
dt := PERF_SNMP_DELIVERY_TIME;
tdt := PERF_SNMP_TOTAL_DELIVERY_TIME;
mgmt_log.log_error(EMD_NOTIFICATION.CHECK_MODULE_NAME,
0,'device not found '||dt||' '||tdt,'','','','',
MGMT_GLOBAL.G_WARN);
END IF;
delivery_time := (SYSDATE-load_time_in) * (24*60*60*1000);
IF delivery_time > 0
THEN
mgmt_log.log_performance(EMD_NOTIFICATION.DELIVER_MODULE_NAME,
delivery_time, SYSDATE, 'N', dt,
delivery_time, NULL, NULL,
device_type_in, oms_name_in);
END IF;
-- Log the time it took from the severity being loaded into
-- the MGMT_VIOLATIONS table until the notification being delivered
BEGIN
now := mgmt_global.sysdate_tzrgn(tz_region_in);
-- Log the time it took from the severity being created until the
-- notification was delivered. Note that sysdate is converted to the
-- target timezone
delivery_time := (now-collection_time_in) * (24*60*60*1000);
IF delivery_time > 0
THEN
mgmt_log.log_performance(EMD_NOTIFICATION.DELIVER_MODULE_NAME,
delivery_time, SYSDATE, 'N', tdt,
delivery_time, NULL, NULL,
device_type_in, oms_name_in);
END IF;
EXCEPTION WHEN OTHERS
THEN
-- There is no point logging the time since we do not have the
-- current time correctly changed into the target timezone
NULL;
END;
EXCEPTION
WHEN OTHERS THEN
mgmt_log.log_error(EMD_NOTIFICATION.CHECK_MODULE_NAME,
err,'ERROR '||errmsg||
' during emd_notification.log_delivery_time','',
device_type_in,oms_name_in,'',MGMT_GLOBAL.G_ERROR);
err := SQLCODE;
errmsg := SUBSTR(SQLERRM,1,256);
IF err <> OLDERR OR OLDERRTIME < SYSDATE-(1/24)
THEN
mgmt_log.log_error(EMD_NOTIFICATION.CHECK_MODULE_NAME,
err,'ERROR '||errmsg||
' during emd_notification.log_delivery_time','',
device_type_in,oms_name_in,'',MGMT_GLOBAL.G_ERROR);
OLDERR := err;
OLDERRTIME := SYSDATE;
END IF;
END;
END LOG_DELIVERY_TIME;
-- PROCEDURE
-- To log a record of a delivery
--
PROCEDURE LOG_HISTORY(source_obj_type_in IN NUMBER,
source_obj_guid_in IN RAW,
delivered_in IN VARCHAR2,
message_in IN VARCHAR2,
tz_region_in IN VARCHAR2 DEFAULT NULL)
IS
t DATE;
tz_region VARCHAR2(64);
guid RAW(16) := source_obj_guid_in;
source_type NUMBER := source_obj_type_in;
BEGIN
IF tz_region_in IS NULL
THEN
SELECT timezone_region INTO tz_region
FROM MGMT_TARGETS tgt, MGMT_VIOLATIONS sev
WHERE sev.violation_guid = source_obj_guid_in
AND tgt.target_guid = sev.target_guid;
t := mgmt_global.sysdate_tzrgn(tz_region);
ELSE
t := mgmt_global.sysdate_tzrgn(tz_region_in);
END IF;
IF source_obj_type_in IN (METRIC_CA_STATE_CHANGE,
POLICY_CA_STATE_CHANGE)
THEN
source_type := METRIC_SEVERITY;
BEGIN
SELECT violation_guid INTO guid FROM MGMT_JOB_STATE_CHANGES
WHERE state_change_guid = source_obj_guid_in;
EXCEPTION WHEN NO_DATA_FOUND
THEN
guid := source_obj_guid_in;
END;
END IF;
INSERT INTO MGMT_NOTIFICATION_LOG
(source_obj_type, source_obj_guid, timestamp, delivered, message)
VALUES (source_type, guid, t, delivered_in, message_in);
EXCEPTION
WHEN OTHERS
THEN
INSERT INTO MGMT_NOTIFICATION_LOG
(source_obj_type, source_obj_guid, timestamp, delivered, message)
VALUES (source_type, source_obj_guid_in, SYSDATE, delivered_in,
message_in);
END LOG_HISTORY;
--
-- PURPOSE
--
-- To remove deleted targets from notification rules
--
-- PARAMETERS
--
-- TARGET_NAME_IN - the target name of the deleted target
-- TARGET_TYPE_IN - the type of the deleted target
--
PROCEDURE HANDLE_TARGET_DELETED(target_name_in IN VARCHAR2,
target_type_in IN VARCHAR2,
target_guid_in IN RAW)
IS
tguid RAW(16);
BEGIN
BEGIN
SELECT target_guid INTO tguid FROM MGMT_TARGETS
WHERE target_name = target_name_in
AND target_type = target_type_in;
EXCEPTION WHEN NO_DATA_FOUND
THEN
RETURN;
END;
DELETE FROM MGMT_NOTIFY_RULE_CONFIGS
WHERE (target_name = target_name_in AND target_type = target_type_in) OR
target_guid = tguid;
DELETE FROM MGMT_NOTIFY_JOB_RULE_CONFIGS
WHERE (target_name = target_name_in AND target_type = target_type_in) OR
target_guid = tguid;
END HANDLE_TARGET_DELETED;
-- PURPOSE
--
-- To cleanup when a key value has been deleted
--
-- PARAMETERS
--
-- P_TARGET_GUID - the target GUID
-- P_METRIC_GUID - the metric GUID
-- P_KEY_VALUE - the key value
--
PROCEDURE HANDLE_METRIC_KEYVAL_DELETION(
p_target_guid mgmt_targets.target_guid%TYPE,
p_metric_guid mgmt_metrics.metric_guid%TYPE,
p_key_value mgmt_metrics_raw.key_value%TYPE)
IS
l_target_name VARCHAR2(256);
l_target_type VARCHAR2(64);
l_met_col VARCHAR2(64);
BEGIN
--trace('called with: ' || p_target_guid || '/' || p_metric_guid || '/' ||
--p_key_value);
SELECT target_name, target_type INTO l_target_name, l_target_type
FROM MGMT_TARGETS
WHERE target_guid = p_target_guid;
-- Using like here to match names in case the Console goes to supporting
-- multiple target types in rules. It already supports multiple targets
-- of the same type
DELETE FROM MGMT_NOTIFY_RULE_CONFIGS
WHERE l_target_type LIKE target_type
AND l_target_name LIKE target_name
AND key_value = p_key_value;
COMMIT;
EXCEPTION WHEN OTHERS
THEN
NULL;
END HANDLE_METRIC_KEYVAL_DELETION;
-- PURPOSE
--
-- To queue a severity into MGMT_NOTIFY_INPUT_Q
--
-- PARAMETERS
--
-- p_msg - violation GUID or state change guid + guid type
-- p_guid_type - JOB_STATE_CHANGE or SEVERITY
PROCEDURE QUEUE_NOTIF_INPUT(p_msg_in RAW,
p_guid_type NUMBER)
IS
enq_options dbms_aq.enqueue_options_t;
qMsg_properties dbms_aq.message_properties_t;
qMsg_handle RAW(16);
BEGIN
IF(length(p_msg_in) != 32 OR p_guid_type NOT IN (GUID_TYPE_SEVERITY, GUID_TYPE_JOB_STATE_CHANGE))
THEN
IF EMDW_LOG.P_IS_INFO_SET
THEN
EMDW_LOG.INFO('Invalid severity / job_state_change GUID or invalid guid type : ' ||
p_msg_in || ' : ' || p_guid_type, 'queue_notif_input');
END IF;
END IF;
-- Add the message to the queue
DBMS_AQ.ENQUEUE(queue_name => G_NOTIFY_INPUT_Q_NAME,
enqueue_options => enq_options,
message_properties => qMsg_properties,
payload => utl_raw.cast_to_raw(p_msg_in || '|' || p_guid_type),
msgid => qMsg_handle);
EXCEPTION
WHEN OTHERS
THEN
mgmt_log.log_error(EMD_NOTIFICATION.CHECK_MODULE_NAME,
MGMT_GLOBAL.UNEXPECTED_ERR,
MGMT_GLOBAL.UNEXPECTED_ERR_M ||
'Error while enquing the severity : ' || p_msg_in || SQLERRM,
'ORA', p_msg_in);
END QUEUE_NOTIF_INPUT;
-- PURPOSE
--
-- To de-queue a severity from MGMT_NOTIFY_INPUT_Q
--
-- PARAMETERS
--
-- p_notif_src_guid - SEVERITY OR JOB_STATE_CHANGE_GUID
-- p_guid_type - JOB_STATE_CHANGE or SEVERITY
-- p_rule_guid - RULE GUID in case of repeat signal, null otherwise
-- p_repeat_count - Repeat count in case of repeat notification, null otherwise
PROCEDURE DEQUEUE_NOTIF_INPUT(p_notif_src_guid OUT RAW,
p_guid_type OUT NUMBER,
p_rule_guid OUT RAW,
p_repeat_count OUT NUMBER)
IS
dq_options dbms_aq.dequeue_options_t;
qMsg_properties dbms_aq.message_properties_t;
msg RAW(500);
msg_content VARCHAR2(500);
qmsg_id_out RAW(32);
BEGIN
dq_options.navigation := DBMS_AQ.FIRST_MESSAGE;
dq_options.wait := DBMS_AQ.NO_WAIT;
-- Dequeue a notification
DBMS_AQ.DEQUEUE(queue_name => G_NOTIFY_INPUT_Q_NAME,
dequeue_options => dq_options,
message_properties => qMsg_properties,
payload => msg,
msgid => qmsg_id_out);
msg_content := utl_raw.cast_to_varchar2(msg);
-- check for lenght
-- change the code to extract the data
p_notif_src_guid := hextoraw(substr(msg_content,1,32));
p_guid_type := substr(msg_content,34,1);
IF(length (msg_content) > 34)
THEN
p_rule_guid := hextoraw(substr(msg_content,36,32));
p_repeat_count := to_number(substr(msg_content,69));
ELSE
p_rule_guid := NULL;
p_repeat_count := NULL;
END IF;
END DEQUEUE_NOTIF_INPUT;
-- PURPOSE
--
-- To update and en-queue RCA completed severity in MGMT_NOTIFY_INPUT_Q
--
-- PARAMETERS
--
-- violation_guid_in - violation guid
PROCEDURE UPDATE_AND_ENQUEUE_RCA_SEV(violation_guid_in IN RAW,
notif_status_in IN NUMBER)
IS
BEGIN
UPDATE mgmt_violations
SET load_timestamp = SYSDATE,
notification_status = notif_status_in
WHERE violation_guid = violation_guid_in;
QUEUE_NOTIF_INPUT(violation_guid_in, EMD_NOTIFICATION.GUID_TYPE_SEVERITY);
END UPDATE_AND_ENQUEUE_RCA_SEV;
-- PURPOSE
--
-- To retrieve global repeat settings
--
-- PARAMETERS
-- p_enabled - 1 if enabled, 0 is disabled
-- p_frequency - frequency in minutes,
-- p_count -- maximum repeat count
--
PROCEDURE GET_GLOBAL_REPEAT_SETTINGS(
p_enabled OUT NUMBER,
p_frequency OUT NUMBER,
p_count OUT NUMBER)
IS
BEGIN
p_enabled := GET_CONFIG_VALUE(REPEAT_ENABLED_PARAM, REPEAT_ENABLED_DEFAULT);
p_frequency := GET_CONFIG_VALUE(REPEAT_FREQUENCY_PARAM, REPEAT_FREQUENCY_DEFAULT);
p_count := GET_CONFIG_VALUE(REPEAT_COUNT_PARAM, REPEAT_COUNT_DEFAULT);
END;
-- PURPOSE
--
-- To set global repeat settings
--
-- PARAMETERS
-- p_enabled - 1 if enabled, 0 is disabled
-- p_frequency - frequency in minutes,
-- p_count -- maximum repeat count
--
PROCEDURE SET_GLOBAL_REPEAT_SETTINGS(
p_enabled IN NUMBER DEFAULT REPEAT_ENABLED_DEFAULT,
p_frequency IN NUMBER DEFAULT REPEAT_FREQUENCY_DEFAULT,
p_count IN NUMBER DEFAULT REPEAT_COUNT_DEFAULT)
IS
l_current_user VARCHAR2(256) := MGMT_USER.GET_CURRENT_EM_USER;
BEGIN
-- Ensure that the caller is a super-user.
IF MGMT_USER.has_priv(l_current_user, MGMT_USER.SUPER_USER) = 0 THEN
raise_application_error(MGMT_GLOBAL.INSUFFICIENT_PRIVILEGES_ERR,
'Only superusers can set global repeat notification settings');
END IF;
SET_CONFIG_VALUE(REPEAT_ENABLED_PARAM, p_enabled);
SET_CONFIG_VALUE(REPEAT_FREQUENCY_PARAM, p_frequency);
SET_CONFIG_VALUE(REPEAT_COUNT_PARAM, p_count);
END;
-- PURPOSE
--
-- To queue a repeat signal into MGMT_NOTIFY_INPUT_Q
--
-- PARAMETERS
--
-- p_msg - violation GUID or state change guid + guid type
-- p_rule_guid - GUID of the rule for which repeat is enabled
-- p_repeat_count - Number of times the repeat is sent for this severity
-- p_delay - duration in minutes after which repeat notification should be send
PROCEDURE QUEUE_REPEAT_NOTIF_INPUT(p_msg_in RAW,
p_rule_guid RAW,
p_repeat_count NUMBER,
p_delay NUMBER)
IS
enq_options dbms_aq.enqueue_options_t;
qMsg_properties dbms_aq.message_properties_t;
qMsg_handle RAW(16);
l_payload VARCHAR2(256);
BEGIN
qMsg_properties.delay := p_delay * 60;
IF(length(p_msg_in) != 32)
THEN
IF EMDW_LOG.P_IS_INFO_SET
THEN
EMDW_LOG.INFO('Invalid severity GUID : ' || p_msg_in , 'queue_notif_input');
END IF;
END IF;
l_payload := p_msg_in || '|' || GUID_TYPE_REP_SEVERITY || '|' || p_rule_guid || '|' || p_repeat_count;
-- Add the message to the queue
DBMS_AQ.ENQUEUE(queue_name => G_NOTIFY_INPUT_Q_NAME,
enqueue_options => enq_options,
message_properties => qMsg_properties,
payload => utl_raw.cast_to_raw(l_payload),
msgid => qMsg_handle);
EXCEPTION
WHEN OTHERS
THEN
mgmt_log.log_error(EMD_NOTIFICATION.CHECK_MODULE_NAME,
MGMT_GLOBAL.UNEXPECTED_ERR,
MGMT_GLOBAL.UNEXPECTED_ERR_M ||
'Error while enquing the severity : ' || p_msg_in || SQLERRM,
'ORA', p_msg_in);
END QUEUE_REPEAT_NOTIF_INPUT;
--
-- PROCEDURE: ACKNOWLEDGE_ALERT
--
-- PURPOSE
-- To acknowledge a particular alert record.
--
-- PARAMETERS
-- p_violation_guid - GUID of the violation record that needs to be acknowledged.
-- p_acknowledged_by - User name who aknowledged this alert.
-- p_annotation_type - Annotation type for severity acknowledged annotation
-- p_message - Annotation message
PROCEDURE ACKNOWLEDGE_ALERT(p_violation_guid IN RAW,
p_acknowledged_by IN VARCHAR2,
p_annotation_type IN VARCHAR2,
p_message IN VARCHAR2)
IS
l_target_guid RAW(16);
l_tz_region VARCHAR2(64);
BEGIN
IF( p_violation_guid IS NULL OR p_acknowledged_by IS NULL OR
p_annotation_type IS NULL OR p_message IS NULL )
THEN
raise_application_error(MGMT_GLOBAL.INVALID_PARAMS_ERR,
'All the parameters are mandatory');
END IF;
UPDATE mgmt_violations
SET acknowledged = 1,
acknowledged_by = p_acknowledged_by
WHERE violation_guid = p_violation_guid
RETURNING target_guid INTO l_target_guid;
IF( l_target_guid IS NULL)
THEN
raise_application_error(MGMT_GLOBAL.INVALID_PARAMS_ERR,
'Violation record does not exist');
END IF;
SELECT TIMEZONE_REGION
INTO l_tz_region
FROM mgmt_targets
WHERE target_guid = l_target_guid;
INSERT INTO MGMT_ANNOTATION (source_obj_type, source_obj_guid,
timestamp, annotation_type,
user_name, message)
VALUES (MGMT_GLOBAL.G_ANNOTATION_SOURCE_SEVERITY, p_violation_guid,
mgmt_global.sysdate_tzrgn(l_tz_region), p_annotation_type,
p_acknowledged_by, p_message);
END ACKNOWLEDGE_ALERT;
BEGIN
-- Get the repository owner and set up the queue name to avoid string
-- concatentation
G_REPOSITORY_OWNER := MGMT_USER.GET_REPOSITORY_OWNER;
G_QUEUE_NAME := G_REPOSITORY_OWNER || '.MGMT_NOTIFY_Q';
G_NOTIFY_INPUT_Q_NAME := G_REPOSITORY_OWNER || '.MGMT_NOTIFY_INPUT_Q';
G_DEV_PING_STATE_TIMEOUT := GET_CONFIG_VALUE(NOTIFY_DEV_PING_STATE_TIMEOUT, DEF_DEV_PING_STATE_TIMEOUT);
END EMD_NOTIFICATION;
/
show errors