Rem drv:
Rem
Rem $Header: blackout_triggers.sql 02-aug-2006.11:52:46 rkpandey Exp $
Rem $Header: blackout_triggers.sql 02-aug-2006.11:52:46 rkpandey Exp $
Rem
Rem blackout_triggers.sql
Rem
Rem Copyright (c) 2002, 2006, Oracle. All rights reserved.
Rem
Rem NAME
Rem blackout_triggers.sql -
Rem
Rem DESCRIPTION
Rem
Rem
Rem NOTES
Rem
Rem
Rem MODIFIED (MM/DD/YY)
Rem rkpandey 08/02/06 - Backport rkpandey_fix_host_notif from main
Rem skini 12/12/05 - Backport skini_bug-4696597 from main
Rem rkpandey 03/31/06 - blackout agent at last
Rem skini 11/28/05 - Fix bu 4696597: when closing node-level
Rem agent-side blackouts, process all current
Rem targets
Rem skini 09/21/05 - After avail change, catch all exceptions
Rem pratagar 08/29/05 - bug 4572196
Rem pmodi 07/08/05 - Bug:4399250 - Use NLS message id for blackout
Rem skini 07/10/05 - Fix bug 4367848: catch NO_DATA_FOUND
Rem gsbhatia 07/01/05 - New repmgr header impl
Rem gsbhatia 06/26/05 - New repmgr header impl
Rem skini 04/12/05 - Fix infinite loop
Rem skini 04/07/05 - Add update trigger to MMGT_BLACKOUTS
Rem skini 03/21/05 - Change blackout message
Rem kmanicka 03/04/05 - move to EMDW_LOG from dbms_output
Rem skini 02/20/05 - Fix 4150882: select distinct
Rem gsbhatia 02/13/05 - updating repmgr header
Rem gsbhatia 02/09/05 - updating repmgr header
Rem gsbhatia 02/07/05 - updating repmgr header
Rem ktlaw 01/11/05 - add repmgr header
Rem snakai 11/22/04 - update beacon avail calls
Rem dhgoswam 11/02/04 - bug 3851644
Rem snakai 10/31/04 - process blackout end events for beacon monitored
Rem tgts
Rem rpinnama 09/13/04 - mgmt_severity -> mgmt_violations (esp for returning clause)
Rem skini 09/03/04 - Fix equal start times
Rem skini 08/30/04 - Fix for bug 3413008: account for out-of-order
Rem jobs
Rem skini 08/18/04 - Catch no_data_found
Rem gan 07/16/04 - handle duplicate record for severity bug 3492516
Rem skini 12/15/03 - Move end time check to trigger
Rem skini 12/05/03 - Obtain a lock before querying in insert trigger
Rem streddy 11/30/03 - Call master_agent package for blackouts
Rem skini 09/25/03 - Convert repos columns to utc columns
Rem skini 09/12/03 - Update source for emctl BOs
Rem skini 08/28/03 - Only update windows for the current occurrence
Rem ancheng 02/14/03 - target version fix
Rem skini 01/16/03 - Insert flat target entries for cli blackouts
Rem skini 12/05/02 - Generate messages
Rem skini 12/03/02 - Change in set_blackout_status
Rem skini 11/24/02 - Add repos timestamps to windows table
Rem skini 11/15/02 - Use category props
Rem skini 11/12/02 - Add triggers to update blackout windows
Rem skini 08/26/02 - ENDED state
Rem skini 08/25/02 - Use set_blackout_status
Rem skini 08/20/02 - New blackout states
Rem skini 08/05/02 - Update blackout status
Rem skini 07/30/02 - Overlapping blackouts
Rem skini 07/26/02 - continue blackout development
Rem skini 07/23/02 - Handle overlapping blackouts
Rem rpinnama 06/05/02 - Insert severity record on detecting blackout start.
Rem skini 06/12/02 - Table name change
Rem rpinnama 05/14/02 - rpinnama_reorg_rep_scripts
Rem rpinnama 05/14/02 - Created
Rem
rem
rem capture some availability data by watching blackout state changes
rem (0 = in blackout, 1 = out of blackout)
rem
CREATE OR REPLACE TRIGGER blackout_change
BEFORE INSERT ON MGMT_BLACKOUT_STATE FOR EACH ROW
DECLARE
latest_availability_rowid ROWID;
latest_availability_status NUMBER;
latest_availability_sev_guid RAW(16);
new_annotation_guid RAW(16);
l_emd_url VARCHAR2(2000);
l_count NUMBER;
l_target_guid RAW(16);
is_target_type_host BOOLEAN;
host_guid RAW(16);
host_availability_status NUMBER;
l_current_target_state NUMBER;
l_current_blackout_state NUMBER;
l_blackout_name MGMT_BLACKOUTS.blackout_name%TYPE;
l_created_by MGMT_BLACKOUTS.created_by%TYPE;
l_reason_id MGMT_BLACKOUTS.reason_id%TYPE;
l_reason MGMT_BLACKOUT_REASON.reason%TYPE;
l_created_thru MGMT_BLACKOUTS.created_thru%TYPE;
l_actual_start_time DATE;
l_actual_end_time DATE;
l_occurrence_number NUMBER;
response_metric_guid RAW(16);
update_availability BOOLEAN := false;
l_new_blackout_status NUMBER;
l_monitoring_mode NUMBER;
l_open_windows MGMT_BLACKOUT_WINDOW_ARRAY;
l_current_window MGMT_BLACKOUT_WINDOW_RECORD;
-- A list of blackout windows to potentially end as part
-- of the processing for the current window.
-- Entries here are inserted in ascending order of end time.
l_blackouts_to_end MGMT_BLACKOUT_WINDOW_ARRAY := MGMT_BLACKOUT_WINDOW_ARRAY();
k NUMBER;
l_start_msg VARCHAR2(1000);
l_stop_msg VARCHAR2(1000);
l_start_msg_params VARCHAR2(1000);
l_stop_msg_params VARCHAR2(1000);
BEGIN
-- Check for invalid entries
BEGIN
SELECT blackout_status, created_thru, occurrence_number,
created_by, reason_id, blackout_name INTO
l_current_blackout_state, l_created_thru, l_occurrence_number,
l_created_by, l_reason_id, l_blackout_name FROM
MGMT_BLACKOUTS WHERE blackout_guid=:new.blackout_guid;
IF l_reason_id IS NOT NULL THEN
SELECT reason INTO l_reason
FROM MGMT_BLACKOUT_REASON
WHERE reason_id=l_reason_id;
ELSE
l_reason := '';
END IF;
EXCEPTION
WHEN NO_DATA_FOUND THEN
-- Blackout definition does not exist! Reject it?
raise_application_error(MGMT_GLOBAL.INVALID_BLACKOUT_ERR,
'Blackout ' || :new.blackout_guid || ' does not exist');
END;
-- Check for duplicates. We reject the last one
SELECT COUNT(*) INTO l_count FROM MGMT_BLACKOUT_STATE WHERE
blackout_guid=:new.blackout_guid AND
target_guid=:new.target_guid AND
collection_timestamp=:new.collection_timestamp AND
blackout_code=:new.blackout_code;
IF l_count > 0 THEN
raise_application_error(MGMT_GLOBAL.DUPLICATE_RECORD_ERR,
'Duplicate record generated for guid ' || :new.blackout_guid);
END IF;
-- Lock a row in the blackouts proxy tables to serialize
-- severity inserts for a single target
SELECT target_guid INTO l_target_guid
FROM MGMT_BLACKOUT_PROXY_TARGETS
WHERE target_guid=:new.target_guid
FOR UPDATE;
-- Collect all active blackout windows that start before the current
-- one. Some of them will potentially have to be started, others stopped
SELECT MGMT_BLACKOUT_WINDOW_RECORD(blackout_guid, occurrence_number,
start_time, end_time, status)
BULK COLLECT INTO l_open_windows
FROM MGMT_BLACKOUT_WINDOWS
WHERE target_guid=:new.target_guid
AND status NOT IN (MGMT_BLACKOUT.BLK_STATE_STOPPED,
MGMT_BLACKOUT.BLK_STATE_ENDED)
AND start_time < :new.collection_timestamp
AND blackout_guid != :new.blackout_guid
ORDER BY start_time;
IF l_open_windows IS NOT NULL AND l_open_windows.COUNT > 0 THEN
-- We need to always lock the blackouts in the same order to
-- prevent deadlocks. Proceed only after all locks are obtained.
-- MGMT_BLACKOUT_ENGINE.lock_windows(l_open_windows);
FOR i IN 1..l_open_windows.COUNT LOOP
l_current_window := l_open_windows(i);
-- Close all pending windows whose end time is less
-- than the current start time. Note that these
-- windows are already in sorted order.
FOR j IN 1..l_blackouts_to_end.COUNT LOOP
IF l_blackouts_to_end(j).end_time <= l_current_window.start_time THEN
IF EMDW_LOG.p_is_debug_set THEN
EMDW_LOG.debug('Closing window with end time ' ||
to_char(l_blackouts_to_end(j).end_time, 'mm/dd/yyyy hh:mi:ss pm'),MGMT_BLACKOUT_ENGINE.MODULE_NAME);
END IF;
MGMT_BLACKOUT_ENGINE.end_blackout_window(l_blackouts_to_end(j).blackout_guid,
l_blackouts_to_end(j).occurrence_number,
:new.target_guid,
l_blackouts_to_end(j).end_time);
l_blackouts_to_end.delete(j);
END IF;
END LOOP;
-- Insert a START for the current window, if required
IF l_current_window.status=MGMT_BLACKOUT.BLK_STATE_START_PENDING THEN
IF EMDW_LOG.p_is_debug_set THEN
EMDW_LOG.debug('STARTING window with start time ' ||
to_char(l_current_window.start_time, 'mm/dd/yyyy hh:mi:ss pm'),MGMT_BLACKOUT_ENGINE.MODULE_NAME);
END IF;
MGMT_BLACKOUT_ENGINE.start_blackout_window(l_current_window.blackout_guid,
l_current_window.occurrence_number,
:new.target_guid);
END IF;
-- Add the end time in sorted order to the current list
-- of blackouts that may need to be ended
IF l_current_window.end_time IS NOT NULL THEN
k := 1;
WHILE k <= l_blackouts_to_end.COUNT AND
l_blackouts_to_end(k).end_time < l_current_window.end_time LOOP
k := k+1;
END LOOP;
l_blackouts_to_end.extend(1);
IF k < l_blackouts_to_end.COUNT THEN
FOR l IN k+1..l_blackouts_to_end.COUNT-1 LOOP
l_blackouts_to_end(l+1):= l_blackouts_to_end(l);
END LOOP;
END IF;
l_blackouts_to_end(k) := l_current_window;
IF EMDW_LOG.p_is_debug_set THEN
EMDW_LOG.debug('Added to end list window with start time ' ||
to_char(l_current_window.start_time, 'mm/dd/yyyy hh:mi:ss pm') ||
' end time ' || to_char(l_current_window.end_time, 'mm/dd/yyyy hh:mi:ss pm') ||
' at index ' || k,MGMT_BLACKOUT_ENGINE.MODULE_NAME);
END IF;
END IF;
END LOOP;
-- End all remaining open windows that need to be ended
-- before this one
-- Note that the previous loop would have
-- ended only blackout windows scheduled to end before the
-- start of another one
FOR j IN 1..l_blackouts_to_end.COUNT LOOP
IF l_blackouts_to_end(j).end_time < :new.collection_timestamp THEN
IF EMDW_LOG.p_is_debug_set THEN
EMDW_LOG.debug('Closing window with end time ' ||
to_char(l_blackouts_to_end(j).end_time, 'mm/dd/yyyy hh:mi:ss pm'),MGMT_BLACKOUT_ENGINE.MODULE_NAME);
END IF;
MGMT_BLACKOUT_ENGINE.end_blackout_window(l_blackouts_to_end(j).blackout_guid,
l_blackouts_to_end(j).occurrence_number,
:new.target_guid,
l_blackouts_to_end(j).end_time);
END IF;
END LOOP;
END IF;
-- Get the current target state, accounting for overlapping
-- blackouts
SELECT SUM(decode(blackout_status, 1, 1, 0)) INTO l_count
FROM MGMT_BLACKOUT_FLAT_TARGETS WHERE
target_guid=:new.target_guid;
IF l_count > 0 THEN
l_current_target_state := MGMT_BLACKOUT_ENGINE.IN_BLACKOUT;
ELSE
l_current_target_state := MGMT_BLACKOUT_ENGINE.NOT_IN_BLACKOUT;
END IF;
IF EMDW_LOG.p_is_debug_set THEN
EMDW_LOG.debug('Old target state for ' || :new.target_guid ||
' is ' || l_current_target_state,MGMT_BLACKOUT_ENGINE.MODULE_NAME);
END IF;
-- Update the state of the target in the blackout flat target status
UPDATE MGMT_BLACKOUT_FLAT_TARGETS SET blackout_status=:new.blackout_code
WHERE blackout_guid=:new.blackout_guid AND
target_guid=:new.target_guid;
IF :new.blackout_code = MGMT_BLACKOUT_ENGINE.IN_BLACKOUT THEN
:new.target_status := MGMT_BLACKOUT_ENGINE.IN_BLACKOUT;
ELSE
-- Obtain the overall state of the target; this is what we
-- should actually set the target_state to
SELECT SUM(decode(blackout_status, 1, 1, 0)) INTO l_count
FROM MGMT_BLACKOUT_FLAT_TARGETS WHERE
target_guid=:new.target_guid;
IF l_count > 0 THEN
-- In blackout
:new.target_status := MGMT_BLACKOUT_ENGINE.IN_BLACKOUT;
ELSE
-- Not in blackout
:new.target_status := MGMT_BLACKOUT_ENGINE.NOT_IN_BLACKOUT;
END IF;
END IF;
-- Update the overall blackout state IF this is a cli blackout
-- For repository blackouts, the overall state will be updated
-- after all targets have been processed
IF l_created_thru IS NOT NULL THEN
IF :new.blackout_code=MGMT_BLACKOUT_ENGINE.IN_BLACKOUT THEN
UPDATE MGMT_BLACKOUT_FLAT_TARGETS
SET job_status=MGMT_BLACKOUT_ENGINE.BLK_JSTATE_STARTED
WHERE blackout_guid=:new.blackout_guid
AND target_guid=:new.target_guid;
ELSE
UPDATE MGMT_BLACKOUT_FLAT_TARGETS
SET job_status=MGMT_BLACKOUT_ENGINE.BLK_JSTATE_STOPPED
WHERE blackout_guid=:new.blackout_guid
AND target_guid=:new.target_guid;
END IF;
MGMT_BLACKOUT_ENGINE.set_blackout_status(:new.blackout_guid,
MGMT_BLACKOUT_ENGINE.BLK_MODE_NONE);
SELECT blackout_status
INTO l_new_blackout_status
FROM MGMT_BLACKOUTS
WHERE blackout_guid=:new.blackout_guid;
IF l_new_blackout_status=MGMT_BLACKOUT_ENGINE.BLK_STATE_ENDED THEN
SELECT emd_url INTO l_emd_url
FROM MGMT_TARGETS
WHERE target_guid=:new.target_guid;
MGMT_BLACKOUT_ENGINE.submit_discard_state_job(:new.blackout_guid,
l_emd_url,
:new.collection_timestamp);
END IF;
END IF;
IF EMDW_LOG.p_is_debug_set THEN
EMDW_LOG.debug('New target state for ' || :new.target_guid ||
' is ' || :new.target_status,MGMT_BLACKOUT_ENGINE.MODULE_NAME);
END IF;
-- Generate a severity (which will affect availability)
-- only if the state of the target has changed
IF :new.target_status != l_current_target_state THEN
update_availability := true;
END IF;
-- TODO:
-- Exclude beacons
-- Generate appropriate annotations
-- Log errors if we receive an invalid blackout code
-- or target_guid.
--
-- Get Response/Status Metric guid for the target
-- Can we avoid getting this guid and get this in severity trigger?
--
IF update_availability THEN
BEGIN
SELECT DISTINCT met.metric_guid INTO response_metric_guid
FROM MGMT_TARGETS tgt, MGMT_METRICS met
WHERE tgt.target_guid = :new.target_guid
AND tgt.target_type = met.target_type
AND met.metric_name = MGMT_GLOBAL.G_AVAIL_METRIC_NAME
AND met.metric_column = MGMT_GLOBAL.G_AVAIL_METRIC_COLUMN
AND met.type_meta_ver = tgt.type_meta_ver
AND (met.category_prop_1 = tgt.category_prop_1 OR
met.category_prop_1 = ' ')
AND (met.category_prop_2 = tgt.category_prop_2 OR
met.category_prop_2 = ' ')
AND (met.category_prop_3 = tgt.category_prop_3 OR
met.category_prop_3 = ' ')
AND (met.category_prop_4 = tgt.category_prop_4 OR
met.category_prop_4 = ' ')
AND (met.category_prop_5 = tgt.category_prop_5 OR
met.category_prop_5 = ' ');
update_availability := TRUE;
EXCEPTION
WHEN NO_DATA_FOUND THEN
update_availability := FALSE;
END;
END IF;
IF (update_availability = TRUE) THEN
IF (:new.target_status = MGMT_BLACKOUT_ENGINE.IN_BLACKOUT) THEN
l_start_msg := REPLACE(MGMT_BLACKOUT_ENGINE.BLK_START_MSG, '{0}', l_created_by);
l_start_msg := REPLACE(l_start_msg, '{1}', l_reason);
l_start_msg := REPLACE(l_start_msg, '{2}', l_blackout_name);
l_start_msg_params := l_created_by||'&'||l_reason||'&'||l_blackout_name ;
-- Setting blackout for this target...
BEGIN
INSERT INTO mgmt_violations
(target_guid, policy_guid,
collection_timestamp,
violation_level, message, message_nlsid, message_params)
VALUES
(:new.target_guid, response_metric_guid,
:new.collection_timestamp,
MGMT_GLOBAL.G_SEVERITY_BLACKOUT_START,
l_start_msg, MGMT_BLACKOUT_ENGINE.BLK_START_MSG_NLSID, l_start_msg_params )
RETURNING collection_timestamp
INTO l_actual_start_time;
EXCEPTION
WHEN MGMT_GLOBAL.duplicate_record THEN
:new.collection_timestamp :=
MGMT_BLACKOUT_ENGINE.reinsert_blackout_severity(
:new.blackout_guid,
:new.target_guid,
response_metric_guid,
MGMT_GLOBAL.G_SEVERITY_BLACKOUT_START,
MGMT_BLACKOUT_ENGINE.BO_START_MSG,
MGMT_BLACKOUT_ENGINE.BO_START_MSG_NLSID,
NULL
);
WHEN MGMT_GLOBAL.internal_severity THEN
:new.collection_timestamp :=
MGMT_BLACKOUT_ENGINE.reinsert_blackout_severity(
:new.blackout_guid,
:new.target_guid,
response_metric_guid,
MGMT_GLOBAL.G_SEVERITY_BLACKOUT_START,
MGMT_BLACKOUT_ENGINE.BO_START_MSG,
MGMT_BLACKOUT_ENGINE.BO_START_MSG_NLSID,
NULL
);
END;
IF l_actual_start_time > :new.collection_timestamp THEN
BEGIN
:new.collection_timestamp := l_actual_start_time;
SELECT end_time INTO l_actual_end_time
FROM MGMT_BLACKOUT_WINDOWS
WHERE blackout_guid=:new.blackout_guid
AND target_guid=:new.target_guid
AND occurrence_number=l_occurrence_number
AND status NOT IN (MGMT_BLACKOUT.BLK_STATE_STOPPED,
MGMT_BLACKOUT.BLK_STATE_ENDED);
-- Adjust the end time if required
IF l_actual_end_time IS NOT NULL AND
l_actual_end_time <= l_actual_start_time THEN
l_actual_end_time := l_actual_start_time+(1/(60*60*24));
END IF;
UPDATE MGMT_BLACKOUT_WINDOWS
SET start_time=l_actual_start_time,
end_time=l_actual_end_time
WHERE blackout_guid=:new.blackout_guid
AND target_guid=:new.target_guid
AND occurrence_number=l_occurrence_number
AND status NOT IN (MGMT_BLACKOUT.BLK_STATE_STOPPED,
MGMT_BLACKOUT.BLK_STATE_ENDED);
EXCEPTION
WHEN NO_DATA_FOUND THEN
NULL;
END;
END IF;
-- Blackout all the tests of Services (i.e. webapps)
BEGIN
MGMT_GENSVC_AVAIL.PROCESS_BLACKOUT_START(:new.target_guid, :new.collection_timestamp);
EXCEPTION
WHEN OTHERS THEN
MGMT_BLACKOUT_ENGINE.log_error(MGMT_GLOBAL.INVALID_PARAMS_ERR,
'Error calling gensvc.process_blackout_start() for blackout ' ||
:new.blackout_guid || ' on target ' || :new.target_guid);
END;
ELSIF (:new.target_status = MGMT_BLACKOUT_ENGINE.NOT_IN_BLACKOUT) THEN
-- Clearing blackout..
BEGIN
l_stop_msg := REPLACE(MGMT_BLACKOUT_ENGINE.BLK_STOP_MSG, '{0}', l_blackout_name);
l_stop_msg_params := l_blackout_name ;
INSERT INTO mgmt_violations
(target_guid, policy_guid,
collection_timestamp,
violation_level, message, message_nlsid, message_params)
VALUES
(:new.target_guid, response_metric_guid,
:new.collection_timestamp,
MGMT_GLOBAL.G_SEVERITY_BLACKOUT_END,
l_stop_msg, MGMT_BLACKOUT_ENGINE.BLK_STOP_MSG_NLSID, l_stop_msg_params );
EXCEPTION
WHEN MGMT_GLOBAL.duplicate_record THEN
:new.collection_timestamp :=
MGMT_BLACKOUT_ENGINE.reinsert_blackout_severity(
:new.blackout_guid,
:new.target_guid,
response_metric_guid,
MGMT_GLOBAL.G_SEVERITY_BLACKOUT_END,
MGMT_BLACKOUT_ENGINE.BO_END_MSG,
MGMT_BLACKOUT_ENGINE.BO_END_MSG_NLSID,
NULL
);
WHEN MGMT_GLOBAL.internal_severity THEN
:new.collection_timestamp :=
MGMT_BLACKOUT_ENGINE.reinsert_blackout_severity(
:new.blackout_guid,
:new.target_guid,
response_metric_guid,
MGMT_GLOBAL.G_SEVERITY_BLACKOUT_END,
MGMT_BLACKOUT_ENGINE.BO_END_MSG,
MGMT_BLACKOUT_ENGINE.BO_END_MSG_NLSID,
NULL
);
END;
-- Select a new master agent if this is a multi-agent target
SELECT monitoring_mode
INTO l_monitoring_mode
FROM mgmt_targets
WHERE target_guid = :new.target_guid;
IF (l_monitoring_mode = mgmt_global.G_MON_MODE_OMS_MEDIATED) THEN
em_master_agent.select_master_agent(:new.target_guid,
:new.collection_timestamp);
END IF;
-- For services (i.e. webapps), discard the state of its beacons
BEGIN
MGMT_GENSVC_AVAIL.PROCESS_BLACKOUT_END(:new.target_guid, :new.collection_timestamp);
EXCEPTION
WHEN OTHERS THEN
MGMT_BLACKOUT_ENGINE.log_error(MGMT_GLOBAL.INVALID_PARAMS_ERR,
'Error calling gensvc.process_blackout_end() for blackout ' ||
:new.blackout_guid || ' on target ' || :new.target_guid);
END;
ELSE
NULL;
END IF;
ELSE
NULL;
END IF;
END;
/
show errors;
CREATE OR REPLACE TRIGGER blackout_status AFTER UPDATE
ON MGMT_BLACKOUT_FLAT_TARGETS FOR EACH ROW
DECLARE
l_created_thru MGMT_BLACKOUTS.created_thru%TYPE;
l_occurrence_number MGMT_BLACKOUTS.occurrence_number%TYPE;
l_status MGMT_BLACKOUTS.blackout_status%TYPE;
BEGIN
SELECT created_thru, occurrence_number
INTO l_created_thru, l_occurrence_number
FROM MGMT_BLACKOUTS
WHERE blackout_guid=:new.blackout_guid;
IF l_created_thru IS NULL THEN
-- Compute the new status
IF :new.job_status=MGMT_BLACKOUT_ENGINE.BLK_JSTATE_START_PROCESSING THEN
l_status := MGMT_BLACKOUT.BLK_STATE_START_PENDING;
ELSIF :new.job_status=MGMT_BLACKOUT_ENGINE.BLK_JSTATE_STOPPED THEN
l_status := MGMT_BLACKOUT.BLK_STATE_ENDED;
ELSE
l_status := MGMT_BLACKOUT.BLK_STATE_STARTED;
END IF;
-- Update entries in the blackout window table. We only
-- need to update "active" entries, ones that are
-- not in state stopped or ended.
UPDATE MGMT_BLACKOUT_WINDOWS
SET status=l_status
WHERE blackout_guid=:new.blackout_guid
AND occurrence_number=l_occurrence_number
AND target_guid=:new.target_guid
AND status NOT IN (MGMT_BLACKOUT.BLK_STATE_STOPPED,
MGMT_BLACKOUT.BLK_STATE_ENDED);
END IF;
END;
/
show errors;
CREATE OR REPLACE TRIGGER insert_flat_targets AFTER INSERT
ON MGMT_BLACKOUT_TARGET_DETAILS FOR EACH ROW
DECLARE
l_created_thru MGMT_BLACKOUTS.created_thru%TYPE;
l_target_type MGMT_TARGETS.target_type%TYPE;
BEGIN
-- For CLI blackouts, add entries to the flat targets table
SELECT created_thru INTO l_created_thru
FROM MGMT_BLACKOUTS
WHERE blackout_guid=:new.blackout_guid;
IF l_created_thru IS NOT NULL THEN
-- This is an agent-side blackout
INSERT INTO MGMT_BLACKOUT_FLAT_TARGETS(blackout_guid, target_guid,
host_blackout, job_status, blackout_status, last_updated_time)
VALUES
(:new.blackout_guid, :new.target_guid, 0,
MGMT_BLACKOUT_ENGINE.BLK_JSTATE_START_PROCESSING,
MGMT_BLACKOUT_ENGINE.NOT_IN_BLACKOUT, SYSDATE);
--Find the target type to make sure that its of type host
SELECT target_type INTO l_target_type
FROM MGMT_TARGETS
WHERE target_guid = :new.target_guid;
--If include_members is true then insert all the dependent targets to the MGMT_BLACKOUT_FLAT_TARGETS
IF (:new.include_members = 1 AND l_target_type = MGMT_GLOBAL.G_HOST_TARGET_TYPE) THEN
--Find all the targets guid for this url and insert in MGMT_BLACKOUT_FLAT_TARGETS
FOR crec IN
(
SELECT a.target_guid
FROM MGMT_TARGETS a, MGMT_TARGETS h
WHERE h.target_guid = :new.target_guid
AND h.emd_url=a.emd_url
AND a.target_type != MGMT_GLOBAL.G_HOST_TARGET_TYPE
)
LOOP
INSERT INTO MGMT_BLACKOUT_FLAT_TARGETS
(
blackout_guid,
target_guid,
host_blackout,
job_status,
blackout_status,
last_updated_time
)
VALUES
(
:new.blackout_guid,
crec.target_guid,
0,
MGMT_BLACKOUT_ENGINE.BLK_JSTATE_START_PROCESSING,
MGMT_BLACKOUT_ENGINE.NOT_IN_BLACKOUT,
SYSDATE
);
END LOOP;
END IF;
END IF;
END;
/
show errors;
CREATE OR REPLACE TRIGGER update_source BEFORE INSERT
ON MGMT_BLACKOUT_SCHEDULE FOR EACH ROW
DECLARE
l_created_thru MGMT_BLACKOUTS.created_thru%TYPE;
BEGIN
BEGIN
SELECT created_thru INTO l_created_thru
FROM MGMT_BLACKOUTS
WHERE blackout_guid=:new.blackout_guid;
EXCEPTION
WHEN NO_DATA_FOUND THEN
RETURN;
END;
IF l_created_thru IS NOT NULL THEN
IF :new.duration > 0 THEN
:new.duration_source :=
MGMT_BLACKOUT_ENGINE.DURATION_SOURCE_DURATION;
ELSIF :new.duration < 0 THEN
:new.duration_source :=
MGMT_BLACKOUT_ENGINE.DURATION_SOURCE_INDEFINITE;
ELSE
:new.duration_source :=
MGMT_BLACKOUT_ENGINE.DURATION_SOURCE_ENDTIME;
END IF;
END IF;
END;
/
show errors;
CREATE OR REPLACE TRIGGER blackout_window_insert BEFORE INSERT OR UPDATE
ON MGMT_BLACKOUT_WINDOWS FOR EACH ROW
DECLARE
l_timezone_region MGMT_TARGETS.timezone_region%TYPE;
BEGIN
SELECT timezone_region INTO l_timezone_region FROM MGMT_TARGETS WHERE
target_guid=:new.target_guid;
:new.utc_start_time :=
MGMT_GLOBAL.to_utc(:new.start_time, l_timezone_region);
IF :new.end_time IS NOT NULL THEN
:new.utc_end_time :=
MGMT_GLOBAL.to_utc(:new.end_time, l_timezone_region);
END IF;
EXCEPTION
WHEN NO_DATA_FOUND THEN
NULL;
END;
/
show errors;
CREATE OR REPLACE TRIGGER handle_related_targets
BEFORE INSERT ON MGMT_BLACKOUT_STATE FOR EACH ROW
DECLARE
l_created_thru MGMT_BLACKOUTS.created_thru%TYPE;
l_include_members MGMT_BLACKOUT_TARGET_DETAILS.include_members%TYPE;
l_target_type MGMT_TARGETS.target_type%TYPE;
l_targets_to_process MGMT_USER_GUID_ARRAY;
BEGIN
-- For CLI blackouts, add entries to the blackout state table
SELECT created_thru INTO l_created_thru
FROM MGMT_BLACKOUTS
WHERE blackout_guid=:new.blackout_guid;
IF l_created_thru IS NOT NULL THEN
BEGIN
SELECT include_members INTO l_include_members
FROM MGMT_BLACKOUT_TARGET_DETAILS
WHERE blackout_guid=:new.blackout_guid
AND target_guid=:new.target_guid;
EXCEPTION
-- If we get a NO_DATA_FOUND, we are processing a
-- node-level blackout, and a target that is on
-- the node but is not the host.
WHEN NO_DATA_FOUND THEN
l_include_members := 0;
END;
--Find the target type to make sure that its of type host
SELECT target_type INTO l_target_type
FROM MGMT_TARGETS
WHERE target_guid = :new.target_guid;
--If include_members is true then insert all the dependent targets to the MGMT_BLACKOUT_STATE
IF (l_include_members = 1 AND
l_target_type = MGMT_GLOBAL.G_HOST_TARGET_TYPE) THEN
--Find all the targets guid for this host url and insert in MGMT_BLACKOUT_FLAT_TARGETS
SELECT t.target_guid
BULK COLLECT INTO l_targets_to_process
FROM MGMT_TARGETS t, MGMT_BLACKOUT_FLAT_TARGETS ft
WHERE ft.blackout_guid=:new.blackout_guid
AND t.target_guid=ft.target_guid
AND t.target_guid != :new.target_guid
ORDER BY DECODE(t.target_type, MGMT_GLOBAL.G_AGENT_TARGET_TYPE, 2, 1), 1;
IF l_targets_to_process IS NOT NULL AND
l_targets_to_process.COUNT > 0 THEN
FOR i IN 1..l_targets_to_process.COUNT LOOP
INSERT INTO MGMT_BLACKOUT_STATE (
blackout_guid,
target_guid,
collection_timestamp,
load_timestamp,
blackout_code,
target_status
)
VALUES (
:new.blackout_guid,
l_targets_to_process(i),
:new.collection_timestamp,
:new.load_timestamp,
:new.blackout_code,
:new.target_status
);
END LOOP;
END IF;
END IF;
END IF;
END;
/
show errors;
-- Compute status for all agent-side blackouts on blackout update
CREATE OR REPLACE TRIGGER compute_agent_side_status
BEFORE UPDATE ON MGMT_BLACKOUTS FOR EACH ROW
BEGIN
IF :new.created_thru IS NOT NULL THEN
:new.blackout_status :=
MGMT_BLACKOUT_ENGINE.compute_blackout_status(:new.blackout_guid,
MGMT_BLACKOUT_ENGINE.BLK_MODE_NONE,
:new.last_start_time,
:new.last_end_time);
END IF;
END;
/
show errors;