Rem Rem $Header: sdk_template_pkgbody.sql 21-jun-2007.11:11:29 dgiaimo Exp $ Rem Rem sdk_template_pkgbody.sql Rem Rem Copyright (c) 2004, 2007, Oracle. All rights reserved. Rem Rem NAME Rem sdk_template_pkgbody.sql - Rem Rem DESCRIPTION Rem Rem Rem NOTES Rem Rem Rem MODIFIED (MM/DD/YY) Rem dgiaimo 06/21/07 - Overloading get_template_settings Rem pratagar 05/10/07 - Null Check in does_target_has_collection Rem denath 03/17/07 - Backport denath_bug-5197525 from Rem st_emgc_10.2.0.1.0 Rem rkpandey 04/30/07 - Add copy common_all_with_retain Rem shnavane 03/26/07 - Backport shnavane_bug-5646200 from main Rem bram 09/06/06 - Adding "distinct" in get_targets_info Rem vmotamar 02/09/06 - EMCLI template operations Rem vmotamar 02/09/06 - EMCLI template operations Rem pratagar 12/08/05 - Delete UDM and 2 Col SQL UDM Support. Rem pratagar 07/25/06 - Backport pratagar_bug-4653111 from main Rem rpinnama 07/26/06 - Backport rpinnama_bug-5055727 from main Rem rpinnama 02/24/06 - Fix 5055727 : Use target collection name when Rem available (necessary for old agents) Rem rpinnama 09/28/05 - Rem rpinnama 09/23/05 - Fix 4595139 : Obtain settings lock before Rem updating the settings Rem jsadras 08/08/05 - Bug:4525497, Applying dbCredsUDM to 10.1 Agent Rem rpinnama 07/27/05 - Fix 4495847 : Decrement CA counter on removing Rem template policy assoc Rem snakai 07/21/05 - delete template-delete svc data before access Rem list Rem rpinnama 07/18/05 - Fix 4491757 : Use proper collection name while Rem copying policy_assoc_cfg/params Rem rpinnama 07/06/05 - Copy UDM on both copies all or common, Fix copy all issues Rem rzazueta 07/05/05 - Fix 4435559 Rem rzazueta 06/16/05 - Add new delete_template_copy Rem rpinnama 06/23/05 - Add get_template_settings API Rem rpinnama 06/22/05 - Fix coll subscript Rem rpinnama 05/27/05 - Use the same copy rules for policies as we do Rem for thresholds Rem rpinnama 05/23/05 - Fix 4382632: Use proper subscript in create_template_copy Rem rpinnama 05/09/05 - Re-order the remove* API to avoid deadlocks Rem njuillar 04/18/05 - Enter super user mode before granting privileges Rem rpinnama 04/06/05 - Fix 4289897 : Remove composite keys associated with template Rem when template is deleted Rem rpinnama 04/08/05 - Fix 4239274: Fix apply all case Rem rpinnama 03/02/05 - Move apply_template to SDK Rem snakai 02/18/05 - call gensvc delete_template Rem rpinnama 02/21/05 - Fix issues with copy-common Rem rpinnama 02/18/05 - Add logging Rem rpinnama 01/31/05 - Fix 4086886 : Enable normal users to create Rem templates Rem skini 12/16/04 - Delete CAs when template deleted Rem rpinnama 12/02/04 - Use object type constants Rem rpinnama 11/22/04 - Support transposed metrics Rem rpinnama 10/21/04 - Remove collections for mntrsetcopy Rem rzazueta 10/08/04 - Check for null collection credentials Rem rpinnama 10/10/04 - Change template to mntr Rem rpinnama 10/06/04 - Add UDM support. Rem rpinnama 09/30/04 - Add template implementation Rem kmanicka 09/20/04 - add user_model callbacks Rem rpinnama 08/30/04 - Throw template_does_not_exist error Rem rpinnama 07/30/04 - Implement create_template API Rem rpinnama 07/30/04 - Provide get_template_guid API Rem rpinnama 07/26/04 - rpinnama_add_policy_api Rem rpinnama 07/14/04 - Created Rem CREATE OR REPLACE PACKAGE BODY mgmt_template AS -- Internal procedure PROCEDURE create_template_copy ( p_target_guid IN RAW, p_template_guid IN RAW, p_template_object_type IN NUMBER, p_template_copy_guid IN RAW, p_copy_type IN NUMBER, p_ca_creds IN MGMT_MNTR_CA_ARRAY DEFAULT NULL); -- Generate template guid FUNCTION generate_template_guid(p_target_type IN VARCHAR2, p_template_name IN VARCHAR2) RETURN RAW IS l_template_guid MGMT_TEMPLATES.template_guid%TYPE; BEGIN l_template_guid := DBMS_OBFUSCATION_TOOLKIT.md5( input => UTL_RAW.cast_to_raw('ora$template' || ';' || p_target_type || ';'|| p_template_name)); RETURN l_template_guid; END generate_template_guid; -- Lookup template guid FUNCTION get_template_guid(p_target_type IN VARCHAR2, p_template_name IN VARCHAR2) RETURN RAW IS l_template_guid MGMT_TEMPLATES.template_guid%TYPE; BEGIN BEGIN SELECT template_guid INTO l_template_guid FROM mgmt_templates WHERE target_type = p_target_type AND template_name = p_template_name; EXCEPTION WHEN NO_DATA_FOUND THEN raise_application_error(MGMT_GLOBAL.TEMPLATE_DOES_NOT_EXIST_ERR, 'Template not found. target_type = ' || p_target_type || ' template_name = ' || p_template_name); END; RETURN l_template_guid; END get_template_guid; -- Get template monitoring settings PROCEDURE get_template_settings( p_target_type IN VARCHAR2, p_template_name IN VARCHAR2, p_metric_list OUT MGMT_MNTR_METRIC_ARRAY, p_policy_list OUT MGMT_MNTR_POLICY_ARRAY, p_collection_list OUT MGMT_MNTR_COLLECTION_ARRAY) IS l_template_guid mgmt_templates.template_guid%TYPE; BEGIN -- Check for NULLs EM_CHECK.check_not_null(p_target_type, 'p_target_type'); EM_CHECK.check_not_null(p_template_name, 'p_template_name'); l_template_guid := MGMT_TEMPLATE.get_template_guid( p_target_type => p_target_type, p_template_name => p_template_name); EM_TEMPLATE.get_object_settings( p_object_guid => l_template_guid, p_object_type => MGMT_GLOBAL.G_OBJECT_TYPE_TEMPLATE, p_metric_list => p_metric_list, p_policy_list => p_policy_list, p_coll_list => p_collection_list); END get_template_settings; PROCEDURE get_template_settings( p_target_type IN VARCHAR2, p_template_name IN VARCHAR2, p_description OUT VARCHAR2, p_is_public OUT NUMBER, p_oms_version OUT VARCHAR2, p_owner OUT VARCHAR2, p_metric_list OUT MGMT_MNTR_METRIC_ARRAY, p_policy_list OUT MGMT_MNTR_POLICY_ARRAY, p_collection_list OUT MGMT_MNTR_COLLECTION_ARRAY) IS l_template_guid mgmt_templates.template_guid%TYPE; BEGIN -- Check for NULLs EM_CHECK.check_not_null(p_target_type, 'p_target_type'); EM_CHECK.check_not_null(p_template_name, 'p_template_name'); l_template_guid := MGMT_TEMPLATE.get_template_guid( p_target_type => p_target_type, p_template_name => p_template_name); SELECT description, is_public, owner INTO p_description, p_is_public, p_owner FROM mgmt_templates WHERE template_guid = l_template_guid; SELECT version INTO p_oms_version FROM mgmt_versions WHERE component_name = 'CORE'; EM_TEMPLATE.get_object_settings( p_object_guid => l_template_guid, p_object_type => MGMT_GLOBAL.G_OBJECT_TYPE_TEMPLATE, p_metric_list => p_metric_list, p_policy_list => p_policy_list, p_coll_list => p_collection_list); END get_template_settings; -- Create template with the given metrics, policies and collections PROCEDURE create_template( p_target_type IN VARCHAR2, p_template_name IN VARCHAR2, p_description IN VARCHAR2 DEFAULT NULL, p_is_public IN NUMBER DEFAULT 0, p_access_list IN MGMT_TEMPLATE_ACCESS_ARRAY DEFAULT NULL, p_metric_list IN MGMT_MNTR_METRIC_ARRAY DEFAULT NULL, p_policy_list IN MGMT_MNTR_POLICY_ARRAY DEFAULT NULL, p_collection_list IN MGMT_MNTR_COLLECTION_ARRAY DEFAULT NULL) IS l_template_guid mgmt_templates.template_guid%TYPE; l_current_user mgmt_created_users.user_name%TYPE; l_metric_guid mgmt_metrics.metric_guid%TYPE; l_policy_guid mgmt_policies.policy_guid%TYPE; l_template_access MGMT_TEMPLATE_ACCESS; l_template_metric MGMT_MNTR_METRIC; l_template_policy MGMT_MNTR_POLICY; l_template_coll MGMT_MNTR_COLLECTION; l_template_found NUMBER := 0; l_coll_metric MGMT_COLL_METRIC; l_coll_prop MGMT_COLL_PROP; l_proc_name VARCHAR2(32) := 'create_template'; BEGIN l_current_user := MGMT_USER.GET_CURRENT_EM_USER; IF EMDW_LOG.P_IS_DEBUG_SET THEN EMDW_LOG.DEBUG(l_proc_name || 'Enter', G_MODULE_NAME) ; END IF ; -- Check for NULLs EM_CHECK.check_not_null(p_target_type, 'p_target_type'); EM_CHECK.check_not_null(p_template_name, 'p_template_name'); -- NOTE: No need to do a privilege check. Any user should be able to -- create a template -- Check if the template name already exist BEGIN SELECT COUNT(1) INTO l_template_found FROM mgmt_templates WHERE template_name = p_template_name; EXCEPTION WHEN NO_DATA_FOUND THEN l_template_found := 0; END; IF (l_template_found > 0) THEN raise_application_error(MGMT_GLOBAL.TEMPLATE_ALREADY_EXISTS_ERR, 'Template with name ' || p_template_name || ' already exists.'); END IF; IF EMDW_LOG.P_IS_DEBUG_SET THEN EMDW_LOG.DEBUG(l_proc_name || ' Target type = [' || p_target_type || '] Template Name = [' || p_template_name || '] Description = [' || p_description || '] Public = [' || p_is_public || ']', G_MODULE_NAME); EMDW_LOG.DEBUG(l_proc_name || ' BEGIN DUMP ------------', G_MODULE_NAME); EM_POLICY.dump_access_list(p_access_list, l_proc_name, G_MODULE_NAME); EM_POLICY.dump_metric_list(p_metric_list, l_proc_name, G_MODULE_NAME); EM_POLICY.dump_policy_list(p_policy_list, l_proc_name, G_MODULE_NAME); EM_POLICY.dump_collection_list(p_collection_list, l_proc_name, G_MODULE_NAME); EMDW_LOG.DEBUG(l_proc_name || ' END DUMP ------------', G_MODULE_NAME); END IF ; l_template_guid := generate_template_guid(p_target_type, p_template_name); -- Insert template row INSERT INTO mgmt_templates (template_guid, target_type, template_name, description, is_public, owner, created_date, last_updated_date, last_updated_by ) VALUES (l_template_guid, p_target_type, p_template_name, p_description, p_is_public, l_current_user, SYSDATE, SYSDATE, l_current_user); BEGIN -- Enter super-user mode. This is necessary because this operation -- involves making calls to the security system that only super-users -- are allowed to make SETEMUSERCONTEXT(MGMT_USER.get_repository_owner, MGMT_USER.OP_SET_IDENTIFIER); -- Grant full access to owner MGMT_USER.grant_priv( grantee_in => l_current_user, priv_name_in => MGMT_USER.FULL_TEMPLATE, guid_in => l_template_guid); -- Revert back to being the same user as we entered SETEMUSERCONTEXT(l_current_user, MGMT_USER.OP_SET_IDENTIFIER); EXCEPTION WHEN OTHERS THEN IF l_current_user IS NOT NULL THEN SETEMUSERCONTEXT(l_current_user, MGMT_USER.OP_SET_IDENTIFIER); END IF; RAISE; END; IF ( (p_access_list IS NOT NULL) AND (p_access_list.COUNT > 0) )THEN FOR acc_ctr IN p_access_list.FIRST..p_access_list.LAST LOOP l_template_access := p_access_list(acc_ctr); MGMT_USER.grant_priv( grantee_in => l_template_access.user_name, priv_name_in => l_template_access.privilege, guid_in => l_template_guid); END LOOP; END IF; -- Process p_collection_list EM_COLL_UTIL.add_object_collections( p_target_type => p_target_type, p_object_guid => l_template_guid, p_object_type => MGMT_GLOBAL.G_OBJECT_TYPE_TEMPLATE, p_coll_list => p_collection_list); -- Process metric_list IF ( (p_metric_list IS NOT NULL) AND (p_metric_list.COUNT > 0) )THEN FOR met_ctr IN p_metric_list.FIRST..p_metric_list.LAST LOOP l_template_metric := p_metric_list(met_ctr); l_metric_guid := MGMT_METRIC.get_metric_guid(p_target_type, l_template_metric.metric_name, l_template_metric.metric_column); IF EMDW_LOG.P_IS_DEBUG_SET THEN EMDW_LOG.DEBUG(l_proc_name || ' Adding template assoc for metric ' || ' type = ' || p_target_type || ' metric_name ' || l_template_metric.metric_name || ' metric_colmn ' || l_template_metric.metric_column, G_MODULE_NAME) ; END IF ; EM_POLICY.add_object_policy_assoc( p_object_guid => l_template_guid, p_policy_guid => l_metric_guid, p_coll_name => l_template_metric.coll_name, p_object_type => MGMT_GLOBAL.G_OBJECT_TYPE_TEMPLATE, p_policy_type => MGMT_GLOBAL.G_TYPE_THRESHOLD_METRIC, p_is_enabled => l_template_metric.is_enabled, p_policy_val_list => l_template_metric.key_val_list, p_add_or_delete => l_template_metric.add_or_delete); END LOOP; END IF; -- Process metric_list IF ( (p_policy_list IS NOT NULL) AND (p_policy_list.COUNT > 0) )THEN FOR pol_ctr IN p_policy_list.FIRST..p_policy_list.LAST LOOP l_template_policy := p_policy_list(pol_ctr); l_policy_guid := MGMT_POLICY.get_policy_guid(p_target_type, l_template_policy.policy_name); IF EMDW_LOG.P_IS_DEBUG_SET THEN EMDW_LOG.DEBUG(l_proc_name || ' Adding template assoc for policy ' || ' type = ' || p_target_type || ' policy_name ' || l_template_policy.policy_name, G_MODULE_NAME) ; END IF ; EM_POLICY.add_object_policy_assoc( p_object_guid => l_template_guid, p_policy_guid => l_policy_guid, p_coll_name => l_template_policy.coll_name, p_object_type => MGMT_GLOBAL.G_OBJECT_TYPE_TEMPLATE, p_policy_type => MGMT_GLOBAL.G_TYPE_POLICY, p_is_enabled => l_template_policy.is_enabled, p_policy_val_list => l_template_policy.key_val_list); END LOOP; END IF; IF EMDW_LOG.P_IS_DEBUG_SET THEN EMDW_LOG.DEBUG(l_proc_name || 'Normal exit', G_MODULE_NAME) ; END IF ; END create_template; -- -- PROCEDURE: modify_template -- -- PURPOSE: -- Modifies the template definition and the list of metrics -- policies, collections associated with it -- Cannot change owner -- PROCEDURE modify_template( p_target_type IN VARCHAR2, p_template_name IN VARCHAR2, p_description IN VARCHAR2 DEFAULT NULL, p_is_public IN NUMBER DEFAULT NULL, p_access_list IN MGMT_TEMPLATE_ACCESS_ARRAY DEFAULT NULL, p_metric_list IN MGMT_MNTR_METRIC_ARRAY DEFAULT NULL, p_policy_list IN MGMT_MNTR_POLICY_ARRAY DEFAULT NULL, p_collection_list IN MGMT_MNTR_COLLECTION_ARRAY DEFAULT NULL) IS l_template_guid mgmt_templates.template_guid%TYPE; l_current_user mgmt_created_users.user_name%TYPE; l_metric_guid mgmt_metrics.metric_guid%TYPE; l_policy_guid mgmt_policies.policy_guid%TYPE; l_curr_priv mgmt_priv_grants.priv_name%TYPE; l_req_priv mgmt_priv_grants.priv_name%TYPE; l_no_priv mgmt_priv_grants.priv_name%TYPE; l_template_access MGMT_TEMPLATE_ACCESS; l_template_metric MGMT_MNTR_METRIC; l_template_policy MGMT_MNTR_POLICY; l_template_coll MGMT_MNTR_COLLECTION; l_coll_metric MGMT_COLL_METRIC; l_coll_prop MGMT_COLL_PROP; l_proc_name VARCHAR2(32) := 'modify_template'; BEGIN l_current_user := MGMT_USER.GET_CURRENT_EM_USER; -- Check for NULLs EM_CHECK.check_not_null(p_target_type, 'p_target_type'); EM_CHECK.check_not_null(p_template_name, 'p_template_name'); l_template_guid := get_template_guid(p_target_type, p_template_name); -- Only users with FULL_TEMPLATE privilege can modify the template IF (MGMT_USER.has_priv(l_current_user, MGMT_USER.FULL_TEMPLATE, l_template_guid) = MGMT_USER.USER_DOES_NOT_HAVE_PRIV) THEN raise_application_error(MGMT_GLOBAL.INSUFFICIENT_PRIVILEGES_ERR, 'Only users with FULL TEMPLATE privilege can modify templates.'); END IF; IF EMDW_LOG.P_IS_DEBUG_SET THEN EMDW_LOG.DEBUG(l_proc_name || ' Target type = [' || p_target_type || '] Template Name = [' || p_template_name || '] Description = [' || p_description || '] Public = [' || p_is_public || ']', G_MODULE_NAME); EMDW_LOG.DEBUG(l_proc_name || ' BEGIN DUMP ------------', G_MODULE_NAME); EM_POLICY.dump_access_list(p_access_list, l_proc_name, G_MODULE_NAME); EM_POLICY.dump_metric_list(p_metric_list, l_proc_name, G_MODULE_NAME); EM_POLICY.dump_policy_list(p_policy_list, l_proc_name, G_MODULE_NAME); EM_POLICY.dump_collection_list(p_collection_list, l_proc_name, G_MODULE_NAME); EMDW_LOG.DEBUG(l_proc_name || ' END DUMP ------------', G_MODULE_NAME); END IF ; -- Update template definition UPDATE mgmt_templates SET description = NVL(p_description, description), is_public = NVL(p_is_public, is_public), last_updated_by = l_current_user, last_updated_date = SYSDATE WHERE template_guid = l_template_guid; l_no_priv := 'NO_TEMPLATE'; IF ( (p_access_list IS NOT NULL) AND (p_access_list.COUNT > 0) )THEN FOR acc_ctr IN p_access_list.FIRST..p_access_list.LAST LOOP l_template_access := p_access_list(acc_ctr); l_req_priv := NVL(l_template_access.privilege, l_no_priv); -- Get the current priv for the user. BEGIN SELECT priv_name INTO l_curr_priv FROM mgmt_priv_grants WHERE grantee = l_template_access.user_name AND guid = l_template_guid; EXCEPTION WHEN NO_DATA_FOUND THEN -- If there is no privilged, initialize to no priv l_curr_priv := l_no_priv; END; IF (l_curr_priv = l_req_priv) THEN -- The user already has the right privilege, do nothing. NULL; ELSIF (l_curr_priv = l_no_priv) THEN -- There was no previous privilege, so grant req priv MGMT_USER.grant_priv( grantee_in => l_template_access.user_name, priv_name_in => l_req_priv, guid_in => l_template_guid); ELSIF (l_req_priv = l_no_priv) THEN -- The current privilege has to be revoked MGMT_USER.revoke_priv( grantee_in => l_template_access.user_name, priv_name_in => l_curr_priv, guid_in => l_template_guid); ELSE -- curr priv is not equal to req privilege and -- Neither req nor curr privilege is no privilege -- Revoke the current privilege and grant the req privilege MGMT_USER.revoke_priv( grantee_in => l_template_access.user_name, priv_name_in => l_curr_priv, guid_in => l_template_guid); MGMT_USER.grant_priv( grantee_in => l_template_access.user_name, priv_name_in => l_req_priv, guid_in => l_template_guid); END IF; END LOOP; END IF; -- Process p_collection_list IF (p_collection_list IS NOT NULL) THEN EM_COLL_UTIL.remove_object_collections(l_template_guid, MGMT_GLOBAL.G_OBJECT_TYPE_TEMPLATE); IF (p_collection_list.COUNT > 0) THEN EM_COLL_UTIL.add_object_collections( p_target_type => p_target_type, p_object_guid => l_template_guid, p_object_type => MGMT_GLOBAL.G_OBJECT_TYPE_TEMPLATE, p_coll_list => p_collection_list); END IF; -- (p_collection_list.COUNT > 0) END IF; -- Lock all CAs associated with this target MGMT_JOB_ENGINE.lock_cas_for_object(l_template_guid, MGMT_CA.CA_SCOPE_TEMPLATE); -- Reset all CA counters.. MGMT_JOB_ENGINE.reset_ca_refctr(l_template_guid, MGMT_CA.CA_SCOPE_TEMPLATE); -- Add metric_list IF (p_metric_list IS NOT NULL) THEN -- Remove the existing metric list and add the new list FOR metric_rec IN (SELECT pa.policy_guid FROM mgmt_policy_assoc pa WHERE pa.object_guid = l_template_guid AND pa.policy_type = MGMT_GLOBAL.G_TYPE_THRESHOLD_METRIC AND pa.object_type = MGMT_GLOBAL.G_OBJECT_TYPE_TEMPLATE) LOOP -- Remove template associations, dont decrement CA counters EM_POLICY.remove_object_policy_assoc( p_object_guid => l_template_guid, p_policy_guid => metric_rec.policy_guid, p_coll_name => NULL, p_remove_ca_assoc => MGMT_GLOBAL.G_FALSE); END LOOP; IF (p_metric_list.COUNT > 0)THEN FOR met_ctr IN p_metric_list.FIRST..p_metric_list.LAST LOOP l_template_metric := p_metric_list(met_ctr); l_metric_guid := MGMT_METRIC.get_metric_guid(p_target_type, l_template_metric.metric_name, l_template_metric.metric_column); EM_POLICY.add_object_policy_assoc( p_object_guid => l_template_guid, p_policy_guid => l_metric_guid, p_coll_name => l_template_metric.coll_name, p_object_type => MGMT_GLOBAL.G_OBJECT_TYPE_TEMPLATE, p_policy_type => MGMT_GLOBAL.G_TYPE_THRESHOLD_METRIC, p_is_enabled => l_template_metric.is_enabled, p_policy_val_list => l_template_metric.key_val_list, p_add_or_delete => l_template_metric.add_or_delete); END LOOP; END IF; -- (p_metric_list.COUNT > 0) END IF; -- Process policy_list IF (p_policy_list IS NOT NULL) THEN -- Remove the existing policy list and add the new list FOR policy_rec IN (SELECT pa.policy_guid FROM mgmt_policy_assoc pa WHERE pa.object_guid = l_template_guid AND pa.policy_type = MGMT_GLOBAL.G_TYPE_POLICY AND pa.object_type = MGMT_GLOBAL.G_OBJECT_TYPE_TEMPLATE) LOOP -- Remove template associations, dont decrement CA counters EM_POLICY.remove_object_policy_assoc( p_object_guid => l_template_guid, p_policy_guid => policy_rec.policy_guid, p_coll_name => NULL, p_remove_ca_assoc => MGMT_GLOBAL.G_FALSE); END LOOP; IF (p_policy_list.COUNT > 0) THEN FOR pol_ctr IN p_policy_list.FIRST..p_policy_list.LAST LOOP l_template_policy := p_policy_list(pol_ctr); l_policy_guid := MGMT_POLICY.get_policy_guid(p_target_type, l_template_policy.policy_name); EM_POLICY.add_object_policy_assoc( p_object_guid => l_template_guid, p_policy_guid => l_policy_guid, p_coll_name => l_template_policy.coll_name, p_object_type => MGMT_GLOBAL.G_OBJECT_TYPE_TEMPLATE, p_policy_type => MGMT_GLOBAL.G_TYPE_POLICY, p_is_enabled => l_template_policy.is_enabled, p_policy_val_list => l_template_policy.key_val_list); END LOOP; END IF; -- (p_policy_list.COUNT > 0) END IF; -- Delete all zero-reference corrective actions MGMT_JOB_ENGINE.delete_noref_cas( p_object_guid => l_template_guid, p_ca_scope => MGMT_CA.CA_SCOPE_TEMPLATE); IF EMDW_LOG.P_IS_DEBUG_SET THEN EMDW_LOG.DEBUG(l_proc_name || 'Normal exit', G_MODULE_NAME) ; END IF ; END modify_template; -- Deletes the template definition PROCEDURE delete_template( p_target_type IN VARCHAR2, p_template_name IN VARCHAR2) IS l_template_guid mgmt_templates.template_guid%TYPE; l_current_user mgmt_created_users.user_name%TYPE; l_proc_name VARCHAR2(32) := 'delete_template'; BEGIN l_current_user := MGMT_USER.GET_CURRENT_EM_USER; -- Check for NULLs EM_CHECK.check_not_null(p_target_type, 'p_target_type'); EM_CHECK.check_not_null(p_template_name, 'p_template_name'); IF EMDW_LOG.P_IS_DEBUG_SET THEN EMDW_LOG.DEBUG(l_proc_name || ' Target type = [' || p_target_type || '] Template Name = [' || p_template_name || ']', G_MODULE_NAME); END IF; l_template_guid := get_template_guid(p_target_type, p_template_name); -- Only users with FULL TEMPLATE privilege can delete templates IF (MGMT_USER.has_priv(l_current_user, MGMT_USER.FULL_TEMPLATE, l_template_guid) = MGMT_USER.USER_DOES_NOT_HAVE_PRIV) THEN raise_application_error(MGMT_GLOBAL.INSUFFICIENT_PRIVILEGES_ERR, 'Only users with FULL TEMPLATE privilege can delete templates.'); END IF; -- Delete test/beacon template metadata MGMT_GENSVC_MONTMPL.delete_template(l_template_guid); -- Delete template collections EM_COLL_UTIL.remove_all_object_collections(l_template_guid, MGMT_GLOBAL.G_OBJECT_TYPE_TEMPLATE); -- Remove template metrics and policies FOR policy_rec IN (SELECT policy_guid FROM mgmt_policy_assoc WHERE object_guid = l_template_guid) LOOP -- Remove template associations, and decrement ctr for any related CAs EM_POLICY.remove_object_policy_assoc( p_object_guid => l_template_guid, p_policy_guid => policy_rec.policy_guid, p_coll_name => NULL, p_remove_ca_assoc => MGMT_GLOBAL.G_TRUE); END LOOP; -- Delete composite keys associated with template DELETE FROM mgmt_metrics_composite_keys WHERE target_guid = l_template_guid; -- Delete all corrective actions associated with the template MGMT_JOB_ENGINE.delete_template_cas(l_template_guid); -- Remove access list MGMT_USER.template_deleted(l_template_guid); -- Delete the template row DELETE FROM mgmt_templates WHERE template_guid = l_template_guid; END delete_template; -- -- If the collections contain DBCredsUDM they do no work on 10.1 agent -- so translated to DBCredsMonitoring -- PROCEDURE translate_credentials (p_colls_in IN MGMT_COLLECTION_CRED_ARRAY, p_cred_from_set IN VARCHAR2, p_cred_to_set IN VARCHAR2, p_colls_out OUT MGMT_COLLECTION_CRED_ARRAY, p_found OUT BOOLEAN) IS BEGIN p_colls_out := p_colls_in ; p_found := FALSE ; IF p_colls_out IS NOT NULL AND p_colls_out.COUNT > 0 THEN FOR i IN p_colls_out.FIRST..p_colls_out.LAST LOOP IF p_colls_out(i).CREDENTIAL.CREDENTIAL_SET_NAME = p_cred_from_set THEN p_colls_out(I).CREDENTIAL.CREDENTIAL_SET_NAME := p_cred_to_set ; p_found := TRUE ; END IF ; END LOOP ; END IF ; END translate_credentials ; -- -- PROCEDURE apply_template -- -- PURPOSE: -- procedure to apply a template to a specified destination list. -- -- Convenience procedure to apply a template to a specified destination list. -- -- p_template_name The source template name -- p_target_type The target type -- p_destination_list The set of destination targets -- p_copy_common_only_flags An array that is as large as the number of -- destination targets. For each target, it specifies whether to copy the common -- thresholds only (1) or all the thresholds (0) from the source. -- p_ca_creds A list of credentials for corrective actions. -- p_coll_creds A list of collection credentials -- p_update_master_agents This is a flag that indicates how to deal with multi-agent -- targets in the destination list. If set to true (1), the master agent as well as all the -- standby agents monitoring the multi-agent target are updated. If set to false (0), -- only the standby agents are updated, but not the master. -- p_schedule An optional schedule -- PROCEDURE apply_template(p_template_name IN VARCHAR2, p_target_type IN VARCHAR2, p_destination_list IN MGMT_TARGET_ARRAY, p_copy_common_only_flags IN MGMT_INTEGER_ARRAY, p_ca_creds IN MGMT_MNTR_CA_ARRAY DEFAULT NULL, p_coll_creds IN MGMT_COLLECTION_CRED_ARRAY DEFAULT NULL, p_update_master_agents IN NUMBER DEFAULT 1, p_schedule IN MGMT_JOB_SCHEDULE_RECORD DEFAULT NULL) IS l_data_set_guid RAW(16); l_operation_guid RAW(16); l_data_guids MGMT_USER_GUID_ARRAY; l_targets MGMT_JOB_TARGET_LIST; l_proc_name VARCHAR2(32) := 'apply_template'; l_translated_creds MGMT_COLLECTION_CRED_ARRAY := MGMT_COLLECTION_CRED_ARRAY() ; l_found BOOLEAN := FALSE ; l_translated BOOLEAN := FALSE ; BEGIN -- TODO: Need to do privilege check -- Check for NULLs EM_CHECK.check_not_null(p_target_type, 'p_target_type'); EM_CHECK.check_not_null(p_template_name, 'p_template_name'); IF ( (p_destination_list IS NULL) OR (p_destination_list.COUNT <= 0) ) THEN raise_application_error(MGMT_GLOBAL.INVALID_PARAMS_ERR, 'Destination target list to apply_template is empty.'); ELSE l_targets := MGMT_JOB_TARGET_LIST(); l_data_guids := MGMT_USER_GUID_ARRAY(); FOR i in 1..p_destination_list.count LOOP l_targets.extend(1); l_targets(l_targets.LAST) := MGMT_JOB_TARGET_RECORD(p_destination_list(i).target_name, p_destination_list(i).target_type); END LOOP; -- Create template_copy and get its associated data_set_guid l_data_set_guid := MGMT_TARGET_UPDATE.submit_template_data(p_template_name, p_target_type, p_copy_common_only_flags(1), NULL, -- target_name p_ca_creds, p_coll_creds); l_data_guids := MGMT_USER_GUID_ARRAY(); l_data_guids.extend(1); l_data_guids(1) := l_data_set_guid; l_operation_guid := MGMT_TARGET_UPDATE.submit_update_operation(l_data_guids, l_targets, p_update_master_agents, p_schedule); END IF; END apply_template; -- Template copy API -- Generate template copy API FUNCTION generate_template_copy_guid ( p_target_type IN VARCHAR2, p_template_name IN VARCHAR2, p_target_name IN VARCHAR2 DEFAULT ' ', p_copy_req_guid IN RAW) RETURN RAW IS l_target_name MGMT_TARGETS.target_name%TYPE; l_template_copy_guid MGMT_TEMPLATE_COPIES.template_copy_guid%TYPE; BEGIN l_target_name := NVL(p_target_name, ' '); l_template_copy_guid := DBMS_OBFUSCATION_TOOLKIT.md5( input => UTL_RAW.cast_to_raw('ora$template_copy' || ';' || p_target_type || ';'|| p_template_name || ';'|| l_target_name || ';'|| p_copy_req_guid)); RETURN l_template_copy_guid; END generate_template_copy_guid; -- Get the template copy guid FUNCTION get_template_copy_guid ( p_target_type IN VARCHAR2, p_template_name IN VARCHAR2, p_target_name IN VARCHAR2 DEFAULT ' ', p_copy_req_guid IN RAW) RETURN RAW IS l_template_guid MGMT_TEMPLATES.template_guid%TYPE; l_target_guid MGMT_TARGETS.target_guid%TYPE; l_template_copy_guid MGMT_TEMPLATE_COPIES.template_copy_guid%TYPE; BEGIN l_template_guid := generate_template_guid(p_target_type, p_template_name); IF (NVL(p_target_name, ' ') = ' ') THEN l_target_guid := MGMT_GLOBAL.G_ALL_ZERO_GUID; ELSE l_target_guid := MGMT_TARGET.get_target_guid( target_type_in => p_target_type, target_name_in => p_target_name); END IF; BEGIN SELECT template_copy_guid INTO l_template_copy_guid FROM mgmt_template_copies WHERE template_guid = l_template_guid AND target_guid = l_target_guid AND copy_req_guid = p_copy_req_guid; EXCEPTION WHEN NO_DATA_FOUND THEN raise_application_error(MGMT_GLOBAL.TEMPLATE_COPY_NOT_FOUND_ERR, 'Template Copy not found. target_type = ' || p_target_type || ' template_name = ' || p_template_name || ' copy req guid = ' || p_copy_req_guid ); END; RETURN l_template_copy_guid; END get_template_copy_guid; -- Get template copy monitoring settings PROCEDURE get_template_copy_settings( p_target_type IN VARCHAR2, p_template_name IN VARCHAR2, p_target_name IN VARCHAR2 DEFAULT ' ', p_copy_req_guid IN RAW, p_metric_list OUT MGMT_MNTR_METRIC_ARRAY, p_policy_list OUT MGMT_MNTR_POLICY_ARRAY, p_collection_list OUT MGMT_MNTR_COLLECTION_ARRAY) IS l_template_copy_guid mgmt_template_copies.template_copy_guid%TYPE; BEGIN -- Check for NULLs EM_CHECK.check_not_null(p_target_type, 'p_target_type'); EM_CHECK.check_not_null(p_template_name, 'p_template_name'); l_template_copy_guid := MGMT_TEMPLATE.get_template_copy_guid( p_target_type => p_target_type, p_template_name => p_template_name, p_target_name => p_target_name, p_copy_req_guid => p_copy_req_guid); EM_TEMPLATE.get_object_settings( p_object_guid => l_template_copy_guid, p_object_type => MGMT_GLOBAL.G_OBJECT_TYPE_TEMPLATE_COPY, p_metric_list => p_metric_list, p_policy_list => p_policy_list, p_coll_list => p_collection_list); END get_template_copy_settings; FUNCTION get_coll_name(p_metric_info IN EM_METRIC.METRIC_INFO_REC, p_target_guid IN RAW) RETURN VARCHAR2 IS l_ret_coll_name VARCHAR2(64); BEGIN BEGIN SELECT ci.coll_name INTO l_ret_coll_name FROM mgmt_targets t, mgmt_coll_items ci, mgmt_coll_item_metrics cim WHERE t.target_type = ci.target_type AND t.type_meta_ver = ci.type_meta_ver AND (t.category_prop_1 = ci.category_prop_1 OR ci.category_prop_1 = ' ') AND (t.category_prop_2 = ci.category_prop_2 OR ci.category_prop_2 = ' ') AND (t.category_prop_3 = ci.category_prop_3 OR ci.category_prop_3 = ' ') AND (t.category_prop_4 = ci.category_prop_4 OR ci.category_prop_4 = ' ') AND (t.category_prop_4 = ci.category_prop_5 OR ci.category_prop_5 = ' ') AND ci.target_type = cim.target_type AND ci.type_meta_ver = cim.type_meta_ver AND ci.coll_name = cim.coll_name AND t.target_guid = p_target_guid AND cim.metric_guid = p_metric_info.metric_guid; EXCEPTION WHEN NO_DATA_FOUND THEN l_ret_coll_name := NULL; END; RETURN l_ret_coll_name; END get_coll_name; FUNCTION get_udm_type(p_metric_info IN EM_METRIC.METRIC_INFO_REC, p_object_type IN NUMBER, p_object_guid IN RAW, p_coll_name IN VARCHAR2) RETURN VARCHAR2 IS l_udm_type VARCHAR2(128); l_key_type VARCHAR2(32); l_value_type VARCHAR2(32); BEGIN l_udm_type := p_metric_info.metric_name || ';'; -- Get key type BEGIN SELECT property_value INTO l_key_type FROM mgmt_coll_item_properties WHERE object_guid = p_object_guid AND object_type = p_object_type AND metric_guid = p_metric_info.metric_guid AND coll_name = p_coll_name AND property_name = 'keytype'; EXCEPTION WHEN OTHERS THEN l_key_type := ' '; END; BEGIN SELECT property_value INTO l_value_type FROM mgmt_coll_item_properties WHERE object_guid = p_object_guid AND object_type = p_object_type AND metric_guid = p_metric_info.metric_guid AND coll_name = p_coll_name AND property_name = 'valuetype'; EXCEPTION WHEN OTHERS THEN l_value_type := ' '; END; l_udm_type := p_metric_info.metric_name || ';' || l_key_type || ';' || l_value_type; RETURN l_udm_type; END get_udm_type; FUNCTION does_target_has_collection(p_tgt_coll_name IN MGMT_SHORT_STRING_ARRAY, p_coll_name IN VARCHAR2) RETURN NUMBER IS l_has_collection NUMBER := 0; BEGIN IF (p_tgt_coll_name IS NOT NULL AND p_tgt_coll_name.COUNT > 0) THEN FOR counter IN p_tgt_coll_name.FIRST..p_tgt_coll_name.LAST LOOP IF (p_tgt_coll_name(counter) = p_coll_name) THEN l_has_collection := 1; END IF; END LOOP; END IF; RETURN l_has_collection; END does_target_has_collection; FUNCTION can_copy(p_metric_info IN EM_METRIC.METRIC_INFO_REC, p_src_object_guid IN RAW, p_src_object_type IN NUMBER, p_dest_object_guid IN RAW, p_dest_object_type IN NUMBER, p_coll_name IN VARCHAR2) RETURN NUMBER IS l_coll_cnt NUMBER := 0; l_can_copy NUMBER := 1; l_tmpl_udm_type VARCHAR2(128); l_tgt_udm_type VARCHAR2(128); l_proc_name VARCHAR2(32) := 'can_copy : '; BEGIN IF EMDW_LOG.P_IS_DEBUG_SET THEN EMDW_LOG.DEBUG(l_proc_name || ' Enter ' || ' is txp = [' || p_metric_info.is_transposed || ']' || ' src guid = [' || p_src_object_guid || ']' || ' src type = [' || p_src_object_type || ']' || ' Dest guid = [' || p_dest_object_guid || ']' || ' Dest type = [' || p_dest_object_type || ']' || ' coll name = [' || p_coll_name || ']', G_MODULE_NAME); END IF ; IF (p_metric_info.is_transposed = 1) THEN -- Check to see if the collection exists on destination SELECT COUNT(1) INTO l_coll_cnt FROM mgmt_collections WHERE object_type = p_dest_object_type AND object_guid = p_dest_object_guid AND coll_name = p_coll_name; IF (l_coll_cnt > 0) THEN -- Get source UDM type l_tmpl_udm_type := get_udm_type( p_metric_info => p_metric_info, p_object_guid => p_src_object_guid, p_object_type => p_src_object_type, p_coll_name => p_coll_name); -- get target UDM type l_tgt_udm_type := get_udm_type( p_metric_info => p_metric_info, p_object_guid => p_dest_object_guid, p_object_type => p_dest_object_type, p_coll_name => p_coll_name); IF NOT (l_tmpl_udm_type = l_tgt_udm_type) THEN l_can_copy := 0; END IF; -- NOT tmpl_udm = tgt_udm END IF; END IF; IF EMDW_LOG.P_IS_DEBUG_SET THEN EMDW_LOG.DEBUG(l_proc_name || ' Exit ' || ' ret val = [' || l_can_copy || ']' || ' tmpl udm tpe = [' || l_tmpl_udm_type || ']' || ' tgt udm type = [' || l_tgt_udm_type || ']', G_MODULE_NAME); END IF ; RETURN l_can_copy; END can_copy; PROCEDURE merge_key_cfgs( p_src1_object_guid IN RAW, p_src1_object_type IN NUMBER, p_src1_coll_name IN VARCHAR2, p_src2_object_guid IN RAW, p_src2_object_type IN NUMBER, p_src2_coll_name IN VARCHAR2, p_dest_object_guid IN RAW, p_dest_object_type IN NUMBER, p_dest_coll_name IN VARCHAR2, p_policy_guid IN RAW, p_policy_type IN NUMBER, p_is_enabled IN NUMBER, p_copy_type IN NUMBER, p_metric_info IN EM_METRIC.METRIC_INFO_REC, p_ca_creds IN MGMT_MNTR_CA_ARRAY DEFAULT NULL, p_add_or_delete IN NUMBER DEFAULT 0) IS l_tmpl_key_values MGMT_MEDIUM_STRING_ARRAY; l_tmpl_key_opers MGMT_INTEGER_ARRAY; l_tmpl_key_status MGMT_INTEGER_ARRAY; l_tmpl_ctr integer; l_tmkc_ctr INTEGER; l_tmkc_idx INTEGER; l_tmkc_dflt_idx integer; l_tgt_key_values MGMT_MEDIUM_STRING_ARRAY; l_tgt_key_opers MGMT_INTEGER_ARRAY; l_tgt_prev_overrides MGMT_INTEGER_ARRAY; l_tgt_actv_bslns MGMT_INTEGER_ARRAY; l_tgt_ctr integer; l_tgkc_dflt_idx integer; l_tgkc_ctr integer; l_tc_eval_order mgmt_policy_assoc_cfg.eval_order%TYPE; l_src_object_type mgmt_policy_assoc.object_type%TYPE; l_src_object_guid mgmt_policy_assoc.object_guid%TYPE; l_src_coll_name mgmt_policy_assoc.coll_name%TYPE; l_proc_name VARCHAR2(32) := 'merge_key_cfgs: '; BEGIN IF EMDW_LOG.P_IS_DEBUG_SET THEN EMDW_LOG.DEBUG(l_proc_name || ' Enter ' || ' src1 guid = [' || p_src1_object_guid || ']' || ' src1 type = [' || p_src1_object_type || ']' || ' src1 coll = [' || p_src1_coll_name || ']' || ' src2 guid = [' || p_src2_object_guid || ']' || ' src2 type = [' || p_src2_object_type || ']' || ' src2 coll = [' || p_src2_coll_name || ']' || ' Dest guid = [' || p_dest_object_guid || ']' || ' Dest type = [' || p_dest_object_type || ']' || ' Dest coll = [' || p_dest_coll_name || ']' || ' Copy Type = [' || p_copy_type || ']', G_MODULE_NAME); END IF ; -- Merge keys algo -- Psuedo code for merge template and target key configurations -- Get template keycfgs sorted by key_value, key_oper -- Get target keycfgs sorted by key_value, key_oper -- Iterate through tgt list -- If DEFAULT key, SKIP -- If copy-all -- If prev_override or has_active_baselines -- Copy keycfg from target -- end-if -- else -- If prev_override or has_active_baselines or -- (tmpl does not have the key) -- Copy keycfg from target -- else -- Copy keycfg from template -- end-if -- end-if -- end-loop -- If (COPY_ALL) -- Iterate through the tmpl_list -- If DEFAULT key, SKIP -- COPY unhandled keycfgs from template to template copy -- end-loop -- end-if -- If tgt has DEFAULT keycfg -- If prev_override or has_active_baselines OR -- (tmpl does not hace DEFAULT keycfg) -- COPY DEFAULT keycfg from target to template copy -- elsif (tmpl has DEFAULT keycfg) -- COPY DEFAULT keycfg from template to template copy -- end-if -- elsif -- if (tmpl has DEFAULT keycfg) -- COPY DEFAULT keycfg from template to template copy -- end-if; -- end-if -- -- Add policy assoc rec EM_POLICY.add_policy_assoc( p_object_guid => p_dest_object_guid, p_policy_guid => p_policy_guid, p_coll_name => p_dest_coll_name, p_object_type => p_dest_object_type, p_policy_type => p_policy_type, p_is_enabled => p_is_enabled, p_add_or_delete => p_add_or_delete); -- Get the list of key cfgs for target/policy ordered by eval order SELECT pac.key_value, pac.key_operator, pac.prevent_override, pac.has_active_baseline BULK COLLECT INTO l_tgt_key_values, l_tgt_key_opers, l_tgt_prev_overrides, l_tgt_actv_bslns FROM mgmt_policy_assoc_cfg pac WHERE pac.object_guid = p_src1_object_guid AND pac.policy_guid = p_policy_guid AND pac.coll_name = p_src1_coll_name ORDER BY eval_order; -- Get the list of key cfgs for template/policy ordered by eval order SELECT pac.key_value, pac.key_operator, 0 BULK COLLECT INTO l_tmpl_key_values, l_tmpl_key_opers, l_tmpl_key_status FROM mgmt_policy_assoc_cfg pac WHERE pac.object_guid = p_src2_object_guid AND pac.policy_guid = p_policy_guid AND pac.coll_name = p_src2_coll_name ORDER BY eval_order; IF EMDW_LOG.P_IS_DEBUG_SET THEN EMDW_LOG.DEBUG(l_proc_name || ' Got src 1 key COUNT = ' || l_tgt_key_values.COUNT || ' src 2 key COUNT = ' || l_tmpl_key_values.COUNT, G_MODULE_NAME) ; END IF ; l_tmpl_ctr := 1; l_tc_eval_order := 0; l_tgkc_dflt_idx := -1; l_tmkc_dflt_idx := -1; -- Add all target key cfgs to template copy IF (l_tgt_key_values.COUNT > 0) THEN l_src_object_type := MGMT_GLOBAL.G_OBJECT_TYPE_TARGET; FOR l_tgkc_ctr IN l_tgt_key_values.FIRST..l_tgt_key_values.LAST LOOP IF EMDW_LOG.P_IS_DEBUG_SET THEN EMDW_LOG.DEBUG(l_proc_name || ' ctr1 = ' || l_tgkc_ctr || ' Processing key value = [' || l_tgt_key_values(l_tgkc_ctr) || ']' || ' key oper = [' || l_tgt_key_opers(l_tgkc_ctr) || ']', G_MODULE_NAME) ; END IF ; l_src_object_type := MGMT_GLOBAL.G_OBJECT_TYPE_TARGET; l_src_object_guid := NULL; l_src_coll_name := NULL; -- Check to see if template also has the same key cfg l_tmkc_idx := -1; IF (l_tmpl_key_values.COUNT > 0) THEN FOR l_tmkc_ctr IN l_tmpl_key_values.FIRST..l_tmpl_key_values.LAST LOOP IF ( (l_tgt_key_values(l_tgkc_ctr) = l_tmpl_key_values(l_tmkc_ctr)) AND (l_tgt_key_opers(l_tgkc_ctr) = l_tmpl_key_opers(l_tmkc_ctr)) ) THEN l_tmkc_idx := l_tmkc_ctr; END IF; END LOOP; END IF; IF (l_tgt_key_values(l_tgkc_ctr) = ' ') THEN -- Skip DEFAULT key and process it at the end l_tgkc_dflt_idx := l_tgkc_ctr; l_tmkc_dflt_idx := l_tmkc_idx; ELSE -- Use target key cfg if prevent override / has active baseline flag is set IF (p_copy_type = MGMT_TEMPLATE.G_TEMPLATE_COPY_ALL) THEN -- For copy-all, copy only key cfgs that has prevent override/has_active_bsln flag IF ( (l_tgt_prev_overrides(l_tgkc_ctr) = MGMT_GLOBAL.G_TRUE) OR (l_tgt_actv_bslns(l_tgkc_ctr) = MGMT_GLOBAL.G_TRUE) ) THEN l_src_object_type := p_src1_object_type; -- TARGET l_src_object_guid := p_src1_object_guid; l_src_coll_name := p_src1_coll_name; IF (l_tmkc_idx <> -1) THEN l_tmpl_key_status(l_tmkc_idx) := 1; -- Mark it as processed, if exists in template END IF; END IF; ELSIF (p_copy_type = MGMT_TEMPLATE.G_TMPL_COPY_ALL_WITH_RETAIN) THEN -- For copy-all-with-retain, copy only key cfgs that has prevent override/has_active_bsln flag -- or if the template does not have the key cfg. IF ( (l_tgt_prev_overrides(l_tgkc_ctr) = MGMT_GLOBAL.G_TRUE) OR (l_tgt_actv_bslns(l_tgkc_ctr) = MGMT_GLOBAL.G_TRUE) OR (l_tmkc_idx = -1) ) THEN l_src_object_type := p_src1_object_type; -- TARGET l_src_object_guid := p_src1_object_guid; l_src_coll_name := p_src1_coll_name; IF (l_tmkc_idx <> -1) THEN l_tmpl_key_status(l_tmkc_idx) := 1; -- Mark it as processed, if exists in template END IF; END IF; ELSE -- For copy common IF (l_tmkc_idx <> -1) THEN l_tmpl_key_status(l_tmkc_idx) := 1; END IF; -- Copy target key cfg if prevent override / has active baseline flag is set -- or if the template does not have the key cfg. IF ( (l_tgt_prev_overrides(l_tgkc_ctr) = MGMT_GLOBAL.G_TRUE) OR (l_tgt_actv_bslns(l_tgkc_ctr) = MGMT_GLOBAL.G_TRUE) OR (l_tmkc_idx = -1) ) THEN l_src_object_type := p_src1_object_type; -- TARGET l_src_object_guid := p_src1_object_guid; l_src_coll_name := p_src1_coll_name; ELSE l_src_object_type := p_src2_object_type; l_src_object_guid := p_src2_object_guid; l_src_coll_name := p_src2_coll_name; END IF; END IF; -- If copy_type = COPY_ALL IF (l_src_object_guid IS NOT NULL) THEN IF EMDW_LOG.P_IS_DEBUG_SET THEN EMDW_LOG.DEBUG(l_proc_name || ' ctr 1 = ' || l_tgkc_ctr || ' tmkc_idx = ' || l_tmkc_idx || ' Copying key cfg from type = [' || l_src_object_type || ']' || ' guid = [' || l_src_object_guid || ']' || ' coll = [' || l_src_coll_name || ']', G_MODULE_NAME) ; END IF ; EM_POLICY.copy_object_policy_assoc_cfg( p_src_object_guid => l_src_object_guid, p_src_object_type => l_src_object_type, p_dest_object_guid => p_dest_object_guid, p_dest_object_type => p_dest_object_type, p_policy_guid => p_policy_guid, p_src_coll_name => l_src_coll_name, p_dest_coll_name => p_dest_coll_name, p_src_key_value => l_tgt_key_values(l_tgkc_ctr), p_src_key_oper => l_tgt_key_opers(l_tgkc_ctr), p_dest_eval_order => l_tc_eval_order, p_metric_info => p_metric_info, p_ca_creds => p_ca_creds); l_tc_eval_order := l_tc_eval_order + 1; END IF; -- l_src_object_guid IS NOT NULL END IF; -- If key = DEFAULT END LOOP; END IF; -- If tgt_keycfg.COUNT > 0 -- Add unprocessed key configs from template, for COPY_ALL and COPY_ALL_WITH_RETAIN case IF ( ( (p_copy_type = MGMT_TEMPLATE.G_TEMPLATE_COPY_ALL) OR (p_copy_type = MGMT_TEMPLATE.G_TMPL_COPY_ALL_WITH_RETAIN) ) AND (l_tmpl_key_values.COUNT > 0) ) THEN FOR l_tmkc_ctr IN l_tmpl_key_values.FIRST..l_tmpl_key_values.LAST LOOP -- If this is a new key present only in the template -- Also, do not process the default key IF (l_tmpl_key_values(l_tmkc_ctr) = ' ') THEN l_tmkc_dflt_idx := l_tmkc_ctr; ELSIF (l_tmpl_key_status(l_tmkc_ctr) = 0) THEN l_src_object_type := p_src2_object_type; l_src_object_guid := p_src2_object_guid; l_src_coll_name := p_src2_coll_name; IF EMDW_LOG.P_IS_DEBUG_SET THEN EMDW_LOG.DEBUG(l_proc_name || ' tmpl ctr = ' || l_tmkc_ctr || ' Copying key cfg from template = [' || l_src_object_type || ']' || ' guid = [' || l_src_object_guid || '] coll_name = [' || l_src_coll_name || ']', G_MODULE_NAME) ; END IF ; EM_POLICY.copy_object_policy_assoc_cfg( p_src_object_guid => l_src_object_guid, p_src_object_type => l_src_object_type, p_dest_object_guid => p_dest_object_guid, p_dest_object_type => p_dest_object_type, p_policy_guid => p_policy_guid, p_src_coll_name => l_src_coll_name, p_dest_coll_name => p_dest_coll_name, p_src_key_value => l_tmpl_key_values(l_tmkc_ctr), p_src_key_oper => l_tmpl_key_opers(l_tmkc_ctr), p_dest_eval_order => l_tc_eval_order, p_metric_info => p_metric_info, p_ca_creds => p_ca_creds); l_tc_eval_order := l_tc_eval_order + 1; END IF; -- l_tmpl_key_stauts = 0 END LOOP; END IF; -- IF l_tmpl_key_values.COUNT > 0 IF EMDW_LOG.P_IS_DEBUG_SET THEN EMDW_LOG.DEBUG(l_proc_name || ' dflt1 idx = ' || l_tgkc_dflt_idx || ' dflt2 idx = ' || l_tmkc_dflt_idx, G_MODULE_NAME) ; END IF ; -- Add the default key (at the end of the key cfg list) IF (l_tgkc_dflt_idx <> -1) THEN -- Default key exists on target -- If prev_override or has_active_baselines OR -- (tmpl does not hace DEFAULT keycfg) -- COPY DEFAULT keycfg from target to template copy -- elsif (tmpl has DEFAULT keycfg) -- COPY DEFAULT keycfg from template to template copy IF ( (l_tgt_prev_overrides(l_tgkc_dflt_idx) = MGMT_GLOBAL.G_TRUE) OR (l_tgt_actv_bslns(l_tgkc_dflt_idx) = MGMT_GLOBAL.G_TRUE) OR (l_tmkc_dflt_idx = -1) ) THEN l_src_object_type := p_src1_object_type; -- TARGET l_src_object_guid := p_src1_object_guid; l_src_coll_name := p_src1_coll_name; ELSE l_src_object_type := p_src2_object_type; l_src_object_guid := p_src2_object_guid; l_src_coll_name := p_src2_coll_name; END IF; IF EMDW_LOG.P_IS_DEBUG_SET THEN EMDW_LOG.DEBUG(l_proc_name || ' dflt prev_over = ' || l_tgt_prev_overrides(l_tgkc_dflt_idx) || ' dflt has_actv = ' || l_tgt_actv_bslns(l_tgkc_dflt_idx) || ' dflt2 idx = ' || l_tmkc_dflt_idx || ' dflt src type = ' || l_src_object_type || ' dflt src guid = ' || l_src_object_guid || ' dflt src coll = ' || l_src_coll_name, G_MODULE_NAME) ; END IF ; EM_POLICY.copy_object_policy_assoc_cfg( p_src_object_guid => l_src_object_guid, p_src_object_type => l_src_object_type, p_dest_object_guid => p_dest_object_guid, p_dest_object_type => p_dest_object_type, p_policy_guid => p_policy_guid, p_src_coll_name => l_src_coll_name, p_dest_coll_name => p_dest_coll_name, p_src_key_value => l_tgt_key_values(l_tgkc_dflt_idx), p_src_key_oper => l_tgt_key_opers(l_tgkc_dflt_idx), p_dest_eval_order => l_tc_eval_order, p_metric_info => p_metric_info, p_ca_creds => p_ca_creds); ELSIF (l_tmkc_dflt_idx <> -1) THEN -- Default key exists in only template l_src_object_type := p_src2_object_type; l_src_object_guid := p_src2_object_guid; l_src_coll_name := p_src2_coll_name; IF EMDW_LOG.P_IS_DEBUG_SET THEN EMDW_LOG.DEBUG(l_proc_name || ' Copying default from template ' || ' dflt src type = ' || l_src_object_type || ' dflt src guid = ' || l_src_object_guid || ' dflt src coll = ' || l_src_coll_name, G_MODULE_NAME) ; END IF ; EM_POLICY.copy_object_policy_assoc_cfg( p_src_object_guid => l_src_object_guid, p_src_object_type => l_src_object_type, p_dest_object_guid => p_dest_object_guid, p_dest_object_type => p_dest_object_type, p_policy_guid => p_policy_guid, p_src_coll_name => l_src_coll_name, p_dest_coll_name => p_dest_coll_name, p_src_key_value => l_tmpl_key_values(l_tmkc_dflt_idx), p_src_key_oper => l_tmpl_key_opers(l_tmkc_dflt_idx), p_dest_eval_order => l_tc_eval_order, p_metric_info => p_metric_info, p_ca_creds => p_ca_creds); ELSE IF EMDW_LOG.P_IS_DEBUG_SET THEN EMDW_LOG.DEBUG(l_proc_name || ' No defualt cfg exists', G_MODULE_NAME) ; END IF ; END IF; -- l_tgkc_dflt_idx <> -1 END merge_key_cfgs; -- Creates template copy FUNCTION create_template_copy ( p_target_type IN VARCHAR2, p_template_name IN VARCHAR2, p_target_name IN VARCHAR2 DEFAULT ' ', p_copy_req_guid IN RAW, p_copy_type IN NUMBER, p_ca_creds IN MGMT_MNTR_CA_ARRAY DEFAULT NULL, p_coll_creds IN MGMT_COLLECTION_CRED_ARRAY DEFAULT NULL) RETURN RAW IS l_template_copy_guid MGMT_TEMPLATE_COPIES.template_copy_guid%TYPE; l_template_guid MGMT_TEMPLATES.template_guid%TYPE; l_target_guid MGMT_TARGETS.target_guid%TYPE; l_current_user mgmt_created_users.user_name%TYPE; l_tmpl_policy_guids MGMT_TARGET_GUID_ARRAY; l_tmpl_metric_guids MGMT_TARGET_GUID_ARRAY; l_tmpl_coll_names MGMT_SHORT_STRING_ARRAY; l_tmpl_policy_types MGMT_SHORT_STRING_ARRAY; l_tmpl_enabled MGMT_INTEGER_ARRAY; l_tmpl_key_values MGMT_MEDIUM_STRING_ARRAY; l_tmpl_key_opers MGMT_INTEGER_ARRAY; l_tmpl_key_status MGMT_INTEGER_ARRAY; l_tmpl_ctr integer; l_tmkc_ctr INTEGER; l_tmkc_idx INTEGER; l_tgt_policy_guids MGMT_TARGET_GUID_ARRAY; l_tgt_metric_guids MGMT_TARGET_GUID_ARRAY; l_tgt_coll_names MGMT_SHORT_STRING_ARRAY; l_tgt_policy_types MGMT_SHORT_STRING_ARRAY; l_tgt_enabled MGMT_INTEGER_ARRAY; l_tgt_udm_type mgmt_coll_item_properties.property_value%TYPE; l_tgt_key_values MGMT_MEDIUM_STRING_ARRAY; l_tgt_key_opers MGMT_INTEGER_ARRAY; l_tgt_prev_overrides MGMT_INTEGER_ARRAY; l_tgt_actv_bslns MGMT_INTEGER_ARRAY; l_tgt_ctr integer; l_tgkc_ctr integer; l_met_info EM_METRIC.METRIC_INFO_REC; l_new_coll_name mgmt_policy_assoc.coll_name%TYPE; l_src_object_type mgmt_policy_assoc.object_type%TYPE; l_src_object_guid mgmt_policy_assoc.object_guid%TYPE; l_src_coll_name mgmt_policy_assoc.coll_name%TYPE; l_dest_object_type mgmt_policy_assoc.object_type%TYPE; l_dest_object_guid mgmt_policy_assoc.object_guid%TYPE; l_dest_coll_name mgmt_policy_assoc.coll_name%TYPE; l_tc_eval_order mgmt_policy_assoc_cfg.eval_order%TYPE; l_metric_guid mgmt_metrics.metric_guid%TYPE; l_tgt_prevent_override mgmt_policy_assoc_cfg.prevent_override%TYPE; l_copy_assoc NUMBER := 0; l_coll_cnt NUMBER := 0; l_proc_name VARCHAR2(32) := 'create_template_copy: '; BEGIN l_current_user := MGMT_USER.get_current_em_user; IF EMDW_LOG.P_IS_DEBUG_SET THEN EMDW_LOG.DEBUG(l_proc_name || ' Enter ' || ' Target type = [' || p_target_type || '] Template Name = [' || p_template_name || '] Target Name = [' || p_target_name || '] Copy Req Guid = [' || p_copy_req_guid || '] Copy Type = [' || p_copy_type || ']', G_MODULE_NAME); END IF ; l_template_guid := get_template_guid(p_target_type, p_template_name); IF (NVL(p_target_name, ' ') = ' ') THEN l_target_guid := MGMT_GLOBAL.G_ALL_ZERO_GUID; ELSE l_target_guid := MGMT_TARGET.get_target_guid( target_type_in => p_target_type, target_name_in => p_target_name); END IF; l_template_copy_guid := generate_template_copy_guid( p_target_type, p_template_name, p_target_name, p_copy_req_guid); IF EMDW_LOG.P_IS_DEBUG_SET THEN EMDW_LOG.DEBUG(l_proc_name || 'Storing template copy guid = ' || l_template_copy_guid || ' template guid = ' || l_template_guid || ' target guid = ' || l_target_guid, G_MODULE_NAME); END IF ; INSERT INTO mgmt_template_copies (template_copy_guid, template_guid, target_guid, copy_req_guid, copy_type, created_date, created_by) VALUES (l_template_copy_guid, l_template_guid, l_target_guid, p_copy_req_guid, p_copy_type, SYSDATE, l_current_user); -- No need to copy access list -- Save the collection credentials IF p_coll_creds IS NOT NULL THEN MGMT_CREDENTIAL.set_collection_template_creds(p_coll_creds, l_template_copy_guid, MGMT_CREDENTIAL.OBJECT_TYPE_TEMPLATE_COPY); END IF; -- create template copy from template create_template_copy(l_target_guid, l_template_guid, MGMT_GLOBAL.G_OBJECT_TYPE_TEMPLATE, l_template_copy_guid, p_copy_type, p_ca_creds); IF EMDW_LOG.P_IS_DEBUG_SET THEN EMDW_LOG.DEBUG(l_proc_name || ' Normal exit. Returing copy_guid = ' || l_template_copy_guid, G_MODULE_NAME); END IF ; RETURN l_template_copy_guid; END create_template_copy; -- Creates template copy PROCEDURE create_template_copy ( p_target_guid IN RAW, p_template_guid IN RAW, p_template_object_type IN NUMBER, p_template_copy_guid IN RAW, p_copy_type IN NUMBER, p_ca_creds IN MGMT_MNTR_CA_ARRAY DEFAULT NULL) IS l_template_copy_guid MGMT_TEMPLATE_COPIES.template_copy_guid%TYPE; l_template_guid MGMT_TEMPLATES.template_guid%TYPE; l_target_guid MGMT_TARGETS.target_guid%TYPE; l_tmpl_policy_guids MGMT_TARGET_GUID_ARRAY; l_tmpl_metric_guids MGMT_TARGET_GUID_ARRAY; l_tmpl_coll_names MGMT_SHORT_STRING_ARRAY; l_tmpl_policy_types MGMT_SHORT_STRING_ARRAY; l_tmpl_enabled MGMT_INTEGER_ARRAY; l_tmpl_add_or_delete MGMT_SHORT_STRING_ARRAY; l_tmpl_key_values MGMT_MEDIUM_STRING_ARRAY; l_tmpl_key_opers MGMT_INTEGER_ARRAY; l_tmpl_key_status MGMT_INTEGER_ARRAY; l_tmpl_ctr integer; l_tmkc_ctr INTEGER; l_tmkc_idx INTEGER; l_tgt_policy_guids MGMT_TARGET_GUID_ARRAY; l_tgt_metric_guids MGMT_TARGET_GUID_ARRAY; l_tgt_coll_names MGMT_SHORT_STRING_ARRAY; l_tgt_policy_types MGMT_SHORT_STRING_ARRAY; l_tgt_enabled MGMT_INTEGER_ARRAY; l_tgt_key_values MGMT_MEDIUM_STRING_ARRAY; l_tgt_key_opers MGMT_INTEGER_ARRAY; l_tgt_prev_overrides MGMT_INTEGER_ARRAY; l_tgt_actv_bslns MGMT_INTEGER_ARRAY; l_tgt_ctr integer; l_tgkc_ctr integer; l_met_info EM_METRIC.METRIC_INFO_REC; l_new_coll_name mgmt_policy_assoc.coll_name%TYPE; l_src_object_type mgmt_policy_assoc.object_type%TYPE; l_src_object_guid mgmt_policy_assoc.object_guid%TYPE; l_tc_eval_order mgmt_policy_assoc_cfg.eval_order%TYPE; l_metric_guid mgmt_metrics.metric_guid%TYPE; l_tgt_prevent_override mgmt_policy_assoc_cfg.prevent_override%TYPE; l_copy_assoc NUMBER := 0; l_has_collection NUMBER := 0; l_proc_name VARCHAR2(32) := 'create_template_copy: '; BEGIN l_template_guid := p_template_guid; l_target_guid := p_target_guid; l_template_copy_guid := p_template_copy_guid; -- Copy collections -- Merge template collections with target collections to create -- template copy collections -- Psuedo code for merging is as follows: -- Get template collections sorted by metric guid, coll name -- Get target collections sorted by metric guid, coll name -- While (one of the list has more entries) -- if (has reached the end of template list) -- COPY collection from target copy -- elsif (has reached the end of target list) -- COPY collection from template copy -- elsif (tmpl_metric < tgt_metric) -- COPY collection from template copy -- elsif (tmpl_metric > tgt_metric) -- COPY collection from target copy -- else -- if (is_transposed_metric) -- if (tmpl_coll_name < tgt_coll_name) -- COPY collection from template to template copy -- elsif (tmpl_coll_name > tgt_coll_name) -- COPY collection from target to template copy -- else -- if (tmpl_udm_type = tgt_udm_type) -- COPY collection from template to template copy -- else -- COPY collection from target -- end-if -- Prop values are same -- end-if -- else -- COPY collection from template to template copy -- end-if; -- is transposed -- end-if -- end-loop; -- TODO: Move the following merging to collection_util.create_template_copy_collections -- We would like to process collections for which add_or_delete is set to "1". -- Thus here we need weather add_or_delete is set in the template or not. SELECT cmt.metric_guid, c.coll_name, c.is_enabled, pa.add_or_delete BULK COLLECT INTO l_tmpl_metric_guids, l_tmpl_coll_names , l_tmpl_enabled, l_tmpl_add_or_delete FROM mgmt_collections c, mgmt_collection_metric_tasks cmt, mgmt_policies p, mgmt_policy_assoc pa WHERE c.object_guid = l_template_guid AND c.object_type = p_template_object_type AND c.object_guid = cmt.target_guid AND c.coll_name = cmt.coll_name AND p.metric_guid = cmt.metric_guid AND p.policy_guid = pa.policy_guid AND pa.object_guid = c.object_guid AND pa.object_type = c.object_type AND pa.coll_name = cmt.coll_name ORDER BY cmt.metric_guid, c.coll_name; SELECT cmt.metric_guid, c.coll_name, c.is_enabled BULK COLLECT INTO l_tgt_metric_guids, l_tgt_coll_names, l_tgt_enabled FROM mgmt_collections c, mgmt_collection_metric_tasks cmt WHERE c.object_guid = cmt.target_guid AND c.coll_name = cmt.coll_name AND c.object_guid = l_target_guid AND c.object_type = MGMT_GLOBAL.G_OBJECT_TYPE_TARGET ORDER BY cmt.metric_guid, c.coll_name; IF EMDW_LOG.P_IS_DEBUG_SET THEN EMDW_LOG.DEBUG(l_proc_name || ' Got template coll COUNT = ' || l_tmpl_metric_guids.COUNT || ' target collections COUNT = ' || l_tgt_metric_guids.COUNT, G_MODULE_NAME) ; END IF ; l_tmpl_ctr := 1; l_tgt_ctr := 1; WHILE ( (l_tmpl_ctr <= l_tmpl_metric_guids.COUNT ) OR (l_tgt_ctr <= l_tgt_metric_guids.COUNT ) ) LOOP IF EMDW_LOG.P_IS_DEBUG_SET THEN EMDW_LOG.DEBUG(l_proc_name || ' Looping tmpl_ctr=[' || l_tmpl_ctr || ']' || ' tgt_ctr=[' || l_tgt_ctr || ']', G_MODULE_NAME) ; END IF ; l_has_collection := 0; IF (l_tmpl_ctr > l_tmpl_metric_guids.COUNT) THEN -- We have reached the end of template list, process from target list IF EMDW_LOG.P_IS_DEBUG_SET THEN EMDW_LOG.DEBUG(l_proc_name || ' Coll Case 1: Processing from target list. ' || ' Metric guid =' || l_tgt_metric_guids(l_tgt_ctr) || ' coll name =[' || l_tgt_coll_names(l_tgt_ctr) || ']', G_MODULE_NAME) ; END IF ; EM_COLL_UTIL.copy_object_coll( p_src_object_guid => l_target_guid, p_src_object_type => MGMT_GLOBAL.G_OBJECT_TYPE_TARGET, p_dest_object_guid => l_template_copy_guid, p_dest_object_type => MGMT_GLOBAL.G_OBJECT_TYPE_TEMPLATE_COPY, p_src_coll_name => l_tgt_coll_names(l_tgt_ctr), p_dest_coll_name => l_tgt_coll_names(l_tgt_ctr) ); l_tgt_ctr := l_tgt_ctr + 1; ELSIF (l_tgt_ctr > l_tgt_metric_guids.COUNT) THEN -- We have reached the end of target list as the target counter is more -- than the COUNT of metrics in the target. Thus, process from template list. -- We have to consider following points before we add Collection to the template copy clone. -- Check for COLL_NAME in case of 2COLSQL NUM or 2COLSQL STR or Single Value UDM on target has -- same name as the COLL_NAME in the Template. We would not like to process such a metrics. -- For Single Value and 2COL SQL UDM NUM/STR will have different METRIC_GUID. -- But can have same collection name. We have to stop such a secnario. IF EMDW_LOG.P_IS_DEBUG_SET THEN EMDW_LOG.DEBUG(l_proc_name || ' Coll Case 2: Processing from template list.' || ' Metric guid =' || l_tmpl_metric_guids(l_tmpl_ctr) || ' coll name =[' || l_tmpl_coll_names(l_tmpl_ctr) || ']', G_MODULE_NAME) ; END IF ; -- Verify that the metric is applicable to the target, EM_METRIC.get_metric_info_for_target(l_tmpl_metric_guids(l_tmpl_ctr), l_target_guid, l_met_info); IF (l_met_info.metric_cols.COUNT > 0) THEN IF EMDW_LOG.P_IS_DEBUG_SET THEN EMDW_LOG.DEBUG(l_proc_name || ' Coll Case 2: Policy is applicable.' || ' Metric Name = ' || l_met_info.metric_name, G_MODULE_NAME) ; END IF ; -- Metric is applicable to the target, proceed with adding to the template copy -- If applicable, Get collection name IF (l_met_info.is_transposed = MGMT_GLOBAL.G_TRUE) THEN l_new_coll_name := l_tmpl_coll_names(l_tmpl_ctr); ELSE l_new_coll_name := NVL(get_coll_name(l_met_info, l_target_guid), l_tmpl_coll_names(l_tmpl_ctr) ); END IF; IF (l_met_info.is_transposed = 1) THEN l_has_collection := does_target_has_collection( p_tgt_coll_name => l_tgt_coll_names, p_coll_name => l_tmpl_coll_names(l_tmpl_ctr)); END IF; -- Check to see if the collection can be copied IF (l_has_collection = 0) THEN l_copy_assoc := can_copy( p_metric_info => l_met_info, p_src_object_guid => l_template_guid, p_src_object_type => p_template_object_type, p_dest_object_guid => l_target_guid, p_dest_object_type => MGMT_GLOBAL.G_OBJECT_TYPE_TARGET, p_coll_name => l_new_coll_name); IF (l_copy_assoc = 1) THEN EM_COLL_UTIL.copy_object_coll( p_src_object_guid => l_template_guid, p_src_object_type => p_template_object_type, p_dest_object_guid => l_template_copy_guid, p_dest_object_type => MGMT_GLOBAL.G_OBJECT_TYPE_TEMPLATE_COPY, p_src_coll_name => l_tmpl_coll_names(l_tmpl_ctr), p_dest_coll_name => l_new_coll_name); END IF; END IF; --l_has_collection = 0 END IF; l_tmpl_ctr := l_tmpl_ctr + 1; ELSIF (l_tmpl_metric_guids(l_tmpl_ctr) < l_tgt_metric_guids(l_tgt_ctr)) THEN IF EMDW_LOG.P_IS_DEBUG_SET THEN EMDW_LOG.DEBUG(l_proc_name || ' Coll Case 3: Processing from template list.' || ' Metric guid =' || l_tmpl_metric_guids(l_tmpl_ctr) || ' coll name =[' || l_tmpl_coll_names(l_tmpl_ctr) || ']', G_MODULE_NAME) ; END IF ; -- Verify that the metric is applicable to the target, EM_METRIC.get_metric_info_for_target(l_tmpl_metric_guids(l_tmpl_ctr), l_target_guid, l_met_info); -- We have to consider following points before we add Collection to the template copy clone. -- Check for COLL_NAME in case of 2COLSQL NUM or 2COLSQL STR or Single Value UDM on target has -- same name as the COLL_NAME in the Template. We would like like to process such a metrics. -- For Single Value and 2COL SQL UDM NUM/STR will have different METRIC_GUID. -- But can have same collection name. We have to stop such a secnario. IF (l_met_info.metric_cols.COUNT > 0) THEN IF EMDW_LOG.P_IS_DEBUG_SET THEN EMDW_LOG.DEBUG(l_proc_name || ' Coll Case 2: Policy is applicable.' || ' Metric Name = ' || l_met_info.metric_name, G_MODULE_NAME) ; END IF ; -- Metric is applicable to the target, proceed with adding to the template copy -- If applicable, Get collection name IF (l_met_info.is_transposed = MGMT_GLOBAL.G_TRUE) THEN l_new_coll_name := l_tmpl_coll_names(l_tmpl_ctr); ELSE l_new_coll_name := NVL(get_coll_name(l_met_info, l_target_guid), l_tmpl_coll_names(l_tmpl_ctr) ); END IF; IF (l_met_info.is_transposed = 1) THEN l_has_collection := does_target_has_collection( p_tgt_coll_name => l_tgt_coll_names, p_coll_name => l_tmpl_coll_names(l_tmpl_ctr)); END IF; IF (l_has_collection = 0) THEN -- Check to see if the collection can be copied l_copy_assoc := can_copy( p_metric_info => l_met_info, p_src_object_guid => l_template_guid, p_src_object_type => p_template_object_type, p_dest_object_guid => l_target_guid, p_dest_object_type => MGMT_GLOBAL.G_OBJECT_TYPE_TARGET, p_coll_name => l_new_coll_name); IF (l_copy_assoc = 1) THEN EM_COLL_UTIL.copy_object_coll( p_src_object_guid => l_template_guid, p_src_object_type => p_template_object_type, p_dest_object_guid => l_template_copy_guid, p_dest_object_type => MGMT_GLOBAL.G_OBJECT_TYPE_TEMPLATE_COPY, p_src_coll_name => l_tmpl_coll_names(l_tmpl_ctr), p_dest_coll_name => l_new_coll_name); END IF; -- l_has_collection = 0 END IF; END IF; -- l_met_info.metric_cols.COUNT > 0 l_tmpl_ctr := l_tmpl_ctr + 1; ELSIF (l_tmpl_metric_guids(l_tmpl_ctr) > l_tgt_metric_guids(l_tgt_ctr)) THEN IF EMDW_LOG.P_IS_DEBUG_SET THEN EMDW_LOG.DEBUG(l_proc_name || ' Coll Case 4: Processing from target list. ' || ' Metric guid =' || l_tgt_metric_guids(l_tgt_ctr) || ' coll name =[' || l_tgt_coll_names(l_tgt_ctr) || ']', G_MODULE_NAME) ; END IF ; EM_COLL_UTIL.copy_object_coll( p_src_object_guid => l_target_guid, p_src_object_type => MGMT_GLOBAL.G_OBJECT_TYPE_TARGET, p_dest_object_guid => l_template_copy_guid, p_dest_object_type => MGMT_GLOBAL.G_OBJECT_TYPE_TEMPLATE_COPY, p_src_coll_name => l_tgt_coll_names(l_tgt_ctr), p_dest_coll_name => l_tgt_coll_names(l_tgt_ctr)); l_tgt_ctr := l_tgt_ctr + 1; ELSE IF EMDW_LOG.P_IS_DEBUG_SET THEN EMDW_LOG.DEBUG(l_proc_name || ' Coll Case 5: Metric guids are same. ' || ' Metric guid =' || l_tmpl_metric_guids(l_tmpl_ctr) || ' coll name =[' || l_tmpl_coll_names(l_tmpl_ctr) || ']', G_MODULE_NAME) ; END IF ; -- Verify that the metric is applicable to the target, EM_METRIC.get_metric_info_for_target(l_tmpl_metric_guids(l_tmpl_ctr), l_target_guid, l_met_info); IF (l_met_info.metric_cols.COUNT > 0) THEN IF (l_met_info.is_transposed = MGMT_GLOBAL.G_TRUE) THEN -- Template Metric GUID id same as target Metric GUID. -- Metric exist on both Template and Target. - UDM of Same TYPE IF (l_tgt_coll_names(l_tgt_ctr) < l_tmpl_coll_names(l_tmpl_ctr)) THEN -- Copy from target IF EMDW_LOG.P_IS_DEBUG_SET THEN EMDW_LOG.DEBUG(l_proc_name || ' Coll Case 51: Processing from target list.' || ' Metric guid =' || l_tgt_metric_guids(l_tgt_ctr) || ' coll name =[' || l_tgt_coll_names(l_tgt_ctr) || ']', G_MODULE_NAME) ; END IF ; EM_COLL_UTIL.copy_object_coll( p_src_object_guid => l_target_guid, p_src_object_type => MGMT_GLOBAL.G_OBJECT_TYPE_TARGET, p_dest_object_guid => l_template_copy_guid, p_dest_object_type => MGMT_GLOBAL.G_OBJECT_TYPE_TEMPLATE_COPY, p_src_coll_name => l_tgt_coll_names(l_tgt_ctr), p_dest_coll_name => l_tgt_coll_names(l_tgt_ctr)); l_tgt_ctr := l_tgt_ctr + 1; ELSIF (l_tgt_coll_names(l_tgt_ctr) > l_tmpl_coll_names(l_tmpl_ctr)) THEN -- Copy from template IF EMDW_LOG.P_IS_DEBUG_SET THEN EMDW_LOG.DEBUG(l_proc_name || ' Coll Case 52: Processing from template list.' || ' Metric guid =' || l_tmpl_metric_guids(l_tmpl_ctr) || ' coll name =[' || l_tmpl_coll_names(l_tmpl_ctr) || ']', G_MODULE_NAME) ; END IF ; l_has_collection := does_target_has_collection( p_tgt_coll_name => l_tgt_coll_names, p_coll_name => l_tmpl_coll_names(l_tmpl_ctr)); IF (l_has_collection = 0) THEN EM_COLL_UTIL.copy_object_coll( p_src_object_guid => l_template_guid, p_src_object_type => p_template_object_type, p_dest_object_guid => l_template_copy_guid, p_dest_object_type => MGMT_GLOBAL.G_OBJECT_TYPE_TEMPLATE_COPY, p_src_coll_name => l_tmpl_coll_names(l_tmpl_ctr), p_dest_coll_name => l_tmpl_coll_names(l_tmpl_ctr)); END IF ; l_tmpl_ctr := l_tmpl_ctr + 1; ELSE -- Both transposed metrics with same collection name -- Get their types, if they match, copy from template, -- copy from target otherwise -- Check to see if the collection can be copied -- In case Prevent Override for any key of teh UDM is high -- We should not modify the collection. IF (l_tmpl_add_or_delete(l_tmpl_ctr) = MGMT_GLOBAL.G_TRUE ) THEN -- Retain the target settings. -- UDM is marked for delete. Either it will be deleted or Target Setting will kept. -- So copy from target as of now. EM_COLL_UTIL.copy_object_coll( p_src_object_guid => l_target_guid, p_src_object_type => MGMT_GLOBAL.G_OBJECT_TYPE_TARGET, p_dest_object_guid => l_template_copy_guid, p_dest_object_type => MGMT_GLOBAL.G_OBJECT_TYPE_TEMPLATE_COPY, p_src_coll_name => l_tgt_coll_names(l_tgt_ctr), p_dest_coll_name => l_tgt_coll_names(l_tgt_ctr)); ELSE -- UDM is not marked for delete. -- So check if we can copy from template or retain target settings. l_copy_assoc := can_copy( p_metric_info => l_met_info, p_src_object_guid => l_template_guid, p_src_object_type => p_template_object_type, p_dest_object_guid => l_target_guid, p_dest_object_type => MGMT_GLOBAL.G_OBJECT_TYPE_TARGET, p_coll_name => l_tgt_coll_names(l_tgt_ctr)); IF (l_copy_assoc = 1) THEN -- Copy from template IF EMDW_LOG.P_IS_DEBUG_SET THEN EMDW_LOG.DEBUG(l_proc_name || ' Coll Case 531: Processing from template list.' || ' Metric guid =' || l_tmpl_metric_guids(l_tmpl_ctr) || ' coll name =[' || l_tmpl_coll_names(l_tmpl_ctr) || ']', G_MODULE_NAME) ; END IF ; -- Check to see if the collection can be copied -- In case Prevent Override for any key of the UDM is high -- We should not modify the collection. As modifying the collection -- will change the UDM definition. BEGIN SELECT count(1) INTO l_tgt_prevent_override FROM mgmt_policy_assoc_cfg cfg, mgmt_policies p WHERE cfg.object_guid = l_target_guid AND p.policy_guid = cfg.policy_guid AND p.metric_guid = l_tgt_metric_guids(l_tgt_ctr) AND cfg.policy_guid = p.policy_guid AND cfg.coll_name = l_tgt_coll_names(l_tgt_ctr) AND prevent_override = 1; END; IF (l_tgt_prevent_override > 0) THEN EM_COLL_UTIL.copy_object_coll( p_src_object_guid => l_target_guid, p_src_object_type => MGMT_GLOBAL.G_OBJECT_TYPE_TARGET, p_dest_object_guid => l_template_copy_guid, p_dest_object_type => MGMT_GLOBAL.G_OBJECT_TYPE_TEMPLATE_COPY, p_src_coll_name => l_tgt_coll_names(l_tgt_ctr), p_dest_coll_name => l_tgt_coll_names(l_tgt_ctr)); ELSE EM_COLL_UTIL.copy_object_coll( p_src_object_guid => l_template_guid, p_src_object_type => p_template_object_type, p_dest_object_guid => l_template_copy_guid, p_dest_object_type => MGMT_GLOBAL.G_OBJECT_TYPE_TEMPLATE_COPY, p_src_coll_name => l_tmpl_coll_names(l_tmpl_ctr), p_dest_coll_name => l_tmpl_coll_names(l_tmpl_ctr)); END IF; ELSE -- Copy from target IF EMDW_LOG.P_IS_DEBUG_SET THEN EMDW_LOG.DEBUG(l_proc_name || ' Coll Case 532: Processing from target list.' || ' Metric guid =' || l_tgt_metric_guids(l_tgt_ctr) || ' coll name =[' || l_tgt_coll_names(l_tgt_ctr) || ']', G_MODULE_NAME) ; END IF ; EM_COLL_UTIL.copy_object_coll( p_src_object_guid => l_target_guid, p_src_object_type => MGMT_GLOBAL.G_OBJECT_TYPE_TARGET, p_dest_object_guid => l_template_copy_guid, p_dest_object_type => MGMT_GLOBAL.G_OBJECT_TYPE_TEMPLATE_COPY, p_src_coll_name => l_tgt_coll_names(l_tgt_ctr), p_dest_coll_name => l_tgt_coll_names(l_tgt_ctr)); END IF; END IF; l_tmpl_ctr := l_tmpl_ctr + 1; l_tgt_ctr := l_tgt_ctr + 1; END IF; -- tgt_coll_name < tmpl_coll_name ELSE -- Not transposed metric, copy details from template with target coll name IF EMDW_LOG.P_IS_DEBUG_SET THEN EMDW_LOG.DEBUG(l_proc_name || ' Coll Case 54: Processing from template list.' || ' Metric guid =' || l_tmpl_metric_guids(l_tmpl_ctr) || ' coll name =[' || l_tmpl_coll_names(l_tmpl_ctr) || ']', G_MODULE_NAME) ; END IF ; l_new_coll_name := l_tgt_coll_names(l_tgt_ctr); -- Check to see if the collection can be copied -- In case Prevent Override for any key of teh UDM is high -- We should not modify the collection. BEGIN SELECT count(1) INTO l_tgt_prevent_override FROM mgmt_policy_assoc_cfg cfg, mgmt_policies p WHERE cfg.object_guid = l_target_guid AND p.policy_guid = cfg.policy_guid AND p.metric_guid = l_tgt_metric_guids(l_tgt_ctr) AND cfg.policy_guid = p.policy_guid AND cfg.coll_name = l_tgt_coll_names(l_tgt_ctr) AND prevent_override = 1; END; IF (l_tgt_prevent_override > 0) THEN EM_COLL_UTIL.copy_object_coll( p_src_object_guid => l_target_guid, p_src_object_type => MGMT_GLOBAL.G_OBJECT_TYPE_TARGET, p_dest_object_guid => l_template_copy_guid, p_dest_object_type => MGMT_GLOBAL.G_OBJECT_TYPE_TEMPLATE_COPY, p_src_coll_name => l_tgt_coll_names(l_tgt_ctr), p_dest_coll_name => l_tgt_coll_names(l_tgt_ctr)); ELSE EM_COLL_UTIL.copy_object_coll( p_src_object_guid => l_template_guid, p_src_object_type => p_template_object_type, p_dest_object_guid => l_template_copy_guid, p_dest_object_type => MGMT_GLOBAL.G_OBJECT_TYPE_TEMPLATE_COPY, p_src_coll_name => l_tmpl_coll_names(l_tmpl_ctr), p_dest_coll_name => l_new_coll_name); END IF; l_tmpl_ctr := l_tmpl_ctr + 1; l_tgt_ctr := l_tgt_ctr + 1; END IF; -- metric.is_transposed = 0 ELSE IF EMDW_LOG.P_IS_DEBUG_SET THEN EMDW_LOG.DEBUG(l_proc_name || ' Coll Case 55: Metric not applicable to target.' || ' Metric guid =' || l_tmpl_metric_guids(l_tmpl_ctr) || ' coll name =[' || l_tmpl_coll_names(l_tmpl_ctr) || ']', G_MODULE_NAME) ; END IF ; l_tmpl_ctr := l_tmpl_ctr + 1; l_tgt_ctr := l_tgt_ctr + 1; END IF; END IF; END LOOP; -- End while -- Create template copy associations -- Psuedo code for merging template and target assocs is as follows: -- Get template assocs sorted by policy guid, coll name -- Get target assocs sorted by policy guid, coll name -- While (one of the list has more entries to process) -- if (reached the end of template list) -- COPY target assoc to template copy -- elsif (reached the end of target list) -- If (policy and underlying metric are applicable to tgt) and -- (COPY_ALL or metric is transposed or test is a policy test) -- COPY template assoc to template copy with proper coll_name -- end-if -- elsif (tmpl_metric < tgt_metric) -- If (policy and underlying metric are applicable to tgt) and COPY_ALL -- (COPY_ALL or metric is transposed or test is a policy test) -- COPY template assoc to template copy with proper coll_name -- end-if -- elsif (tmpl_metric > tgt_metric) -- COPY target assoc to template copy -- else -- POLICIES MATCH -- if (is_transposed metric) -- if (temp coll_name < tgt coll_name) -- If (COPY_ALL) -- COPY template assoc to template copy with templ_coll_name -- end-if -- elsif (tmpl_coll_name > tgt_coll_name) -- COPY target assoc to template copy with tgt_coll_name -- else -- If (tmpl_udm_type = tgt_udm_type) -- -- Both tgt and tmpl have same UDM -- -- Merge keys [ See merge keys algo ] -- else -- COPY target assoc to template copy with tgt_coll_name -- end-if -- end-if -- elsif (test is a policy-test) -- if (prevent_override set for policy) -- COPY target assoc to template-copy -- else -- -- Both template and target have same policy -- -- Merge keys [ See merge keys algo ] -- end-if -- (prevent_override for policy) -- else -- -- Both tgt and tmpl have same metric-thr -- -- Merge keycfgs [ See merge keys algo ] -- end-if -- is_transposed -- end-if -- end-loop --End of while -- -- TODO: Move the following merging to em_policy.create_template_copy_assocs -- Get template policy assocs SELECT pa.policy_guid, pa.coll_name, pa.policy_type, p.metric_guid, pa.is_enabled, pa.add_or_delete BULK COLLECT INTO l_tmpl_policy_guids, l_tmpl_coll_names, l_tmpl_policy_types, l_tmpl_metric_guids, l_tmpl_enabled, l_tmpl_add_or_delete FROM mgmt_policy_assoc pa, mgmt_policies p WHERE pa.policy_guid = p.policy_guid AND pa.object_guid = l_template_guid AND pa.object_type = p_template_object_type ORDER BY pa.policy_guid, pa.coll_name; SELECT pa.policy_guid, pa.coll_name, pa.policy_type, p.metric_guid, pa.is_enabled BULK COLLECT INTO l_tgt_policy_guids, l_tgt_coll_names, l_tgt_policy_types, l_tgt_metric_guids, l_tgt_enabled FROM mgmt_policy_assoc pa, mgmt_policies p WHERE pa.policy_guid = p.policy_guid AND pa.object_guid = l_target_guid AND pa.object_type = MGMT_GLOBAL.G_OBJECT_TYPE_TARGET ORDER BY pa.policy_guid, pa.coll_name; IF EMDW_LOG.P_IS_DEBUG_SET THEN EMDW_LOG.DEBUG(l_proc_name || ' Got template metrics COUNT = ' || l_tmpl_policy_guids.COUNT || ' target metrics COUNT = ' || l_tgt_policy_guids.COUNT, G_MODULE_NAME) ; END IF ; l_tmpl_ctr := 1; l_tgt_ctr := 1; WHILE ( (l_tmpl_ctr <= l_tmpl_policy_guids.COUNT ) OR (l_tgt_ctr <= l_tgt_policy_guids.COUNT ) ) LOOP IF EMDW_LOG.P_IS_DEBUG_SET THEN EMDW_LOG.DEBUG(l_proc_name || ' Looping tmpl_ctr=[' || l_tmpl_ctr || ']' || ' tgt_ctr=[' || l_tgt_ctr || ']', G_MODULE_NAME) ; END IF ; l_has_collection := 0; IF (l_tmpl_ctr > l_tmpl_policy_guids.COUNT ) THEN -- We have reached the end of template list as the template counter is more -- that the COUNT of metrics in the template. Thus, process from target list. IF EMDW_LOG.P_IS_DEBUG_SET THEN EMDW_LOG.DEBUG(l_proc_name || ' Case 1: Processing from target list. ' || ' Policy guid =' || l_tgt_policy_guids(l_tgt_ctr) || ' policy type =[' || l_tgt_policy_types(l_tgt_ctr) || ']' || ' coll name =[' || l_tgt_coll_names(l_tgt_ctr) || ']', G_MODULE_NAME) ; END IF ; EM_POLICY.copy_object_policy_assoc( p_src_object_guid => l_target_guid, p_src_object_type => MGMT_GLOBAL.G_OBJECT_TYPE_TARGET, p_dest_object_guid => l_template_copy_guid, p_dest_object_type => MGMT_GLOBAL.G_OBJECT_TYPE_TEMPLATE_COPY, p_policy_guid => l_tgt_policy_guids(l_tgt_ctr), p_policy_type => l_tgt_policy_types(l_tgt_ctr), p_src_coll_name => l_tgt_coll_names(l_tgt_ctr), p_is_enabled => l_tgt_enabled(l_tgt_ctr)); l_tgt_ctr := l_tgt_ctr + 1; ELSIF (l_tgt_ctr > l_tgt_policy_guids.COUNT ) THEN -- We have reached the end of target list as the target counter is more -- that the COUNT of metrics in the target. Thus, process from template list. -- We have to consider following points before we add Metrics to the template copy clone. -- Check for COLL_NAME in case of 2COLSQL NUM or 2COLSQL STR or Single Value UDM on target has -- same name as the COLL_NAME in the Template. We would like like to process such a metrics. -- For Single Value and 2COL SQL UDM NUM/STR will have different METRIC_GUID. -- But can have same collection name. We have to stop such a secnario. -- NEED to check is_tranposed and the continue with checking. IF EMDW_LOG.P_IS_DEBUG_SET THEN EMDW_LOG.DEBUG(l_proc_name || ' Case 2: Processing from template list.' || ' Policy guid =' || l_tmpl_policy_guids(l_tmpl_ctr) || ' policy type =' || l_tmpl_policy_types(l_tmpl_ctr) || ' coll name =[' || l_tmpl_coll_names(l_tmpl_ctr) || ']', G_MODULE_NAME) ; END IF ; -- Verify that the metric is applicable to the target, EM_METRIC.get_metric_info_for_target(l_tmpl_metric_guids(l_tmpl_ctr), l_target_guid, l_met_info); IF (l_met_info.metric_cols.COUNT > 0) THEN -- Metric is Applicable to the Target. IF EMDW_LOG.P_IS_DEBUG_SET THEN EMDW_LOG.DEBUG(l_proc_name || ' Case 2: Policy is applicable.' || ' Metric Name = ' || l_met_info.metric_name, G_MODULE_NAME) ; END IF ; -- Metric is applicable to the target, proceed with adding to the template copy -- If applicable, Get collection name l_new_coll_name := NVL(get_coll_name(l_met_info, l_target_guid), l_tmpl_coll_names(l_tmpl_ctr) ); -- Copy from template for COPY-ALL/COPY_ALL_WITH_RETAIN or for transposed metric -- or if the policy type is a POLICY IF ( (p_copy_type = MGMT_TEMPLATE.G_TEMPLATE_COPY_ALL) OR (p_copy_type = MGMT_TEMPLATE.G_TMPL_COPY_ALL_WITH_RETAIN) OR (l_met_info.is_transposed = 1) OR (l_tmpl_policy_types(l_tmpl_ctr) = MGMT_GLOBAL.G_TYPE_POLICY) ) THEN IF EMDW_LOG.P_IS_DEBUG_SET THEN EMDW_LOG.DEBUG(l_proc_name || ' Case 2: Adding with new coll name ' || l_new_coll_name, G_MODULE_NAME) ; END IF ; -- Check for COLL_NAME in case of 2COLSQL NUM or 2COLSQL STR or Single Value UDM on target has -- same name as the COLL_NAME in the Template. We would like like to process such a metrics. IF (l_met_info.is_transposed = 1) THEN l_has_collection := does_target_has_collection( p_tgt_coll_name => l_tgt_coll_names, p_coll_name => l_tmpl_coll_names(l_tmpl_ctr)); END IF; -- Check to see if the policy assoc can be copied -- NEED to check is_tranposed and the continue with checking. -- We can copy only when target doesnot have a metric with same collection name. IF (l_has_collection = 0) THEN l_copy_assoc := can_copy( p_metric_info => l_met_info, p_src_object_guid => l_template_guid, p_src_object_type => p_template_object_type, p_dest_object_guid => l_target_guid, p_dest_object_type => MGMT_GLOBAL.G_OBJECT_TYPE_TARGET, p_coll_name => l_new_coll_name); IF (l_copy_assoc = 1) THEN EM_POLICY.copy_object_policy_assoc( p_src_object_guid => l_template_guid, p_src_object_type => p_template_object_type, p_dest_object_guid => l_template_copy_guid, p_dest_object_type => MGMT_GLOBAL.G_OBJECT_TYPE_TEMPLATE_COPY, p_policy_guid => l_tmpl_policy_guids(l_tmpl_ctr), p_policy_type => l_tmpl_policy_types(l_tmpl_ctr), p_src_coll_name => l_tmpl_coll_names(l_tmpl_ctr), p_dest_coll_name => l_new_coll_name, p_is_enabled => l_tmpl_enabled(l_tmpl_ctr), p_add_or_delete => l_tmpl_add_or_delete(l_tmpl_ctr)); END IF; -- If copy_assoc = 1 END IF; -- l_has_collection = 0 END IF; -- If copy_type = COPY_ALL END IF; -- If metric is valid l_tmpl_ctr := l_tmpl_ctr + 1; ELSIF (l_tmpl_policy_guids(l_tmpl_ctr) < l_tgt_policy_guids(l_tgt_ctr)) THEN IF EMDW_LOG.P_IS_DEBUG_SET THEN EMDW_LOG.DEBUG(l_proc_name || ' Case 3: Processing from template list.' || ' Policy guid =' || l_tmpl_policy_guids(l_tmpl_ctr) || ' Policy type =' || l_tmpl_policy_types(l_tmpl_ctr) || ' coll name =[' || l_tmpl_coll_names(l_tmpl_ctr) || ']', G_MODULE_NAME) ; END IF ; -- We have to consider following points before we add Metrics to the template copy clone. -- Check for COLL_NAME in case of 2COLSQL NUM or 2COLSQL STR or Single Value UDM on target has -- same name as the COLL_NAME in the Template. We would like like to process such a metrics. -- For Single Value and 2COL SQL UDM NUM/STR will have different METRIC_GUID. -- But can have same collection name. We have to stop such a secnario. -- Copy all configurations from template list to template copy list -- Verify that the metric is applicable to the target, EM_METRIC.get_metric_info_for_target(l_tmpl_metric_guids(l_tmpl_ctr), l_target_guid, l_met_info); IF (l_met_info.metric_cols.COUNT > 0) THEN IF EMDW_LOG.P_IS_DEBUG_SET THEN EMDW_LOG.DEBUG(l_proc_name || ' Case 3: Policy is applicable. Metric Name = ' || l_met_info.metric_name, G_MODULE_NAME) ; END IF ; -- Metric is applicable to the target, proceed with adding to the template copy -- If applicable, Get collection name l_new_coll_name := NVL(get_coll_name(l_met_info, l_target_guid), l_tmpl_coll_names(l_tmpl_ctr) ); -- Copy from template only for COPY-ALL case IF ( (p_copy_type = MGMT_TEMPLATE.G_TEMPLATE_COPY_ALL) OR (p_copy_type = MGMT_TEMPLATE.G_TMPL_COPY_ALL_WITH_RETAIN) OR (l_met_info.is_transposed = 1) OR (l_tmpl_policy_types(l_tmpl_ctr) = MGMT_GLOBAL.G_TYPE_POLICY) ) THEN IF EMDW_LOG.P_IS_DEBUG_SET THEN EMDW_LOG.DEBUG(l_proc_name || ' Case 3: Adding with new coll name ' || l_new_coll_name, G_MODULE_NAME) ; END IF ; -- Check for COLL_NAME in case of 2COLSQL NUM or 2COLSQL STR or Single Value UDM on target has -- same name as the COLL_NAME in the Template. We would like like to process such a metrics. IF (l_met_info.is_transposed = 1) THEN l_has_collection := does_target_has_collection( p_tgt_coll_name => l_tgt_coll_names, p_coll_name => l_tmpl_coll_names(l_tmpl_ctr)); END IF; -- Check to see if the policy assoc can be copied -- We can copy only when target doesnot have a metric with same collection name. IF (l_has_collection = 0) THEN l_copy_assoc := can_copy( p_metric_info => l_met_info, p_src_object_guid => l_template_guid, p_src_object_type => p_template_object_type, p_dest_object_guid => l_target_guid, p_dest_object_type => MGMT_GLOBAL.G_OBJECT_TYPE_TARGET, p_coll_name => l_new_coll_name); IF (l_copy_assoc = 1) THEN EM_POLICY.copy_object_policy_assoc( p_src_object_guid => l_template_guid, p_src_object_type => p_template_object_type, p_dest_object_guid => l_template_copy_guid, p_dest_object_type => MGMT_GLOBAL.G_OBJECT_TYPE_TEMPLATE_COPY, p_policy_guid => l_tmpl_policy_guids(l_tmpl_ctr), p_policy_type => l_tmpl_policy_types(l_tmpl_ctr), p_src_coll_name => l_tmpl_coll_names(l_tmpl_ctr), p_dest_coll_name => l_new_coll_name, p_is_enabled => l_tmpl_enabled(l_tmpl_ctr), p_add_or_delete => l_tmpl_add_or_delete(l_tmpl_ctr)); END IF; -- copy_assoc = 1 END IF; -- l_has_collection = 0 END IF; -- If copy type is COPY_ALL END IF; -- metric is valid l_tmpl_ctr := l_tmpl_ctr + 1; ELSIF (l_tmpl_policy_guids(l_tmpl_ctr) > l_tgt_policy_guids(l_tgt_ctr)) THEN -- Copy all configurations from target list to template copy list IF EMDW_LOG.P_IS_DEBUG_SET THEN EMDW_LOG.DEBUG(l_proc_name || ' Case 4: Processing from target list. ' || ' Metric guid =' || l_tgt_policy_guids(l_tgt_ctr) || ' coll name =[' || l_tgt_coll_names(l_tgt_ctr) || ']', G_MODULE_NAME) ; END IF ; EM_POLICY.copy_object_policy_assoc( p_src_object_guid => l_target_guid, p_src_object_type => MGMT_GLOBAL.G_OBJECT_TYPE_TARGET, p_dest_object_guid => l_template_copy_guid, p_dest_object_type => MGMT_GLOBAL.G_OBJECT_TYPE_TEMPLATE_COPY, p_policy_guid => l_tgt_policy_guids(l_tgt_ctr), p_policy_type => l_tgt_policy_types(l_tgt_ctr), p_src_coll_name => l_tgt_coll_names(l_tgt_ctr), p_is_enabled => l_tgt_enabled(l_tgt_ctr)); l_tgt_ctr := l_tgt_ctr + 1; ELSE -- Here, we have a case when Target and Template both havse same Policy GUIDs. -- This is where Template Override Flag is used. -- Options for "Metrics with multiple thresholds" is used. -- UDMs will have same name by different COLL_NAME. -- We have to consider following points before we add Metrics to the template copy clone. -- Check for COLL_NAME in case of 2COLSQL NUM or 2COLSQL STR or Single Value UDM on target has -- same name as the COLL_NAME in the Template. We would not like to process such a metrics. -- For Single Value and 2COL SQL UDM NUM/STR will have different METRIC_GUID. -- But can have same collection name. We have to stop such a secnario. IF EMDW_LOG.P_IS_DEBUG_SET THEN EMDW_LOG.DEBUG(l_proc_name || ' Case 5: Merging key configurations for policy. ' || ' Policy guid =' || l_tgt_policy_guids(l_tgt_ctr) || ' Policy type =' || l_tgt_policy_types(l_tgt_ctr) || ' tgt coll name =[' || l_tgt_coll_names(l_tgt_ctr) || ']' || ' tmpl coll name =[' || l_tmpl_coll_names(l_tmpl_ctr) || ']', G_MODULE_NAME) ; END IF ; -- Actually, there is no need to verify that the metric/collection is -- applicable to the target, As the target already had this collection, -- But we do the following to get the collection name EM_METRIC.get_metric_info_for_target(l_tmpl_metric_guids(l_tmpl_ctr), l_target_guid, l_met_info); IF (l_met_info.metric_cols.COUNT > 0) THEN IF (l_met_info.is_transposed = MGMT_GLOBAL.G_TRUE) THEN IF (l_tgt_coll_names(l_tgt_ctr) < l_tmpl_coll_names(l_tmpl_ctr)) THEN IF EMDW_LOG.P_IS_DEBUG_SET THEN EMDW_LOG.DEBUG(l_proc_name || ' Case 51: Transposed metric, Processing from target' || ' tgt coll name =[' || l_tgt_coll_names(l_tgt_ctr) || ']' || ' tmpl coll name =[' || l_tmpl_coll_names(l_tmpl_ctr) || ']', G_MODULE_NAME) ; END IF ; EM_POLICY.copy_object_policy_assoc( p_src_object_guid => l_target_guid, p_src_object_type => MGMT_GLOBAL.G_OBJECT_TYPE_TARGET, p_dest_object_guid => l_template_copy_guid, p_dest_object_type => MGMT_GLOBAL.G_OBJECT_TYPE_TEMPLATE_COPY, p_policy_guid => l_tgt_policy_guids(l_tgt_ctr), p_policy_type => l_tgt_policy_types(l_tgt_ctr), p_src_coll_name => l_tgt_coll_names(l_tgt_ctr), p_is_enabled => l_tgt_enabled(l_tgt_ctr)); l_tgt_ctr := l_tgt_ctr + 1; ELSIF (l_tgt_coll_names(l_tgt_ctr) > l_tmpl_coll_names(l_tmpl_ctr)) THEN IF EMDW_LOG.P_IS_DEBUG_SET THEN EMDW_LOG.DEBUG(l_proc_name || ' Case 52: Transposed metric, Processing from template' || ' tgt coll name =[' || l_tgt_coll_names(l_tgt_ctr) || ']' || ' tmpl coll name =[' || l_tmpl_coll_names(l_tmpl_ctr) || ']', G_MODULE_NAME) ; END IF ; -- Check if Any other UDM has Same collection Name. -- Check for COLL_NAME in case of 2COLSQL NUM or 2COLSQL STR or Single Value UDM on target has -- same name as the COLL_NAME in the Template. We would like like to process such a metrics. IF (l_met_info.is_transposed = 1) THEN l_has_collection := does_target_has_collection( p_tgt_coll_name => l_tgt_coll_names, p_coll_name => l_tmpl_coll_names(l_tmpl_ctr)); END IF; IF (l_has_collection = 0) THEN EM_POLICY.copy_object_policy_assoc( p_src_object_guid => l_template_guid, p_src_object_type => p_template_object_type, p_dest_object_guid => l_template_copy_guid, p_dest_object_type => MGMT_GLOBAL.G_OBJECT_TYPE_TEMPLATE_COPY, p_policy_guid => l_tmpl_policy_guids(l_tmpl_ctr), p_policy_type => l_tmpl_policy_types(l_tmpl_ctr), p_src_coll_name => l_tmpl_coll_names(l_tmpl_ctr), p_dest_coll_name => l_tmpl_coll_names(l_tmpl_ctr), p_is_enabled => l_tmpl_enabled(l_tmpl_ctr), p_add_or_delete => l_tmpl_add_or_delete(l_tmpl_ctr)); END IF; l_tmpl_ctr := l_tmpl_ctr + 1; ELSE -- Same Policy GUID and Same COLL_NAME. Thus, a UDM of same type is present in both -- target and template. IF (l_tmpl_add_or_delete(l_tmpl_ctr) = MGMT_GLOBAL.G_FALSE) THEN -- Check to see if the collection can be copied l_copy_assoc := can_copy( p_metric_info => l_met_info, p_src_object_guid => l_template_guid, p_src_object_type => p_template_object_type, p_dest_object_guid => l_target_guid, p_dest_object_type => MGMT_GLOBAL.G_OBJECT_TYPE_TARGET, p_coll_name => l_tgt_coll_names(l_tgt_ctr)); IF (l_copy_assoc = 1) THEN IF EMDW_LOG.P_IS_DEBUG_SET THEN EMDW_LOG.DEBUG(l_proc_name || ' Case 531: Transposed metric, Same collection UDM type, Merging keys' || ' tgt coll name =[' || l_tgt_coll_names(l_tgt_ctr) || ']' || ' tmpl coll name =[' || l_tmpl_coll_names(l_tmpl_ctr) || ']', G_MODULE_NAME) ; END IF ; merge_key_cfgs( p_src1_object_guid => l_target_guid, p_src1_object_type => MGMT_GLOBAL.G_OBJECT_TYPE_TARGET, p_src1_coll_name => l_tgt_coll_names(l_tgt_ctr), p_src2_object_guid => l_template_guid, p_src2_object_type => p_template_object_type, p_src2_coll_name => l_tmpl_coll_names(l_tmpl_ctr), p_dest_object_guid => l_template_copy_guid, p_dest_object_type => MGMT_GLOBAL.G_OBJECT_TYPE_TEMPLATE_COPY, p_dest_coll_name => l_tmpl_coll_names(l_tmpl_ctr), p_policy_guid => l_tmpl_policy_guids(l_tmpl_ctr), p_policy_type => l_tmpl_policy_types(l_tmpl_ctr), p_is_enabled => l_tmpl_enabled(l_tmpl_ctr), p_copy_type => p_copy_type, p_metric_info => l_met_info, p_ca_creds => p_ca_creds, p_add_or_delete => l_tmpl_add_or_delete(l_tmpl_ctr)); ELSE IF EMDW_LOG.P_IS_DEBUG_SET THEN EMDW_LOG.DEBUG(l_proc_name || ' Case 532: Transposed metric, Same collection, but different udm types. Copying from target. ' || ' tgt coll name =[' || l_tgt_coll_names(l_tgt_ctr) || ']' || ' tmpl coll name =[' || l_tmpl_coll_names(l_tmpl_ctr) || ']', G_MODULE_NAME) ; END IF ; EM_POLICY.copy_object_policy_assoc( p_src_object_guid => l_target_guid, p_src_object_type => MGMT_GLOBAL.G_OBJECT_TYPE_TARGET, p_dest_object_guid => l_template_copy_guid, p_dest_object_type => MGMT_GLOBAL.G_OBJECT_TYPE_TEMPLATE_COPY, p_policy_guid => l_tgt_policy_guids(l_tgt_ctr), p_policy_type => l_tgt_policy_types(l_tgt_ctr), p_src_coll_name => l_tgt_coll_names(l_tgt_ctr), p_is_enabled => l_tgt_enabled(l_tgt_ctr)); END IF; -- Can Copy check ELSE -- add_or_delete = 1. Retain the target existing settings as of Now. EM_POLICY.copy_object_policy_assoc( p_src_object_guid => l_target_guid, p_src_object_type => MGMT_GLOBAL.G_OBJECT_TYPE_TARGET, p_dest_object_guid => l_template_copy_guid, p_dest_object_type => MGMT_GLOBAL.G_OBJECT_TYPE_TEMPLATE_COPY, p_policy_guid => l_tgt_policy_guids(l_tgt_ctr), p_policy_type => l_tgt_policy_types(l_tgt_ctr), p_src_coll_name => l_tgt_coll_names(l_tgt_ctr), p_is_enabled => l_tmpl_enabled(l_tmpl_ctr), p_add_or_delete => l_tmpl_add_or_delete(l_tmpl_ctr)); END IF; l_tgt_ctr := l_tgt_ctr + 1; l_tmpl_ctr := l_tmpl_ctr + 1; END IF; -- If tmpl coll_name < tgt coll_name ELSIF (l_tmpl_policy_types(l_tmpl_ctr) = MGMT_GLOBAL.G_TYPE_POLICY) THEN IF EMDW_LOG.P_IS_DEBUG_SET THEN EMDW_LOG.DEBUG(l_proc_name || ' Case 54: Non-transposed metric, Policy type Merging keys' || ' tgt coll name =[' || l_tgt_coll_names(l_tgt_ctr) || ']' || ' tmpl coll name =[' || l_tmpl_coll_names(l_tmpl_ctr) || ']', G_MODULE_NAME) ; END IF ; -- Get prevent override flag. -- For policies, preventoverride of the policy is stored as the -- prevent override of the default keycfg BEGIN SELECT prevent_override INTO l_tgt_prevent_override FROM mgmt_policy_assoc_cfg WHERE object_guid = l_target_guid AND policy_guid = l_tgt_policy_guids(l_tgt_ctr) AND coll_name = l_tgt_coll_names(l_tgt_ctr) AND key_value = ' ' AND key_operator = 0; EXCEPTION WHEN OTHERS THEN l_tgt_prevent_override := 0; END; IF (l_tgt_prevent_override = MGMT_GLOBAL.G_TRUE) THEN -- Dont override, copy from target IF EMDW_LOG.P_IS_DEBUG_SET THEN EMDW_LOG.DEBUG(l_proc_name || ' Case 541: Non-transposed metric, Policy type . Prevent override . Copy from target' || ' tgt coll name =[' || l_tgt_coll_names(l_tgt_ctr) || ']' || ' tmpl coll name =[' || l_tmpl_coll_names(l_tmpl_ctr) || ']', G_MODULE_NAME) ; END IF ; EM_POLICY.copy_object_policy_assoc( p_src_object_guid => l_target_guid, p_src_object_type => MGMT_GLOBAL.G_OBJECT_TYPE_TARGET, p_dest_object_guid => l_template_copy_guid, p_dest_object_type => MGMT_GLOBAL.G_OBJECT_TYPE_TEMPLATE_COPY, p_policy_guid => l_tgt_policy_guids(l_tgt_ctr), p_policy_type => l_tgt_policy_types(l_tgt_ctr), p_src_coll_name => l_tgt_coll_names(l_tgt_ctr), p_is_enabled => l_tgt_enabled(l_tgt_ctr)); ELSE -- Merge the keys IF EMDW_LOG.P_IS_DEBUG_SET THEN EMDW_LOG.DEBUG(l_proc_name || ' Case 542: Non-transposed metric, Policy type Merging keys' || ' tgt coll name =[' || l_tgt_coll_names(l_tgt_ctr) || ']' || ' tmpl coll name =[' || l_tmpl_coll_names(l_tmpl_ctr) || ']', G_MODULE_NAME) ; END IF ; l_new_coll_name := NVL(get_coll_name(l_met_info, l_target_guid), l_tmpl_coll_names(l_tmpl_ctr) ); merge_key_cfgs( p_src1_object_guid => l_target_guid, p_src1_object_type => MGMT_GLOBAL.G_OBJECT_TYPE_TARGET, p_src1_coll_name => l_tgt_coll_names(l_tgt_ctr), p_src2_object_guid => l_template_guid, p_src2_object_type => p_template_object_type, p_src2_coll_name => l_tmpl_coll_names(l_tmpl_ctr), p_dest_object_guid => l_template_copy_guid, p_dest_object_type => MGMT_GLOBAL.G_OBJECT_TYPE_TEMPLATE_COPY, p_dest_coll_name => l_new_coll_name, p_policy_guid => l_tmpl_policy_guids(l_tmpl_ctr), p_policy_type => l_tmpl_policy_types(l_tmpl_ctr), p_is_enabled => l_tmpl_enabled(l_tmpl_ctr), p_copy_type => p_copy_type, p_metric_info => l_met_info, p_ca_creds => p_ca_creds, p_add_or_delete => l_tmpl_add_or_delete(l_tmpl_ctr)); END IF; -- If tgt_prevent_override = true l_tgt_ctr := l_tgt_ctr + 1; l_tmpl_ctr := l_tmpl_ctr + 1; ELSE IF EMDW_LOG.P_IS_DEBUG_SET THEN EMDW_LOG.DEBUG(l_proc_name || ' Case 55: Non-transposed metric, Non -policy, Merging keys' || ' tgt coll name =[' || l_tgt_coll_names(l_tgt_ctr) || ']' || ' tmpl coll name =[' || l_tmpl_coll_names(l_tmpl_ctr) || ']', G_MODULE_NAME) ; END IF ; -- Both target and template have same policy guid -- The policy guid is for a non-transposed, metric column -- Use target collection name l_new_coll_name := l_tgt_coll_names(l_tgt_ctr); merge_key_cfgs( p_src1_object_guid => l_target_guid, p_src1_object_type => MGMT_GLOBAL.G_OBJECT_TYPE_TARGET, p_src1_coll_name => l_tgt_coll_names(l_tgt_ctr), p_src2_object_guid => l_template_guid, p_src2_object_type => p_template_object_type, p_src2_coll_name => l_tmpl_coll_names(l_tmpl_ctr), p_dest_object_guid => l_template_copy_guid, p_dest_object_type => MGMT_GLOBAL.G_OBJECT_TYPE_TEMPLATE_COPY, p_dest_coll_name => l_new_coll_name, p_policy_guid => l_tmpl_policy_guids(l_tmpl_ctr), p_policy_type => l_tmpl_policy_types(l_tmpl_ctr), p_is_enabled => l_tmpl_enabled(l_tmpl_ctr), p_copy_type => p_copy_type, p_metric_info => l_met_info, p_ca_creds => p_ca_creds, p_add_or_delete => l_tmpl_add_or_delete(l_tmpl_ctr)); l_tgt_ctr := l_tgt_ctr + 1; l_tmpl_ctr := l_tmpl_ctr + 1; END IF; -- If l_met_info.is_transposed = TRUE ELSE IF EMDW_LOG.P_IS_DEBUG_SET THEN EMDW_LOG.DEBUG(l_proc_name || ' Case 55: Metric not applicable ' || ' tgt coll name =[' || l_tgt_coll_names(l_tgt_ctr) || ']' || ' tmpl coll name =[' || l_tmpl_coll_names(l_tmpl_ctr) || ']', G_MODULE_NAME) ; END IF ; -- Metric not applicable l_tmpl_ctr := l_tmpl_ctr + 1; l_tgt_ctr := l_tgt_ctr + 1; END IF; -- l_met_info.metric_columns.COUNT > 0 END IF; -- END LOOP; -- While loop END create_template_copy; -- Creates template copy from clone FUNCTION create_template_copy_clone ( p_target_type IN VARCHAR2, p_template_clone_guid IN RAW, p_target_name IN VARCHAR2 DEFAULT ' ', p_copy_req_guid IN RAW) RETURN RAW IS l_template_copy_guid MGMT_TEMPLATE_COPIES.template_copy_guid%TYPE; l_copy_type MGMT_TEMPLATE_COPIES.copy_type%TYPE; l_target_guid MGMT_TARGETS.target_guid%TYPE; l_template_guid MGMT_TEMPLATES.template_guid%TYPE; l_current_user mgmt_created_users.user_name%TYPE; l_proc_name VARCHAR2(32) := 'create_template_clone_copy: '; l_cnt_template_copy_guid NUMBER; BEGIN l_current_user := MGMT_USER.get_current_em_user; IF EMDW_LOG.P_IS_DEBUG_SET THEN EMDW_LOG.DEBUG(l_proc_name || ' Enter ' || ' Target type = [' || p_target_type || '] Template Clone Guid = [' || p_template_clone_guid || '] Target Name = [' || p_target_name || '] Copy Req Guid = [' || p_copy_req_guid || ']', G_MODULE_NAME); END IF ; IF (NVL(p_target_name, ' ') = ' ') THEN l_target_guid := MGMT_GLOBAL.G_ALL_ZERO_GUID; ELSE l_target_guid := MGMT_TARGET.get_target_guid( target_type_in => p_target_type, target_name_in => p_target_name); END IF; SELECT template_guid, copy_type INTO l_template_guid, l_copy_type FROM mgmt_template_copies WHERE template_copy_guid = p_template_clone_guid; l_template_copy_guid := generate_template_copy_guid( p_target_type, RAWTOHEX(l_template_guid), p_target_name, p_copy_req_guid); IF EMDW_LOG.P_IS_DEBUG_SET THEN EMDW_LOG.DEBUG(l_proc_name || 'Storing template copy guid = ' || l_template_copy_guid || ' template clone guid = ' || p_template_clone_guid || ' target guid = ' || l_target_guid, G_MODULE_NAME); END IF ; -- Bug Fix 5197525.Handled ORA-0001 for already existing l_template_copy_guid. SELECT count(*) INTO l_cnt_template_copy_guid FROM mgmt_template_copies WHERE template_copy_guid = l_template_copy_guid; -- Create new Template Copy only if not existing. IF l_cnt_template_copy_guid >= 1 THEN RETURN l_template_copy_guid; END IF; BEGIN INSERT INTO mgmt_template_copies (template_copy_guid, template_guid, target_guid, copy_req_guid, copy_type, created_date, created_by) VALUES (l_template_copy_guid, l_template_guid, l_target_guid, p_copy_req_guid, l_copy_type, SYSDATE, l_current_user); EXCEPTION WHEN DUP_VAL_ON_INDEX THEN -- return to caller as template copy already created for target. RETURN l_template_copy_guid; END; -- Update object guid of collection_template_creds with new template_copy_guid -- for the current target MGMT_CREDENTIAL.upd_collection_template_creds(p_template_clone_guid, l_template_copy_guid, MGMT_CREDENTIAL.OBJECT_TYPE_TEMPLATE_COPY, l_target_guid); -- Create template copy settings create_template_copy(l_target_guid, p_template_clone_guid, MGMT_GLOBAL.G_OBJECT_TYPE_TEMPLATE_COPY, l_template_copy_guid, l_copy_type); IF EMDW_LOG.P_IS_DEBUG_SET THEN EMDW_LOG.DEBUG(l_proc_name || ' Normal exit. Returing copy_guid = ' || l_template_copy_guid, G_MODULE_NAME); END IF ; RETURN l_template_copy_guid; END create_template_copy_clone; -- Creates template clone FUNCTION create_template_clone ( p_target_type IN VARCHAR2, p_template_name IN VARCHAR2, p_target_name IN VARCHAR2 DEFAULT ' ', p_copy_req_guid IN RAW, p_copy_type IN NUMBER, p_ca_creds IN MGMT_MNTR_CA_ARRAY DEFAULT NULL, p_coll_creds IN MGMT_COLLECTION_CRED_ARRAY DEFAULT NULL) RETURN RAW IS l_template_copy_guid MGMT_TEMPLATE_COPIES.template_copy_guid%TYPE; l_template_guid MGMT_TEMPLATES.template_guid%TYPE; l_target_guid MGMT_TARGETS.target_guid%TYPE; l_current_user mgmt_created_users.user_name%TYPE; l_metric_list MGMT_MNTR_METRIC_ARRAY; l_policy_list MGMT_MNTR_POLICY_ARRAY; l_collection_list MGMT_MNTR_COLLECTION_ARRAY; l_metric_guid mgmt_metrics.metric_guid%TYPE; l_policy_guid mgmt_policies.policy_guid%TYPE; l_template_metric MGMT_MNTR_METRIC; l_template_policy MGMT_MNTR_POLICY; l_job_id mgmt_job.job_id%TYPE; l_proc_name VARCHAR2(32) := 'create_template_clone: '; BEGIN l_current_user := MGMT_USER.get_current_em_user; IF EMDW_LOG.P_IS_DEBUG_SET THEN EMDW_LOG.DEBUG(l_proc_name || ' Enter ' || ' Target type = [' || p_target_type || '] Template Name = [' || p_template_name || '] Target Name = [' || p_target_name || '] Copy Req Guid = [' || p_copy_req_guid || '] Copy Type = [' || p_copy_type || ']', G_MODULE_NAME); END IF ; l_template_guid := get_template_guid(p_target_type, p_template_name); get_template_settings( p_target_type => p_target_type, p_template_name => p_template_name, p_metric_list => l_metric_list, p_policy_list => l_policy_list, p_collection_list => l_collection_list); IF (NVL(p_target_name, ' ') = ' ') THEN l_target_guid := MGMT_GLOBAL.G_ALL_ZERO_GUID; ELSE l_target_guid := MGMT_TARGET.get_target_guid( target_type_in => p_target_type, target_name_in => p_target_name); END IF; l_template_copy_guid := generate_template_copy_guid( p_target_type, p_template_name, p_target_name, p_copy_req_guid); IF EMDW_LOG.P_IS_DEBUG_SET THEN EMDW_LOG.DEBUG(l_proc_name || 'Storing template copy guid = ' || l_template_copy_guid || ' template guid = ' || l_template_guid || ' target guid = ' || l_target_guid, G_MODULE_NAME); END IF ; INSERT INTO mgmt_template_copies (template_copy_guid, template_guid, target_guid, copy_req_guid, copy_type, created_date, created_by) VALUES (l_template_copy_guid, l_template_guid, l_target_guid, p_copy_req_guid, p_copy_type, SYSDATE, l_current_user); -- Create template_clone CAs from template CAs FOR tmpl_cas IN (SELECT crit_action_job_id, warn_action_job_id, info_action_job_id FROM mgmt_policy_assoc_cfg WHERE object_guid = l_template_guid ORDER BY policy_guid, coll_name, eval_order) LOOP -- copy_ca_id ( l_job_id := EM_POLICY.copy_ca_id( l_template_guid, MGMT_GLOBAL.G_OBJECT_TYPE_TEMPLATE, l_template_copy_guid, MGMT_GLOBAL.G_OBJECT_TYPE_TEMPLATE_COPY, tmpl_cas.info_action_job_id, NULL); l_job_id := EM_POLICY.copy_ca_id( l_template_guid, MGMT_GLOBAL.G_OBJECT_TYPE_TEMPLATE, l_template_copy_guid, MGMT_GLOBAL.G_OBJECT_TYPE_TEMPLATE_COPY, tmpl_cas.warn_action_job_id, NULL); l_job_id := EM_POLICY.copy_ca_id( l_template_guid, MGMT_GLOBAL.G_OBJECT_TYPE_TEMPLATE, l_template_copy_guid, MGMT_GLOBAL.G_OBJECT_TYPE_TEMPLATE_COPY, tmpl_cas.crit_action_job_id, NULL); END LOOP; -- Save the collection credentials IF p_coll_creds IS NOT NULL THEN MGMT_CREDENTIAL.set_collection_template_creds(p_coll_creds, l_template_copy_guid, MGMT_CREDENTIAL.OBJECT_TYPE_TEMPLATE_COPY); END IF; -- Process p_collection_list EM_COLL_UTIL.add_object_collections( p_target_type => p_target_type, p_object_guid => l_template_copy_guid, p_object_type => MGMT_GLOBAL.G_OBJECT_TYPE_TEMPLATE_COPY, p_coll_list => l_collection_list); -- Process metric_list IF ( (l_metric_list IS NOT NULL) AND (l_metric_list.COUNT > 0) )THEN FOR met_ctr IN l_metric_list.FIRST..l_metric_list.LAST LOOP l_template_metric := l_metric_list(met_ctr); l_metric_guid := MGMT_METRIC.get_metric_guid(p_target_type, l_template_metric.metric_name, l_template_metric.metric_column); IF EMDW_LOG.P_IS_DEBUG_SET THEN EMDW_LOG.DEBUG(l_proc_name || ' Adding template assoc for metric ' || ' type = ' || p_target_type || ' metric_name ' || l_template_metric.metric_name || ' metric_colmn ' || l_template_metric.metric_column, G_MODULE_NAME) ; END IF ; EM_POLICY.add_object_policy_assoc( p_object_guid => l_template_copy_guid, p_policy_guid => l_metric_guid, p_coll_name => l_template_metric.coll_name, p_object_type => MGMT_GLOBAL.G_OBJECT_TYPE_TEMPLATE_COPY, p_policy_type => MGMT_GLOBAL.G_TYPE_THRESHOLD_METRIC, p_is_enabled => l_template_metric.is_enabled, p_policy_val_list => l_template_metric.key_val_list, p_add_or_delete => l_template_metric.add_or_delete); END LOOP; END IF; -- Process metric_list IF ( (l_policy_list IS NOT NULL) AND (l_policy_list.COUNT > 0) )THEN FOR pol_ctr IN l_policy_list.FIRST..l_policy_list.LAST LOOP l_template_policy := l_policy_list(pol_ctr); l_policy_guid := MGMT_POLICY.get_policy_guid(p_target_type, l_template_policy.policy_name); IF EMDW_LOG.P_IS_DEBUG_SET THEN EMDW_LOG.DEBUG(l_proc_name || ' Adding template assoc for policy ' || ' type = ' || p_target_type || ' policy_name ' || l_template_policy.policy_name, G_MODULE_NAME) ; END IF ; EM_POLICY.add_object_policy_assoc( p_object_guid => l_template_copy_guid, p_policy_guid => l_policy_guid, p_coll_name => l_template_policy.coll_name, p_object_type => MGMT_GLOBAL.G_OBJECT_TYPE_TEMPLATE_COPY, p_policy_type => MGMT_GLOBAL.G_TYPE_POLICY, p_is_enabled => l_template_policy.is_enabled, p_policy_val_list => l_template_policy.key_val_list); END LOOP; END IF; IF EMDW_LOG.P_IS_DEBUG_SET THEN EMDW_LOG.DEBUG(l_proc_name || ' Normal exit. Returing copy_guid = ' || l_template_copy_guid, G_MODULE_NAME); END IF ; RETURN l_template_copy_guid; END create_template_clone; -- Deletes template copy PROCEDURE delete_template_copy ( p_target_type IN VARCHAR2, p_template_name IN VARCHAR2, p_target_name IN VARCHAR2 DEFAULT ' ', p_copy_req_guid IN RAW) IS l_template_copy_guid MGMT_TEMPLATE_COPIES.template_copy_guid%TYPE; BEGIN l_template_copy_guid := get_template_copy_guid( p_target_type, p_template_name, p_target_name, p_copy_req_guid); delete_template_copy(l_template_copy_guid); END delete_template_copy; -- Deletes template copy PROCEDURE delete_template_copy (p_template_copy_guid IN RAW) IS BEGIN -- Remove collections. EM_COLL_UTIL.remove_all_object_collections(p_template_copy_guid, MGMT_GLOBAL.G_OBJECT_TYPE_TEMPLATE_COPY); -- Remove template metrics and policies FOR policy_rec IN (SELECT policy_guid FROM mgmt_policy_assoc WHERE object_guid = p_template_copy_guid) LOOP -- Remove template copy associations, and decrement ctr for any related CAs EM_POLICY.remove_object_policy_assoc( p_object_guid => p_template_copy_guid, p_policy_guid => policy_rec.policy_guid, p_coll_name => NULL, p_remove_ca_assoc => MGMT_GLOBAL.G_TRUE); END LOOP; -- Delete composite keys associated with template DELETE FROM mgmt_metrics_composite_keys WHERE target_guid = p_template_copy_guid; -- Remove CAs MGMT_JOB_ENGINE.delete_template_cas(p_template_copy_guid, true); -- TODO: Remove collection credentials -- The API should be changed to accept only object_guid and object_type -- MGMT_CREDENTIAL.delete_coll_template_creds(p_template_copy_guid, -- MGMT_CREDENTIAL.OBJECT_TYPE_TEMPLATE_COPY); DELETE FROM mgmt_template_copies WHERE template_copy_guid = p_template_copy_guid; END delete_template_copy; -- Save the template copy settings to target PROCEDURE save_template_copy_to_target ( p_template_copy_guid IN RAW, p_target_guid IN RAW) IS l_metric_list MGMT_MNTR_METRIC_ARRAY; l_policy_list MGMT_MNTR_POLICY_ARRAY; l_collection_list MGMT_MNTR_COLLECTION_ARRAY; l_target_name mgmt_targets.target_name%TYPE; l_target_type mgmt_targets.target_type%TYPE; l_clear_msg mgmt_violations.message%TYPE; l_job_id mgmt_job.job_id%TYPE; l_proc_name VARCHAR2(32) := 'save_template_copy_to_target'; BEGIN IF EMDW_LOG.P_IS_DEBUG_SET THEN EMDW_LOG.DEBUG(l_proc_name || 'Enter', G_MODULE_NAME) ; EMDW_LOG.DEBUG(l_proc_name || ' Template guid = [' || p_template_copy_guid || ']' || ' Target guid = [' || p_target_guid || ']', G_MODULE_NAME); END IF ; -- Get template copy settings EM_TEMPLATE.get_object_settings( p_object_guid => p_template_copy_guid, p_object_type => MGMT_GLOBAL.G_OBJECT_TYPE_TEMPLATE_COPY, p_metric_list => l_metric_list, p_policy_list => l_policy_list, p_coll_list => l_collection_list); -- Get target_name and type SELECT target_name, target_type INTO l_target_name, l_target_type FROM MGMT_TARGETS WHERE target_guid = p_target_guid; -- Create target CAs from template-copy CAs FOR tc_cas IN (SELECT crit_action_job_id, warn_action_job_id, info_action_job_id FROM mgmt_policy_assoc_cfg WHERE object_guid = p_template_copy_guid ORDER BY policy_guid, coll_name, eval_order) LOOP -- copy_ca_id ( l_job_id := EM_POLICY.copy_ca_id( p_template_copy_guid, MGMT_GLOBAL.G_OBJECT_TYPE_TEMPLATE_COPY, p_target_guid, MGMT_GLOBAL.G_OBJECT_TYPE_TARGET, tc_cas.info_action_job_id, NULL); l_job_id := EM_POLICY.copy_ca_id( p_template_copy_guid, MGMT_GLOBAL.G_OBJECT_TYPE_TEMPLATE_COPY, p_target_guid, MGMT_GLOBAL.G_OBJECT_TYPE_TARGET, tc_cas.warn_action_job_id, NULL); l_job_id := EM_POLICY.copy_ca_id( p_template_copy_guid, MGMT_GLOBAL.G_OBJECT_TYPE_TEMPLATE_COPY, p_target_guid, MGMT_GLOBAL.G_OBJECT_TYPE_TARGET, tc_cas.crit_action_job_id, NULL); END LOOP; -- Save settings BEGIN MGMT_MONITORING.save_settings( p_target_type => l_target_type, p_target_name => l_target_name, p_metric_list => l_metric_list, p_policy_list => l_policy_list, p_collection_list => l_collection_list); EXCEPTION WHEN MGMT_GLOBAL.metric_settings_lock_busy THEN IF EMDW_LOG.P_IS_DEBUG_SET THEN EMDW_LOG.DEBUG(l_proc_name || 'Apply operation failed due to concurrent updates of this target''s settings by ' || 'another administrator or by Enterprise Manager''s background operations. ' || 'Apply operation will automatically be retried.', G_MODULE_NAME); END IF ; raise_application_error(MGMT_GLOBAL.METRIC_SETTINGS_LOCK_BUSY_ERR, 'Apply operation failed due to concurrent updates of this target''s settings by ' || 'another administrator or by Enterprise Manager''s background operations. ' || 'Apply operation will automatically be retried.'); END; -- Apply collection credentials MGMT_CREDENTIAL.apply_template_copy_coll_creds(p_template_copy_guid, p_target_guid); END save_template_copy_to_target; -- -- PROCEDURE : get_user_templates -- -- PURPOSE -- -- this is a callback which will be registered to the user_model pkg -- user_model pkg will call this procedure to get a list of templets which the -- user has -- -- PARAMETERS -- -- user_name_in - name of the user -- user_objects_out - list of templets will be appended to user_objects_out -- type_in - type of user model callback -- -- NOTES -- PROCEDURE get_user_templates(user_name_in IN VARCHAR2, user_objects_out OUT MGMT_USER_OBJECTS, type_in IN NUMBER) IS l_user_name VARCHAR2(256):= UPPER(TRIM(user_name_in)); i INTEGER := 0; l_user_templates MGMT_USER_OBJECTS := MGMT_USER_OBJECTS(); CURSOR c_templates IS SELECT template_name FROM MGMT_TEMPLATES WHERE owner=l_user_name; BEGIN FOR c IN c_templates LOOP l_user_templates.extend(1); i := i + 1; l_user_templates(i) := MGMT_USER_OBJECT(MGMT_USER.USER_OBJECT_TEMPLATE, c.template_name, null, MGMT_USER.SYNC_DROP_OBJECT); END LOOP; user_objects_out := l_user_templates; END; -- -- PROCEDURE : drop_user_templates -- -- PURPOSE -- -- this is a callback which will be registered to the user_model pkg -- user_model pkg will call this procedure to drop the templets -- owned by a user. -- -- PARAMETERS -- -- user_name_in - name of the user -- type_in - type of user model callback -- -- NOTES -- PROCEDURE drop_user_templates(user_name_in IN VARCHAR2, type_in IN NUMBER) IS l_user_name VARCHAR2(256):= UPPER(TRIM(user_name_in)); CURSOR c_templates IS SELECT target_type,template_name FROM MGMT_TEMPLATES WHERE owner=l_user_name; BEGIN FOR c IN c_templates LOOP BEGIN delete_template(c.target_type,c.template_name); EXCEPTION WHEN OTHERS THEN mgmt_log.log_error(MGMT_USER.USERMODEL_MODULE_NAME, MGMT_GLOBAL.CALLBACK_FAILED_ERR, 'DROP_USER_TEMPLATE ' || l_user_name || ' : ' || c.target_type || ' : ' || c.template_name || ' : ' || SQLERRM); END; END LOOP; END; -- -- PROCEDURE : reassign_user_templates -- -- PURPOSE -- -- this is a callback which will be registered to the user_model pkg -- user_model pkg will call this procedure to reassign the templets -- owned by a user to the new user -- -- PARAMETERS -- -- user_name_in - name of the user -- new_user_name_in - the new user name -- type_in - type of user model callback -- -- NOTES -- PROCEDURE reassign_user_templates(user_name_in IN VARCHAR2, new_user_name_in IN VARCHAR2, type_in IN NUMBER) IS l_user_name VARCHAR2(256):= UPPER(TRIM(user_name_in)); l_new_user_name VARCHAR2(256):= UPPER(TRIM(new_user_name_in)); CURSOR c_templates IS SELECT template_guid FROM MGMT_TEMPLATES WHERE owner=l_user_name; BEGIN FOR c IN c_templates LOOP UPDATE MGMT_TEMPLATES SET owner = l_new_user_name WHERE template_guid = c.template_guid; MGMT_USER.GRANT_PRIV(l_new_user_name, MGMT_USER.FULL_TEMPLATE, c.template_guid); END LOOP; END; -- Purpose : To determine the template guid and applicable target type of template -- Input Parameters -- p_template_name : Name of template, for which the info is reqd -- Output Parameters -- p_template_guid : Template guid -- p_target_type : Target type to which the template is applicable to PROCEDURE get_template_info ( p_template_name IN VARCHAR2, p_template_guid OUT RAW, p_target_type OUT VARCHAR2 ) IS BEGIN BEGIN SELECT template_guid, target_type INTO p_template_guid, p_target_type FROM mgmt_templates WHERE template_name = p_template_name; EXCEPTION WHEN OTHERS THEN p_template_guid := '0'; p_target_type := 'N.A.'; END; END get_template_info; -- Private FUNCTION -- Purpose : To determine the flattened targets from within the composite which -- are not applicable to the metric template dur to disabled collection, etc -- Input Parameters -- p_comp_targets_list : List of composite targets and their types -- p_template_target_type : Target type which the template is applicable to -- Returning type : -- MGMT_TARGET_ARRAY type list which contains flattened targets and their types FUNCTION get_flattened_invalid_targets ( p_comp_targets_list IN MGMT_TARGET_ARRAY, p_template_target_type IN VARCHAR2 ) RETURN MGMT_TARGET_ARRAY IS p_flat_invalid_targets_list MGMT_TARGET_ARRAY := MGMT_TARGET_ARRAY(); l_flat_invalid_count NUMBER := 0; BEGIN FOR i in 1..p_comp_targets_list.COUNT LOOP FOR cursor_type IN ( SELECT DISTINCT target_name, target_type FROM mgmt_targets t WHERE target_guid IN ( SELECT assoc_target_guid FROM mgmt_flat_target_assoc, mgmt_targets WHERE is_membership = '1' AND source_target_guid IN ( SELECT target_guid FROM mgmt_targets WHERE target_name IN (p_comp_targets_list(i).target_name) ) AND assoc_target_guid = mgmt_targets.target_guid AND target_type = p_template_target_type ) AND ( t.emd_url IS NULL OR t.emd_url IN ( SELECT emd_url FROM mgmt_targets t2, mgmt_target_properties prop WHERE t2.target_type = 'oracle_emd' AND t2.emd_url = t.emd_url AND t2.target_guid = prop.target_guid AND prop.property_name = 'Version' AND prop.property_type = 'INSTANCE' AND prop.property_value NOT LIKE '10.1%' AND prop.property_value NOT LIKE '4.%' ) ) ) LOOP l_flat_invalid_count := l_flat_invalid_count +1; p_flat_invalid_targets_list.extend; p_flat_invalid_targets_list(l_flat_invalid_count) := MGMT_TARGET_OBJ(cursor_type.target_name,cursor_type.target_type); END LOOP; END LOOP; RETURN p_flat_invalid_targets_list; END get_flattened_invalid_targets; -- Private FUNCTION -- Purpose : To determine the flattened targets from within the composite which -- are applicable to the metric template -- Input Parameters -- p_comp_targets_list : List of composite targets and their types -- p_template_target_type : Target type which the template is applicable to -- p_mode : 1 refers to mode in which collection is disabled, etc -- others fall in normal category -- Output Parameters -- p_array_out : List of targets which are not applicable due to disabled -- collection,etc -- Returning type : -- MGMT_TARGET_ARRAY type list which contains flattened targets and their types FUNCTION get_flattened_targets ( p_comp_targets_list IN MGMT_TARGET_ARRAY, p_template_target_type IN VARCHAR2, p_mode IN VARCHAR2 DEFAULT NULL, p_array_out OUT MGMT_TARGET_ARRAY ) RETURN MGMT_TARGET_ARRAY IS p_flat_targets_list MGMT_TARGET_ARRAY := MGMT_TARGET_ARRAY(); l_flat_count NUMBER := 0; BEGIN p_array_out := MGMT_TARGET_ARRAY(); IF (p_mode IS NOT NULL AND p_mode = 1) THEN FOR i IN 1..p_comp_targets_list.COUNT LOOP FOR cursor_type IN ( SELECT DISTINCT target_name, target_type FROM mgmt_targets t WHERE target_guid IN ( SELECT assoc_target_guid FROM mgmt_flat_target_assoc, mgmt_targets WHERE is_membership = '1' AND source_target_guid IN ( SELECT target_guid FROM mgmt_targets WHERE target_name IN (p_comp_targets_list(i).target_name) ) AND assoc_target_guid = mgmt_targets.target_guid AND target_type = p_template_target_type ) AND ( t.emd_url IS NULL OR t.emd_url IN ( SELECT emd_url FROM mgmt_targets t2, mgmt_target_properties prop WHERE t2.target_type = 'oracle_emd' AND t2.emd_url = t.emd_url AND t2.target_guid = prop.target_guid AND prop.property_name = 'Version' AND prop.property_type = 'INSTANCE' AND prop.property_value NOT LIKE '10.1%' AND prop.property_value NOT LIKE '4.%' ) ) ) LOOP l_flat_count := l_flat_count +1; p_flat_targets_list.extend; p_flat_targets_list(l_flat_count) := MGMT_TARGET_OBJ(cursor_type.target_name,cursor_type.target_type); END LOOP; END LOOP; p_array_out := get_flattened_invalid_targets(p_comp_targets_list, p_template_target_type); ELSE FOR i IN 1..p_comp_targets_list.COUNT LOOP FOR cursor_type IN ( SELECT target_name, target_type FROM mgmt_targets WHERE target_guid IN ( SELECT assoc_target_guid FROM mgmt_flat_target_assoc, mgmt_targets WHERE is_membership='1' AND source_target_guid IN ( SELECT target_guid FROM mgmt_targets WHERE target_name IN (p_comp_targets_list(i).target_name) ) AND assoc_target_guid=mgmt_targets.target_guid AND target_type=p_template_target_type ) ) LOOP l_flat_count := l_flat_count +1; p_flat_targets_list.extend; p_flat_targets_list(l_flat_count) := MGMT_TARGET_OBJ(cursor_type.target_name,cursor_type.target_type); END LOOP; END LOOP; END IF; RETURN p_flat_targets_list; END get_flattened_targets; -- Purpose : Listed below -- 1> Get the list of valid targets in database. -- 2> Scan the above list for composite target types. -- 3> Invoke the private function to get flattened list of applicable targets -- in the composite targets types. -- 4> Append the flat targets to the original list of valid targets, remove duplicates -- 5> Populate the list of invalid targets (from the input the user has specified) -- 6> Populate the list of not applicable targets (from the input specified) -- 7> Populate the list of targets which are not supported by agent,etc -- Input Parameters -- p_template_target_type : Target type, the template is applicable to -- p_tgt_name_type_list : Array of target names and their types -- p_mode : Mode - wildcard/disabled collection etc -- Output Parameters -- p_targets_list : List of valid target names and their types in database -- p_na_targets_list : List of not applicable target names and their types -- p_invalid_targets_list : List of invalid target names and their types -- p_invalid_mode_targets_list : List of invalid target names and their types due to disabled -- collection,etc PROCEDURE get_targets_info ( p_template_target_type IN VARCHAR2, p_tgt_name_type_list IN MGMT_TARGET_ARRAY, p_mode IN VARCHAR2 DEFAULT NULL, p_targets_list OUT MGMT_TARGET_ARRAY, p_na_targets_list OUT MGMT_TARGET_ARRAY, p_invalid_targets_list OUT MGMT_TARGET_ARRAY, p_invalid_mode_targets_list OUT MGMT_TARGET_ARRAY ) IS l_count1 NUMBER; l_count2 NUMBER; p_dest_count NUMBER :=0; p_invalid_count NUMBER := 0; p_na_count NUMBER := 0; p_comp_count NUMBER := 0; p_comp_targets_list MGMT_TARGET_ARRAY := MGMT_TARGET_ARRAY(); p_flat_targets_list MGMT_TARGET_ARRAY := MGMT_TARGET_ARRAY(); p_temp_targets_list MGMT_TARGET_ARRAY := MGMT_TARGET_ARRAY(); p_temp_tgt_name VARCHAR2_TABLE := VARCHAR2_TABLE(); p_temp_tgt_type VARCHAR2_TABLE := VARCHAR2_TABLE(); BEGIN p_targets_list := MGMT_TARGET_ARRAY(); p_na_targets_list := MGMT_TARGET_ARRAY(); p_invalid_targets_list := MGMT_TARGET_ARRAY(); p_invalid_mode_targets_list := MGMT_TARGET_ARRAY(); FOR i IN 1..p_tgt_name_type_list.COUNT LOOP SELECT COUNT(1) INTO l_count1 FROM mgmt_targets WHERE target_type = p_tgt_name_type_list(i).target_type AND mgmt_targets.target_name = p_tgt_name_type_list(i).target_name; IF l_count1 > 0 THEN --if templateTargetType = computed targetType then do the following IF (p_template_target_type = p_tgt_name_type_list(i).target_type) THEN p_dest_count := p_dest_count + 1; p_targets_list.extend(1); p_targets_list(p_dest_count) := MGMT_TARGET_OBJ(p_tgt_name_type_list(i).target_name, p_tgt_name_type_list(i).target_type); -- else, here we get composite+invalid targetTypes -- else if composite, populate a third list for flattened targets -- else if invalid, populate the invalid list of not applicable targets ELSE SELECT COUNT(1) INTO l_count2 FROM mgmt_type_properties WHERE target_type = p_tgt_name_type_list(i).target_type AND property_name = 'is_aggregate' AND property_value = '1'; IF l_count2 > 0 THEN ---populate a new list p_comp_count := p_comp_count + 1; p_comp_targets_list.extend(1); p_comp_targets_list(p_comp_count) := MGMT_TARGET_OBJ(p_tgt_name_type_list(i).target_name, p_tgt_name_type_list(i).target_type); ELSE --populate the not applicable list p_na_count := p_na_count + 1; p_na_targets_list.extend(1); p_na_targets_list(p_na_count) := MGMT_TARGET_OBJ(p_tgt_name_type_list(i).target_name, p_tgt_name_type_list(i).target_type); END if; END IF; ELSE p_invalid_count := p_invalid_count + 1; p_invalid_targets_list.extend(1); p_invalid_targets_list(p_invalid_count) := MGMT_TARGET_OBJ(p_tgt_name_type_list(i).target_name, p_tgt_name_type_list(i).target_type); END IF; END LOOP; -- call get_flattened_targets and pass composite list array (p_comp_targets_list) into it -- for composites get the flattened targets -- and return the entire thing to the calling program p_flat_targets_list := get_flattened_targets(p_comp_targets_list, p_template_target_type, p_mode, p_invalid_mode_targets_list); -- get the actual flattened list and append it to the original valid targets list FOR i IN 1..p_flat_targets_list.COUNT LOOP p_dest_count := p_dest_count +1; p_targets_list.extend(1); p_targets_list(p_dest_count) := p_flat_targets_list(i); END LOOP; SELECT DISTINCT a.target_name, a.target_type BULK COLLECT INTO p_temp_tgt_name, p_temp_tgt_type FROM TABLE ( CAST(p_targets_list AS MGMT_TARGET_ARRAY) ) a ; p_targets_list.delete; p_targets_list := MGMT_TARGET_ARRAY(); IF (p_temp_tgt_name.count > 0 AND p_temp_tgt_name IS NOT NULL) THEN FOR i IN 1..p_temp_tgt_name.COUNT LOOP p_targets_list.extend(1); p_targets_list(i) := MGMT_TARGET_OBJ(p_temp_tgt_name(i),p_temp_tgt_type(i)); END LOOP; END IF; p_temp_tgt_name.delete; p_temp_tgt_type.delete; END get_targets_info; END mgmt_template; / show errors;