From a974aa0cfb827476104c140096de676711d2b673 Mon Sep 17 00:00:00 2001 From: Pamela Dragosh Date: Tue, 14 Feb 2017 19:31:53 -0500 Subject: Initial OpenECOMP policy/common commit Change-Id: I61cd29d6d8bf8702c1a66915895b519bf3484afa Signed-off-by: Pamela Dragosh --- .../common/im/AdministrativeStateException.java | 37 + .../policy/common/im/ForwardProgressException.java | 37 + .../policy/common/im/IntegrityMonitor.java | 1300 ++++++++++++++++++++ .../common/im/IntegrityMonitorProperties.java | 55 + .../im/IntegrityMonitorPropertiesException.java | 37 + .../policy/common/im/StandbyStatusException.java | 48 + .../policy/common/im/StateChangeNotifier.java | 76 ++ .../openecomp/policy/common/im/StateElement.java | 160 +++ .../policy/common/im/StateManagement.java | 1015 +++++++++++++++ .../policy/common/im/StateTransition.java | 726 +++++++++++ .../policy/common/im/jmx/ComponentAdmin.java | 227 ++++ .../policy/common/im/jmx/ComponentAdminMBean.java | 50 + .../policy/common/im/jmx/JmxAgentConnection.java | 133 ++ .../common/im/jpa/ForwardProgressEntity.java | 131 ++ .../policy/common/im/jpa/ImTestEntity.java | 146 +++ .../common/im/jpa/ResourceRegistrationEntity.java | 150 +++ .../common/im/jpa/StateManagementEntity.java | 143 +++ 17 files changed, 4471 insertions(+) create mode 100644 integrity-monitor/src/main/java/org/openecomp/policy/common/im/AdministrativeStateException.java create mode 100644 integrity-monitor/src/main/java/org/openecomp/policy/common/im/ForwardProgressException.java create mode 100644 integrity-monitor/src/main/java/org/openecomp/policy/common/im/IntegrityMonitor.java create mode 100644 integrity-monitor/src/main/java/org/openecomp/policy/common/im/IntegrityMonitorProperties.java create mode 100644 integrity-monitor/src/main/java/org/openecomp/policy/common/im/IntegrityMonitorPropertiesException.java create mode 100644 integrity-monitor/src/main/java/org/openecomp/policy/common/im/StandbyStatusException.java create mode 100644 integrity-monitor/src/main/java/org/openecomp/policy/common/im/StateChangeNotifier.java create mode 100644 integrity-monitor/src/main/java/org/openecomp/policy/common/im/StateElement.java create mode 100644 integrity-monitor/src/main/java/org/openecomp/policy/common/im/StateManagement.java create mode 100644 integrity-monitor/src/main/java/org/openecomp/policy/common/im/StateTransition.java create mode 100644 integrity-monitor/src/main/java/org/openecomp/policy/common/im/jmx/ComponentAdmin.java create mode 100644 integrity-monitor/src/main/java/org/openecomp/policy/common/im/jmx/ComponentAdminMBean.java create mode 100644 integrity-monitor/src/main/java/org/openecomp/policy/common/im/jmx/JmxAgentConnection.java create mode 100644 integrity-monitor/src/main/java/org/openecomp/policy/common/im/jpa/ForwardProgressEntity.java create mode 100644 integrity-monitor/src/main/java/org/openecomp/policy/common/im/jpa/ImTestEntity.java create mode 100644 integrity-monitor/src/main/java/org/openecomp/policy/common/im/jpa/ResourceRegistrationEntity.java create mode 100644 integrity-monitor/src/main/java/org/openecomp/policy/common/im/jpa/StateManagementEntity.java (limited to 'integrity-monitor/src/main/java/org') diff --git a/integrity-monitor/src/main/java/org/openecomp/policy/common/im/AdministrativeStateException.java b/integrity-monitor/src/main/java/org/openecomp/policy/common/im/AdministrativeStateException.java new file mode 100644 index 00000000..1115c177 --- /dev/null +++ b/integrity-monitor/src/main/java/org/openecomp/policy/common/im/AdministrativeStateException.java @@ -0,0 +1,37 @@ +/*- + * ============LICENSE_START======================================================= + * Integrity Monitor + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.policy.common.im; + +public class AdministrativeStateException extends Exception{ + private static final long serialVersionUID = 1L; + public AdministrativeStateException() { + } + public AdministrativeStateException(String message) { + super(message); + } + + public AdministrativeStateException(Throwable cause) { + super(cause); + } + public AdministrativeStateException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/integrity-monitor/src/main/java/org/openecomp/policy/common/im/ForwardProgressException.java b/integrity-monitor/src/main/java/org/openecomp/policy/common/im/ForwardProgressException.java new file mode 100644 index 00000000..982f71aa --- /dev/null +++ b/integrity-monitor/src/main/java/org/openecomp/policy/common/im/ForwardProgressException.java @@ -0,0 +1,37 @@ +/*- + * ============LICENSE_START======================================================= + * Integrity Monitor + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.policy.common.im; + +public class ForwardProgressException extends Exception{ + private static final long serialVersionUID = 1L; + public ForwardProgressException() { + } + public ForwardProgressException(String message) { + super(message); + } + + public ForwardProgressException(Throwable cause) { + super(cause); + } + public ForwardProgressException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/integrity-monitor/src/main/java/org/openecomp/policy/common/im/IntegrityMonitor.java b/integrity-monitor/src/main/java/org/openecomp/policy/common/im/IntegrityMonitor.java new file mode 100644 index 00000000..6c575ab7 --- /dev/null +++ b/integrity-monitor/src/main/java/org/openecomp/policy/common/im/IntegrityMonitor.java @@ -0,0 +1,1300 @@ +/*- + * ============LICENSE_START======================================================= + * Integrity Monitor + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.policy.common.im; + +import java.net.InetAddress; +import java.util.Arrays; +import java.util.Date; +import java.util.List; +import java.util.Properties; +import java.util.concurrent.TimeUnit; + +import javax.management.JMX; +import javax.management.MBeanServerConnection; +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.EntityTransaction; +import javax.persistence.FlushModeType; +import javax.persistence.LockModeType; +import javax.persistence.Persistence; +import javax.persistence.Query; + +//import org.apache.log4j.Logger; + +import org.openecomp.policy.common.im.jmx.*; +import org.openecomp.policy.common.im.jpa.ForwardProgressEntity; +import org.openecomp.policy.common.im.jpa.ResourceRegistrationEntity; +import org.openecomp.policy.common.im.jpa.StateManagementEntity; +import org.openecomp.policy.common.logging.flexlogger.FlexLogger; +import org.openecomp.policy.common.logging.flexlogger.Logger; + +/** + * IntegrityMonitor + * Main class for monitoring the integrity of a resource and managing its state. State management follows + * the X.731 ITU standard. + */ +public class IntegrityMonitor { + private static final Logger logger = FlexLogger.getLogger(IntegrityMonitor.class.getName()); + + //private static final Map imInstances = new HashMap(); + + // only allow one instance of IntegrityMonitor + private static IntegrityMonitor instance = null; + + private static String resourceName = null; + private boolean fpcError = false; + boolean alarmExists = false; + + /* + * Error message that is written by the dependencyCheck() method. It is made available externally + * through the evaluateSanity() method. + */ + private String dependencyCheckErrorMsg = ""; + + + // The entity manager factory for JPA access + private EntityManagerFactory emf; + private EntityManager em; + + // Persistence Unit for JPA + private static final String PERSISTENCE_UNIT = "operationalPU"; + + private ComponentAdmin admin = null; + private StateManagement stateManager = null; + + private static final int CYCLE_INTERVAL_MILLIS = 1000; + + // The forward progress counter is incremented as the + // process being monitored makes forward progress + private int fpCounter = 0; + private int lastFpCounter = 0; + + // elapsed time since last FP counter check + private long elapsedTime = 0; + + // elapsed time since last test transaction check + private long elapsedTestTransTime = 0; + + // elapsed time since last write Fpc check + private long elapsedWriteFpcTime = 0; + + // last dependency health check time. Initialize so that the periodic check starts after 60 seconds. + // This allows time for dependents to come up. + private long lastDependencyCheckTime = System.currentTimeMillis(); + + // the number of cycles since 'fpCounter' was last changed + private int missedCycles = 0; + + // forward progress monitoring interval + private static int monitorInterval = IntegrityMonitorProperties.DEFAULT_MONITOR_INTERVAL; + // The number of periods the counter fails to increment before an alarm is raised. + private static int failedCounterThreshold = IntegrityMonitorProperties.DEFAULT_FAILED_COUNTER_THRESHOLD; + // test transaction interval + private static int testTransInterval = IntegrityMonitorProperties.DEFAULT_TEST_INTERVAL; + // write Fpc to DB interval + private static int writeFpcInterval = IntegrityMonitorProperties.DEFAULT_WRITE_FPC_INTERVAL; + + // A lead subsystem will have dependency groups with resource names in the properties file. + // For non-lead subsystems, the dependency_group property will be absent. + private static String [] dep_groups = null; + + public static boolean isUnitTesting = false; + + // can turn on health checking of dependents via jmx test() call by setting this property to true + private static boolean testViaJmx = false; + + private static String jmxFqdn = null; + + // this is the max interval allowed without any forward progress counter updates + private static int maxFpcUpdateInterval = IntegrityMonitorProperties.DEFAULT_MAX_FPC_UPDATE_INTERVAL; + + // Node types + private enum NodeType { + pdp_xacml, + pdp_drools, + pap, + pap_admin, + logparser, + brms_gateway, + astra_gateway, + elk_server, + pypdp + + } + + private static String site_name; + private static String node_type; + private Date refreshStateAuditLastRunDate; + private int refreshStateAuditIntervalMs = 60000; //run it once per minute + + //lock objects + private final Object evaluateSanityLock = new Object(); + private final Object fpMonitorCycleLock = new Object(); + private final Object dependencyCheckLock = new Object(); + private final Object testTransactionLock = new Object(); + private final Object startTransactionLock = new Object(); + private final Object endTransactionLock = new Object(); + private final Object checkTestTransactionLock = new Object(); + private final Object checkWriteFpcLock = new Object(); + private static final Object getInstanceLock = new Object(); + private final Object refreshStateAuditLock = new Object(); + private final Object IMFLUSHLOCK = new Object(); + + /** + * Get an instance of IntegrityMonitor for a given resource name. It creates one if it does not exist. + * Only one instance is allowed to be created per resource name. + * @param resourceName The resource name of the resource + * @param properties a set of properties passed in from the resource + * @return The new instance of IntegrityMonitor + * @throws Exception if unable to create jmx url or the constructor returns an exception + */ + public static IntegrityMonitor getInstance(String resourceName, Properties properties) throws Exception { + synchronized(getInstanceLock){ + logger.info("getInstance() called - resourceName=" + resourceName); + if (resourceName == null || resourceName.isEmpty() || properties == null) { + logger.error("Error: getIntegrityMonitorInstance() called with invalid input"); + return null; + } + + if (instance == null) { + logger.info("Creating new instance of IntegrityMonitor"); + instance = new IntegrityMonitor(resourceName, properties); + } + return instance; + } + } + + public static IntegrityMonitor getInstance() throws Exception{ + logger.info("getInstance() called"); + if (instance == null) { + String msg = "No IntegrityMonitor instance exists." + + " Please use the method IntegrityMonitor.getInstance(String resourceName, Properties properties)"; + throw new IntegrityMonitorPropertiesException(msg); + }else{ + return instance; + } + } + + public static void deleteInstance(){ + logger.info("deleteInstance() called"); + if(isUnitTesting){ + instance=null; + } + logger.info("deleteInstance() exit"); + } + /** + * IntegrityMonitor constructor. It is invoked from the getInstance() method in + * this class or from the constructor of a child or sub-class. A class can extend + * the IntegrityMonitor class if there is a need to override any of the base + * methods (ex. subsystemTest()). Only one instance is allowed to be created per + * resource name. + * @param resourceName The resource name of the resource + * @param properties a set of properties passed in from the resource + * @throws Exception if any errors are encountered in the consructor + */ + protected IntegrityMonitor(String resourceName, Properties properties) throws Exception { + + // singleton check since this constructor can be called from a child or sub-class + if (instance != null) { + String msg = "IM object exists and only one instance allowed"; + logger.error(msg); + throw new Exception("IntegrityMonitor constructor exception: " + msg); + } + instance = this; + + IntegrityMonitor.resourceName = resourceName; + + /* + * Validate that the properties file contains all the needed properties. Throws + * an IntegrityMonitorPropertiesException + */ + validateProperties(properties); + + // construct jmx url + String jmxUrl = getJmxUrl(); + + // + // Create the entity manager factory + // + emf = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT, properties); + // + // Did it get created? + // + if (emf == null) { + logger.error("Error creating IM entity manager factory with persistence unit: " + + PERSISTENCE_UNIT); + throw new Exception("Unable to create IM Entity Manager Factory"); + } + + // add entry to forward progress and resource registration tables in DB + + // Start a transaction + em = emf.createEntityManager(); + EntityTransaction et = em.getTransaction(); + + et.begin(); + + try { + // if ForwardProgress entry exists for resourceName, update it. If not found, create a new entry + Query fquery = em.createQuery("Select f from ForwardProgressEntity f where f.resourceName=:rn"); + fquery.setParameter("rn", resourceName); + + @SuppressWarnings("rawtypes") + List fpList = fquery.setLockMode( + LockModeType.NONE).setFlushMode(FlushModeType.COMMIT).getResultList(); + ForwardProgressEntity fpx = null; + if(!fpList.isEmpty()){ + //ignores multiple results + fpx = (ForwardProgressEntity) fpList.get(0); + // refresh the object from DB in case cached data was returned + em.refresh(fpx); + logger.info("Resource " + resourceName + " exists and will be updated - old fpc=" + fpx.getFpcCount() + ", lastUpdated=" + fpx.getLastUpdated()); + fpx.setFpcCount(fpCounter); + }else{ + //Create a forward progress object + logger.info("Adding resource " + resourceName + " to ForwardProgress table"); + fpx = new ForwardProgressEntity(); + } + //update/set columns in entry + fpx.setResourceName(resourceName); + em.persist(fpx); + // flush to the DB + synchronized(IMFLUSHLOCK){ + em.flush(); + } + + // if ResourceRegistration entry exists for resourceName, update it. If not found, create a new entry + Query rquery = em.createQuery("Select r from ResourceRegistrationEntity r where r.resourceName=:rn"); + rquery.setParameter("rn", resourceName); + + @SuppressWarnings("rawtypes") + List rrList = rquery.setLockMode( + LockModeType.NONE).setFlushMode(FlushModeType.COMMIT).getResultList(); + ResourceRegistrationEntity rrx = null; + if(!rrList.isEmpty()){ + //ignores multiple results + rrx = (ResourceRegistrationEntity) rrList.get(0); + // refresh the object from DB in case cached data was returned + em.refresh(rrx); + logger.info("Resource " + resourceName + " exists and will be updated - old url=" + rrx.getResourceUrl() + ", createdDate=" + rrx.getCreatedDate()); + rrx.setLastUpdated(new Date()); + }else{ + // register resource by adding entry to table in DB + logger.info("Adding resource " + resourceName + " to ResourceRegistration table"); + rrx = new ResourceRegistrationEntity(); + } + //update/set columns in entry + rrx.setResourceName(resourceName); + rrx.setResourceUrl(jmxUrl); + rrx.setNodeType(node_type); + rrx.setSite(site_name); + em.persist(rrx); + // flush to the DB + synchronized(IMFLUSHLOCK){ + em.flush(); + et.commit(); + } + + } catch (Exception e) { + logger.error("IntegrityMonitor constructor DB table update failed with exception: " + e); + try { + if (et.isActive()) { + synchronized(IMFLUSHLOCK){ + et.rollback(); + } + } + } catch (Exception e1) { + // ignore + } + throw e; + } + + // create instance of StateMangement class and pass emf to it + stateManager = new StateManagement(emf, resourceName); + + /** + * Initialize the state and status attributes. This will maintain any Administrative state value + * but will set the operational state = enabled, availability status = null, standby status = null. + * The integrity monitor will set the operational state via the FPManager and the owning application + * must set the standby status by calling promote/demote on the StateManager. + */ + stateManager.initializeState(); + + + // create management bean + try { + admin = new ComponentAdmin(resourceName, this, stateManager); + } catch (Exception e) { + logger.error("ComponentAdmin constructor exception: " + e.toString()); + } + + // create FPManager inner class + FPManager fpMonitor = new FPManager(); + + + } + + private static String getJmxUrl() throws Exception { + + // get the jmx remote port and construct the JMX URL + Properties systemProps = System.getProperties(); + String jmx_port = systemProps.getProperty("com.sun.management.jmxremote.port"); + String jmx_err_msg = ""; + if (jmx_port == null) { + jmx_err_msg = "System property com.sun.management.jmxremote.port for JMX remote port is not set"; + logger.error(jmx_err_msg); + throw new Exception("getJmxUrl exception: " + jmx_err_msg); + } + + int port = 0; + try { + port = Integer.parseInt(jmx_port); + } catch (NumberFormatException e) { + jmx_err_msg = "JMX remote port is not a valid integer value - " + jmx_port; + logger.error(jmx_err_msg); + throw new Exception("getJmxUrl exception: " + jmx_err_msg); + } + + try { + if (jmxFqdn == null) { + jmxFqdn = InetAddress.getLocalHost().getCanonicalHostName(); // get FQDN of this host + } + } catch (Exception e) { + String msg = "getJmxUrl could not get hostname" + e; + logger.error(msg); + throw new Exception("getJmxUrl Exception: " + msg); + } + if (jmxFqdn == null) { + String msg = "getJmxUrl encountered null hostname"; + logger.error(msg); + throw new Exception("getJmxUrl error: " + msg); + } + + // assemble the jmx url + String jmx_url = "service:jmx:rmi:///jndi/rmi://" + jmxFqdn + ":" + port + "/jmxrmi"; + logger.info("IntegerityMonitor - jmx url=" + jmx_url); + + return jmx_url; + } + /** + * evaluateSanity() is designed to be called by an external entity to evealuate the sanity + * of the node. It checks the operational and administrative states and the standby + * status. If the operational state is disabled, it will include the dependencyCheckErrorMsg + * which includes information about any dependency (node) which has failed. + */ + public void evaluateSanity() throws Exception { + logger.debug("evaluateSanity called ...."); + synchronized(evaluateSanityLock){ + + String error_msg = dependencyCheckErrorMsg; + logger.debug("evaluateSanity dependencyCheckErrorMsg = " + error_msg); + + // check op state and throw exception if disabled + if ((stateManager.getOpState() != null) && stateManager.getOpState().equals(StateManagement.DISABLED)) { + String msg = "Resource " + resourceName + " operation state is disabled. " + error_msg; + logger.debug(msg); + throw new Exception(msg); + } + + // check admin state and throw exception if locked + if ((stateManager.getAdminState() != null) && stateManager.getAdminState().equals(StateManagement.LOCKED)) { + String msg = "Resource " + resourceName + " is administratively locked"; + logger.debug(msg); + throw new AdministrativeStateException("IntegrityMonitor Admin State Exception: " + msg); + } + // check standby state and throw exception if cold standby + if ((stateManager.getStandbyStatus() != null) && stateManager.getStandbyStatus().equals(StateManagement.COLD_STANDBY)){ + String msg = "Resource " + resourceName + " is cold standby"; + logger.debug(msg); + throw new StandbyStatusException("IntegrityMonitor Standby Status Exception: " + msg); + } + +/* + * This is checked in the FPManager where the state is coordinated + if (fpcError) { + String msg = resourceName + ": no forward progress detected"; + logger.error(msg); + throw new ForwardProgressException(msg); + } + + * Additional testing to be provided by susbsystemTest() which could be overridden + * This has been moved to dependencyCheck where it is treated as testing of a dependency + subsystemTest(); +*/ + } + + } + + private String stateCheck(String dep) { + logger.debug("checking state of dependent resource: " + dep); + + // get state management entry for dependent resource + StateManagementEntity stateManagementEntity = null; + String error_msg = null; + try { + // Start a transaction + EntityTransaction et = em.getTransaction(); + et.begin(); + + // query if StateManagement entry exists for dependent resource + Query query = em.createQuery("Select p from StateManagementEntity p where p.resourceName=:resource"); + query.setParameter("resource", dep); + + @SuppressWarnings("rawtypes") + List smList = query.setLockMode( + LockModeType.NONE).setFlushMode(FlushModeType.COMMIT).getResultList(); + if (!smList.isEmpty()) { + // exist + stateManagementEntity = (StateManagementEntity) smList.get(0); + // refresh the object from DB in case cached data was returned + em.refresh(stateManagementEntity); + logger.debug("Found entry in StateManagementEntity table for dependent Resource=" + dep); + } else { + error_msg = dep + ": resource not found in state management entity database table"; + logger.error(error_msg); + } + + synchronized(IMFLUSHLOCK){ + et.commit(); + } + } catch (Exception e) { + // log an error + error_msg = dep + ": StateManagementEntity DB read failed with exception: " + e; + logger.error(error_msg); + } + + // check operation, admin and standby states of dependent resource + if (error_msg == null) { + if ((stateManager.getAdminState() != null) && stateManagementEntity.getAdminState().equals(StateManagement.LOCKED)) { + error_msg = dep + ": resource is administratively locked"; + logger.error(error_msg); + } else if ((stateManager.getOpState() != null) && stateManagementEntity.getOpState().equals(StateManagement.DISABLED)) { + error_msg = dep + ": resource is operationally disabled"; + logger.error(error_msg); + } else if ((stateManager.getStandbyStatus() != null) && stateManagementEntity.getStandbyStatus().equals(StateManagement.COLD_STANDBY)) { + error_msg = dep + ": resource is cold standby"; + logger.error(error_msg); + } + } + + return error_msg; + } + + private String fpCheck(String dep) { + logger.debug("checking forward progress count of dependent resource: " + dep); + + String error_msg = null; + + // check FPC count - a changing FPC count indicates the resource JVM is running + + // Start a transaction + EntityTransaction et = em.getTransaction(); + et.begin(); + try { + Query fquery = em.createQuery("Select f from ForwardProgressEntity f where f.resourceName=:rn"); + fquery.setParameter("rn", dep); + + @SuppressWarnings("rawtypes") + List fpList = fquery.setLockMode( + LockModeType.NONE).setFlushMode(FlushModeType.COMMIT).getResultList(); + ForwardProgressEntity fpx = null; + if (!fpList.isEmpty()) { + //ignores multiple results + fpx = (ForwardProgressEntity) fpList.get(0); + // refresh the object from DB in case cached data was returned + em.refresh(fpx); + logger.debug("Dependent resource " + dep + " - fpc=" + fpx.getFpcCount() + ", lastUpdated=" + fpx.getLastUpdated()); + long currTime = System.currentTimeMillis(); + // if dependent resource FPC has not been updated, consider it an error + if ((currTime - fpx.getLastUpdated().getTime()) > (1000 * maxFpcUpdateInterval)) { + error_msg = dep + ": FP count has not been updated in the last " + maxFpcUpdateInterval + " seconds"; + logger.error(error_msg); + try { + // create instance of StateMangement class for dependent + StateManagement depStateManager = new StateManagement(emf, dep); + if (depStateManager != null) { + logger.info("Forward progress not detected for dependent resource " + dep + ". Setting dependent's state to disable failed."); + depStateManager.disableFailed(); + } + } catch (Exception e) { + // ignore errors + logger.info("Update dependent state failed with exception: " + e); + } + } + } else { + // resource entry not found in FPC table + error_msg = dep + ": resource not found in ForwardProgressEntity table in the DB"; + logger.error(error_msg); + } + synchronized(IMFLUSHLOCK){ + et.commit(); + } + } catch (Exception e) { + // log an error and continue + error_msg = dep + ": ForwardProgressEntity DB read failed with exception: " + e; + logger.error(error_msg); + } + + return error_msg; + } + + private String jmxCheck(String dep) { + logger.debug("checking health of dependent by calling test() via JMX on resource: " + dep); + + String error_msg = null; + + // get the JMX URL from the database + String jmxUrl = null; + try { + // Start a transaction + EntityTransaction et = em.getTransaction(); + et.begin(); + + // query if ResourceRegistration entry exists for resourceName + Query rquery = em.createQuery("Select r from ResourceRegistrationEntity r where r.resourceName=:rn"); + rquery.setParameter("rn", dep); + + @SuppressWarnings("rawtypes") + List rrList = rquery.setLockMode( + LockModeType.NONE).setFlushMode(FlushModeType.COMMIT).getResultList(); + ResourceRegistrationEntity rrx = null; + + if (!rrList.isEmpty()) { + //ignores multiple results + rrx = (ResourceRegistrationEntity) rrList.get(0); + // refresh the object from DB in case cached data was returned + em.refresh(rrx); + jmxUrl = rrx.getResourceUrl(); + logger.debug("Dependent Resource=" + dep + ", url=" + jmxUrl + ", createdDate=" + rrx.getCreatedDate()); + } else { + error_msg = dep + ": resource not found in ResourceRegistrationEntity table in the DB"; + logger.error(error_msg); + } + + synchronized(IMFLUSHLOCK){ + et.commit(); + } + } catch (Exception e) { + error_msg = dep + ": ResourceRegistrationEntity DB read failed with exception: " + e; + logger.error(error_msg); + } + + + if (jmxUrl != null) { + JmxAgentConnection jmxAgentConnection = null; + try { + jmxAgentConnection = new JmxAgentConnection(jmxUrl); + MBeanServerConnection mbeanServer = jmxAgentConnection.getMBeanConnection(); + ComponentAdminMBean admin = JMX.newMXBeanProxy(mbeanServer, ComponentAdmin.getObjectName(dep), + ComponentAdminMBean.class); + + // invoke the test method via the jmx proxy + admin.test(); + logger.debug("Dependent resource " + dep + " sanity test passed"); + } catch (Exception e) { + error_msg = dep + ": resource sanity test failed with exception: " + e; + logger.error(error_msg); + // TODO: extract real error message from exception which may be nested + } finally { + // close the JMX connector + if (jmxAgentConnection != null) { + jmxAgentConnection.disconnect(); + } + } + } + + return error_msg; + } + + private String dependencyCheck() { + logger.debug("dependencyCheck: entry - checking health of dependent groups and setting resource's state"); + synchronized(dependencyCheckLock){ + + // Start with the error message empty + String error_msg = ""; + boolean dependencyFailure = false; + + + // Check the sanity of dependents for lead subcomponents + if (dep_groups != null && dep_groups.length > 0) { + // check state of resources in dependency groups + for (String group : dep_groups) { + group = group.trim(); + if (group.isEmpty()) { + // ignore empty group + continue; + } + String [] dependencies = group.split(","); + logger.debug("group dependencies = " + Arrays.toString(dependencies)); + int real_dep_count = 0; + int fail_dep_count = 0; + for (String dep : dependencies) { + dep = dep.trim(); + if (dep.isEmpty()) { + // ignore empty dependency + continue; + } + real_dep_count++; // this is a valid dependency whose state is tracked + String fail_msg = fpCheck(dep); // if a resource is down, its FP count will not be incremented + if (fail_msg == null) { + if (testViaJmx) { + fail_msg = jmxCheck(dep); + } else { + fail_msg = stateCheck(dep); + } + } + if (fail_msg != null) { + fail_dep_count++; + if (!error_msg.isEmpty()) { + error_msg = error_msg.concat(", "); + } + error_msg = error_msg.concat(fail_msg); + } + }// end for (String dep : dependencies) + + // if all dependencies in a group are failed, set this resource's state to disable dependency + if ((real_dep_count > 0) && (fail_dep_count == real_dep_count)) { + dependencyFailure=true; + try { + logger.info("All dependents in group " + group + " have failed their health check. Updating this resource's state to disableDependency"); + if( !( (stateManager.getAvailStatus()).equals(StateManagement.DEPENDENCY) || + (stateManager.getAvailStatus()).equals(StateManagement.DEPENDENCY_FAILED) ) ){ + // Note: redundant calls are made by refreshStateAudit + this.stateManager.disableDependency(); + }else //corruption has occurred - This will not be corrected by the refreshStateAudit + if(!(stateManager.getOpState()).equals(StateManagement.DISABLED)){ + // Note: redundant calls are made by refreshStateAudit + this.stateManager.disableDependency(); + } + } catch (Exception e) { + if (!error_msg.isEmpty()) { + error_msg = error_msg.concat(","); + } + error_msg = error_msg.concat(resourceName + ": Failed to disable dependency"); + break; // break out on failure and skip checking other groups + } + } + //check the next group + + }//end for (String group : dep_groups) + + /* + * We have checked all the dependency groups. If all are ok, dependencyFailure == false + */ + if(!dependencyFailure){ + try { + logger.debug("All dependency groups have at least one viable member. Updating this resource's state to enableNoDependency"); + if( ( (stateManager.getAvailStatus()).equals(StateManagement.DEPENDENCY) || + (stateManager.getAvailStatus()).equals(StateManagement.DEPENDENCY_FAILED) ) ){ + // Note: redundant calls are made by refreshStateAudit + this.stateManager.enableNoDependency(); + } // The refreshStateAudit will catch the case where it is disabled but availStatus != failed + } catch (Exception e) { + if (!error_msg.isEmpty()) { + error_msg = error_msg.concat(","); + } + error_msg = error_msg.concat(resourceName + ": Failed to enable no dependency"); + } + } + }else{ + /* + * This is put here to clean up when no dependency group should exist, but one was erroneously + * added which caused the state to be disabled/dependency/coldstandby and later removed. We saw + * this happen in the lab, but is not very likely in a production environment...but you never know. + */ + try { + logger.debug("There are no dependents. Updating this resource's state to enableNoDependency"); + if( ( (stateManager.getAvailStatus()).equals(StateManagement.DEPENDENCY) || + (stateManager.getAvailStatus()).equals(StateManagement.DEPENDENCY_FAILED) ) ){ + // Note: redundant calls are made by refreshStateAudit + this.stateManager.enableNoDependency(); + }// The refreshStateAudit will catch the case where it is disabled but availStatus != failed + } catch (Exception e) { + if (!error_msg.isEmpty()) { + error_msg = error_msg.concat(","); + } + error_msg = error_msg.concat(resourceName + ": Failed to enable no dependency"); + } + } + + /* + * We have checked dependency groups and if there were none, we set enableNoDependency. If there were some + * but they are all ok, we set enableNoDependency. So, the recovery from a disabled dependency state + * is handled above. We only need to set disableDependency if the subsystemTest fails. + */ + try { + //Test any subsystems that are not covered under the dependency relationship + subsystemTest(); + }catch (Exception e){ + //This indicates a subsystemTest failure + try { + logger.info(resourceName + ": There has been a subsystemTest failure with error: " + e.getMessage() + " Updating this resource's state to disableDependency"); + //Capture the subsystemTest failure info + if(!error_msg.isEmpty()){ + error_msg = error_msg.concat(","); + } + error_msg = error_msg.concat(resourceName + ": " + e.getMessage()); + this.stateManager.disableDependency(); + } catch (Exception ex) { + if (!error_msg.isEmpty()) { + error_msg = error_msg.concat(","); + } + error_msg = error_msg.concat("\n" + resourceName + ": Failed to disable dependency after subsystemTest failure due to: " + ex.getMessage()); + } + } + + if (!error_msg.isEmpty()) { + logger.error("Sanity failure detected in a dependent resource: " + error_msg); + + } + + dependencyCheckErrorMsg = error_msg; + lastDependencyCheckTime = System.currentTimeMillis(); + return error_msg; + } + } + + /** + * Execute a test transaction. It is called when the test transaction timer fires. + * It could be overridden to provide additional test functionality. If overridden, + * the overriding method must invoke startTransaction() and endTransaction() + */ + public void testTransaction() { + synchronized (testTransactionLock){ + logger.debug("testTransaction called..."); + // start Transaction - resets transaction timer and check admin state + try { + startTransaction(); + } catch (AdministrativeStateException e) { + // ignore + } catch (StandbyStatusException e) { + // ignore + } + + // TODO: add test functionality if needed + + // end transaction - increments local FP counter + endTransaction(); + } + } + + /** + * Additional testing for subsystems that do not have a /test interface (for ex. 3rd party + * processes like elk). This method would be overridden by the subsystem. + */ + public void subsystemTest() throws Exception { + // Testing provided by subsystem + logger.debug("IntegrityMonitor subsystemTest() OK"); + } + + /** + * Checks admin state and resets transaction timer. + * Called by application at the start of a transaction. + * @throws AdministrativeStateException throws admin state exception if resource is locked + * @throws StandbyStatusException + */ + public void startTransaction() throws AdministrativeStateException, StandbyStatusException { + + synchronized(startTransactionLock){ + // check admin state and throw exception if locked + if ((stateManager.getAdminState() != null) && stateManager.getAdminState().equals(StateManagement.LOCKED)) { + String msg = "Resource " + resourceName + " is administratively locked"; + // logger.debug(msg); + throw new AdministrativeStateException("IntegrityMonitor Admin State Exception: " + msg); + } + // check standby state and throw exception if locked + + if ((stateManager.getStandbyStatus() != null) && + (stateManager.getStandbyStatus().equals(StateManagement.HOT_STANDBY) || + stateManager.getStandbyStatus().equals(StateManagement.COLD_STANDBY))){ + String msg = "Resource " + resourceName + " is standby"; + //logger.debug(msg); + throw new StandbyStatusException("IntegrityMonitor Standby Status Exception: " + msg); + } + + // reset transactionTimer so it will not fire + elapsedTestTransTime = 0; + } + } + + /** + * Increment the local forward progress counter. Called by application at the + * end of each transaction (successful or not). + */ + public void endTransaction() { + synchronized(endTransactionLock){ + // increment local FPC + fpCounter++; + } + } + + // update FP count in DB with local FP count + private void writeFpc() throws Exception { + + // Start a transaction + EntityTransaction et = em.getTransaction(); + + if(!et.isActive()){ + et.begin(); + } + + try { + // query if ForwardProgress entry exists for resourceName + Query fquery = em.createQuery("Select f from ForwardProgressEntity f where f.resourceName=:rn"); + fquery.setParameter("rn", resourceName); + + @SuppressWarnings("rawtypes") + List fpList = fquery.setLockMode( + LockModeType.NONE).setFlushMode(FlushModeType.COMMIT).getResultList(); + ForwardProgressEntity fpx = null; + if(!fpList.isEmpty()) { + //ignores multiple results + fpx = (ForwardProgressEntity) fpList.get(0); + // refresh the object from DB in case cached data was returned + em.refresh(fpx); + logger.debug("Updating FP entry: Resource=" + resourceName + ", fpcCount=" + fpx.getFpcCount() + + ", lastUpdated=" + fpx.getLastUpdated() + ", new fpcCount=" + fpCounter); + fpx.setFpcCount(fpCounter); + em.persist(fpx); + // flush to the DB and commit + synchronized(IMFLUSHLOCK){ + em.flush(); + et.commit(); + } + } + else { + // Error - FP entry does not exist + String msg = "FP entry not found in database for resource " + resourceName; + throw new Exception(msg); + } + } catch (Exception e) { + try { + if (et.isActive()) { + et.rollback(); + } + } catch (Exception e1) { + // ignore + } + logger.error("writeFpc DB table commit failed with exception: " + e); + throw e; + } + } + + // retrieve state manager reference + public final StateManagement getStateManager() { + return this.stateManager; + } + + /** + * Read and validate properties + * @throws Exception + */ + private static void validateProperties(Properties prop) throws IntegrityMonitorPropertiesException { + + if (prop.getProperty(IntegrityMonitorProperties.DB_DRIVER)== null){ + String msg = IntegrityMonitorProperties.DB_DRIVER + " property is null"; + logger.error(msg); + throw new IntegrityMonitorPropertiesException("IntegrityMonitor Property Exception: " + msg); + } + + if (prop.getProperty(IntegrityMonitorProperties.DB_URL)== null){ + String msg = IntegrityMonitorProperties.DB_URL + " property is null"; + logger.error(msg); + throw new IntegrityMonitorPropertiesException("IntegrityMonitor Property Exception: " + msg); + } + + if (prop.getProperty(IntegrityMonitorProperties.DB_USER)== null){ + String msg = IntegrityMonitorProperties.DB_USER + " property is null"; + logger.error(msg); + throw new IntegrityMonitorPropertiesException("IntegrityMonitor Property Exception: " + msg); + } + + if (prop.getProperty(IntegrityMonitorProperties.DB_PWD)== null){ + String msg = IntegrityMonitorProperties.DB_PWD + " property is null"; + logger.error(msg); + throw new IntegrityMonitorPropertiesException("IntegrityMonitor Property Exception: " + msg); + } + + if (prop.getProperty(IntegrityMonitorProperties.FP_MONITOR_INTERVAL) != null) { + try { + monitorInterval = Integer.parseInt(prop.getProperty(IntegrityMonitorProperties.FP_MONITOR_INTERVAL).trim()); + } catch (NumberFormatException e) { + logger.warn("Ignored invalid property: " + IntegrityMonitorProperties.FP_MONITOR_INTERVAL); + } + } + + if (prop.getProperty(IntegrityMonitorProperties.FAILED_COUNTER_THRESHOLD) != null) { + try { + failedCounterThreshold = Integer.parseInt(prop.getProperty(IntegrityMonitorProperties.FAILED_COUNTER_THRESHOLD).trim()); + } catch (NumberFormatException e) { + logger.warn("Ignored invalid property: " + IntegrityMonitorProperties.FAILED_COUNTER_THRESHOLD); + } + } + + if (prop.getProperty(IntegrityMonitorProperties.TEST_TRANS_INTERVAL) != null) { + try { + testTransInterval = Integer.parseInt(prop.getProperty(IntegrityMonitorProperties.TEST_TRANS_INTERVAL).trim()); + } catch (NumberFormatException e) { + logger.warn("Ignored invalid property: " + IntegrityMonitorProperties.TEST_TRANS_INTERVAL); + } + } + + if (prop.getProperty(IntegrityMonitorProperties.WRITE_FPC_INTERVAL) != null) { + try { + writeFpcInterval = Integer.parseInt(prop.getProperty(IntegrityMonitorProperties.WRITE_FPC_INTERVAL).trim()); + } catch (NumberFormatException e) { + logger.warn("Ignored invalid property: " + IntegrityMonitorProperties.WRITE_FPC_INTERVAL); + } + } + + /*********************** + // followers are a comma separated list of resource names + if (prop.getProperty(IntegrityMonitorProperties.SS_FOLLOWERS) != null) { + try { + followers = prop.getProperty(IntegrityMonitorProperties.SS_FOLLOWERS).split(","); + logger.debug("followers property = " + Arrays.toString(followers)); + } catch (Exception e) { + logger.warn("Ignored invalid property: " + IntegrityMonitorProperties.SS_FOLLOWERS); + } + } + **************************/ + + // dependency_groups are a semi-colon separated list of groups + // each group is a comma separated list of resource names + // For ex. dependency_groups = site_1.pap_1,site_1.pap_2 ; site_1.pdp_1, site_1.pdp_2 + if (prop.getProperty(IntegrityMonitorProperties.DEPENDENCY_GROUPS) != null) { + try { + dep_groups = prop.getProperty(IntegrityMonitorProperties.DEPENDENCY_GROUPS).split(";"); + logger.info("dependency groups property = " + Arrays.toString(dep_groups)); + } catch (Exception e) { + logger.warn("Ignored invalid property: " + IntegrityMonitorProperties.DEPENDENCY_GROUPS); + } + } + + site_name = prop.getProperty(IntegrityMonitorProperties.SITE_NAME); + if (site_name == null) { + String msg = IntegrityMonitorProperties.SITE_NAME + " property is null"; + logger.error(msg); + throw new IntegrityMonitorPropertiesException("IntegrityMonitor Property Exception: " + msg); + }else{ + site_name = site_name.trim(); + } + + node_type = prop.getProperty(IntegrityMonitorProperties.NODE_TYPE); + if (node_type == null) { + String msg = IntegrityMonitorProperties.NODE_TYPE + " property is null"; + logger.error(msg); + throw new IntegrityMonitorPropertiesException("IntegrityMonitor Property Exception: " + msg); + } else { + node_type = node_type.trim(); + if (!isNodeTypeEnum(node_type)) { + String msg = IntegrityMonitorProperties.NODE_TYPE + " property " + node_type + " is invalid"; + logger.error(msg); + throw new IntegrityMonitorPropertiesException("IntegrityMonitor Property Exception: " + msg); + } + } + + if (prop.getProperty(IntegrityMonitorProperties.TEST_VIA_JMX) != null) { + String jmx_test = prop.getProperty(IntegrityMonitorProperties.TEST_VIA_JMX).trim(); + testViaJmx = Boolean.parseBoolean(jmx_test); + } + + if (prop.getProperty(IntegrityMonitorProperties.JMX_FQDN) != null) { + jmxFqdn = prop.getProperty(IntegrityMonitorProperties.JMX_FQDN).trim(); + if (jmxFqdn.isEmpty()) { + jmxFqdn = null; + } + } + + + if (prop.getProperty(IntegrityMonitorProperties.MAX_FPC_UPDATE_INTERVAL) != null) { + try { + maxFpcUpdateInterval = Integer.parseInt(prop.getProperty(IntegrityMonitorProperties.MAX_FPC_UPDATE_INTERVAL).trim()); + } catch (NumberFormatException e) { + logger.warn("Ignored invalid property: " + IntegrityMonitorProperties.MAX_FPC_UPDATE_INTERVAL); + } + } + + + return; + } + + public static void updateProperties(Properties newprop) { + if (isUnitTesting) { + try { + validateProperties(newprop); + } catch (IntegrityMonitorPropertiesException e) { + // ignore + } + } + else { + logger.info("Update integrity monitor properties not allowed"); + } + } + + private static boolean isNodeTypeEnum(String nodeType) { + for (NodeType n : NodeType.values()) { + if (n.toString().equals(nodeType)) { + return true; + } + } + return false; + } + + /** + * Look for "Forward Progress" -- if the 'FPMonitor' is stalled + * for too long, the operational state is changed to 'Disabled', + * and an alarm is set. The state is restored when forward + * progress continues. + */ + private void fpMonitorCycle() { + synchronized(fpMonitorCycleLock){ + // monitoring interval checks + if (monitorInterval <= 0) { + elapsedTime = 0; + return; // monitoring is disabled + } + + elapsedTime = elapsedTime + TimeUnit.MILLISECONDS.toSeconds(CYCLE_INTERVAL_MILLIS); + if (elapsedTime < monitorInterval) { + return; // monitoring interval not reached + } + + elapsedTime = 0; // reset elapsed time + + // TODO: check if alarm exists + + try { + if (fpCounter == lastFpCounter) { + // no forward progress + missedCycles += 1; + if (missedCycles >= failedCounterThreshold && !alarmExists) { + // set op state to disabled failed + fpcError = true; + logger.info("Forward progress not detected for resource " + resourceName + ". Setting state to disable failed."); + if(!(stateManager.getOpState()).equals(StateManagement.DISABLED)){ + // Note: The refreshStateAudit will make redundant calls + stateManager.disableFailed(); + }// The refreshStateAudit will catch the case where opStat = disabled and availState ! failed/dependency.failed + // TODO: raise alarm or Nagios alert + alarmExists = true; + } + } else { + // forward progress has occurred + lastFpCounter = fpCounter; + missedCycles = 0; + fpcError = false; + // set op state to enabled + logger.debug("Forward progress detected for resource " + resourceName + ". Setting state to enable not failed."); + if(!(stateManager.getOpState()).equals(StateManagement.ENABLED)){ + // Note: The refreshStateAudit will make redundant calls + stateManager.enableNotFailed(); + }// The refreshStateAudit will catch the case where opState=enabled and availStatus != null + + // TODO: clear alarm or Nagios alert + alarmExists = false; + } + } catch (Exception e) { + // log error + logger.error("FP Monitor encountered error. ", e); + } + } + } + + /** + * Execute a test transaction when test transaction interval has elapsed. + */ + private void checkTestTransaction() { + synchronized(checkTestTransactionLock){ + + // test transaction timer checks + if (testTransInterval <= 0) { + elapsedTestTransTime = 0; + return; // test transaction is disabled + } + + elapsedTestTransTime = elapsedTestTransTime + TimeUnit.MILLISECONDS.toSeconds(CYCLE_INTERVAL_MILLIS); + if (elapsedTestTransTime < testTransInterval) { + return; // test transaction interval not reached + } + + elapsedTestTransTime = 0; // reset elapsed time + + // execute test transaction + testTransaction(); + } + } + + /** + * Updates Fpc counter in database when write Fpc interval has elapsed. + */ + private void checkWriteFpc() { + synchronized(checkWriteFpcLock){ + + // test transaction timer checks + if (writeFpcInterval <= 0) { + elapsedWriteFpcTime = 0; + return; // write Fpc is disabled + } + + elapsedWriteFpcTime = elapsedWriteFpcTime + TimeUnit.MILLISECONDS.toSeconds(CYCLE_INTERVAL_MILLIS); + if (elapsedWriteFpcTime < writeFpcInterval) { + return; // write Fpc interval not reached + } + + elapsedWriteFpcTime = 0; // reset elapsed time + + // write Fpc to database + try { + writeFpc(); + } catch (Exception e) { + // ignore + } + } + } + + /** + * Execute a dependency health check periodically which also updates this resource's state. + */ + private void checkDependentHealth() { + logger.debug("checkDependentHealth: entry"); + + long currTime = System.currentTimeMillis(); + logger.debug("checkDependentHealth currTime - lastDependencyCheckTime = " + (currTime - lastDependencyCheckTime)); + if ((currTime - lastDependencyCheckTime) > (1000 * IntegrityMonitorProperties.DEFAULT_TEST_INTERVAL)) { + // execute dependency check and update this resource's state + + dependencyCheck(); + } + } + + /* + * This is a simple refresh audit which is periodically run to assure that the states and status + * attributes are aligned and notifications are sent to any listeners. It is possible for state/status + * to get out of synch and notified systems to be out of synch due to database corruption (manual or + * otherwise) or because a node became isolated. + * + * When the operation (lock/unlock) is called, it will cause a re-evaluation of the state and + * send a notification to all registered observers. + */ + private void refreshStateAudit(){ + synchronized(refreshStateAuditLock){ + logger.debug("refreshStateAudit: entry"); + Date now = new Date(); + long nowMs = now.getTime(); + long lastTimeMs = refreshStateAuditLastRunDate.getTime(); + logger.debug("refreshStateAudit: ms since last run = " + (nowMs - lastTimeMs)); + + if((nowMs - lastTimeMs) > refreshStateAuditIntervalMs){ + String adminState = stateManager.getAdminState(); + logger.debug("refreshStateAudit: adminState = " + adminState); + if(adminState.equals(StateManagement.LOCKED)){ + try { + logger.debug("refreshStateAudit: calling lock()"); + stateManager.lock(); + } catch (Exception e) { + logger.error("refreshStateAudit: caught unexpected exception from stateManager.lock(): " + e ); + System.out.println(new Date() + " refreshStateAudit: caught unexpected exception " + + "from stateManager.lock()"); + e.printStackTrace(); + } + }else{//unlocked + try { + logger.debug("refreshStateAudit: calling unlock()"); + stateManager.unlock();; + } catch (Exception e) { + logger.error("refreshStateAudit: caught unexpected exception from stateManager.unlock(): " + e ); + System.out.println(new Date() + " refreshStateAudit: caught unexpected exception " + + "from stateManager.unlock()"); + e.printStackTrace(); + } + } + refreshStateAuditLastRunDate = new Date(); + logger.debug("refreshStateAudit: exit"); + } + } + } + + /** + * The following nested class periodically performs the forward progress check, + * checks dependencies and does a refresh state audit. + */ + class FPManager extends Thread { + + // Constructor - start FP manager thread + FPManager() { + // set now as the last time the refreshStateAudit ran + IntegrityMonitor.this.refreshStateAuditLastRunDate = new Date(); + // start thread + this.start(); + } + + public void run() { + logger.info("FPManager thread running"); + while (true) { + try { + Thread.sleep(CYCLE_INTERVAL_MILLIS); + } catch (InterruptedException e) { + // The 'sleep' call was interrupted + continue; + } + + try { + if(logger.isDebugEnabled()){ + logger.debug("FPManager calling fpMonitorCycle()"); + } + // check forward progress timer + IntegrityMonitor.this.fpMonitorCycle(); + + if(logger.isDebugEnabled()){ + logger.debug("FPManager calling checkTestTransaction()"); + } + // check test transaction timer + IntegrityMonitor.this.checkTestTransaction(); + + if(logger.isDebugEnabled()){ + logger.debug("FPManager calling checkWriteFpc()"); + } + // check write Fpc timer + IntegrityMonitor.this.checkWriteFpc(); + + if(logger.isDebugEnabled()){ + logger.debug("FPManager calling checkDependentHealth()"); + } + // check dependency health + IntegrityMonitor.this.checkDependentHealth(); + + if(logger.isDebugEnabled()){ + logger.debug("FPManager calling refreshStateAudit()"); + } + // check if it is time to run the refreshStateAudit + IntegrityMonitor.this.refreshStateAudit(); + + } catch (Exception e) { + logger.debug("Ignore FPManager thread processing timer(s) exception: " + e); + } + } + } + + } + +} + diff --git a/integrity-monitor/src/main/java/org/openecomp/policy/common/im/IntegrityMonitorProperties.java b/integrity-monitor/src/main/java/org/openecomp/policy/common/im/IntegrityMonitorProperties.java new file mode 100644 index 00000000..8c3d7e6b --- /dev/null +++ b/integrity-monitor/src/main/java/org/openecomp/policy/common/im/IntegrityMonitorProperties.java @@ -0,0 +1,55 @@ +/*- + * ============LICENSE_START======================================================= + * Integrity Monitor + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.policy.common.im; + +public class IntegrityMonitorProperties { + + public static final String DEFAULT_DB_DRIVER = "org.h2.Driver"; + public static final String DEFAULT_DB_URL = "jdbc:h2:file:./sql/imTest"; + public static final String DEFAULT_DB_USER = "sa"; + public static final String DEFAULT_DB_PWD = ""; + + public static final String DB_DRIVER = "javax.persistence.jdbc.driver"; + public static final String DB_URL = "javax.persistence.jdbc.url"; + public static final String DB_USER = "javax.persistence.jdbc.user"; + public static final String DB_PWD = "javax.persistence.jdbc.password"; + + // intervals specified are in seconds + public static final int DEFAULT_MONITOR_INTERVAL = 30; + public static final int DEFAULT_FAILED_COUNTER_THRESHOLD = 3; + public static final int DEFAULT_TEST_INTERVAL = 10; //20; + public static final int DEFAULT_WRITE_FPC_INTERVAL = 5; + public static final int DEFAULT_MAX_FPC_UPDATE_INTERVAL = 60; + + public static final String FP_MONITOR_INTERVAL = "fp_monitor_interval"; + public static final String FAILED_COUNTER_THRESHOLD = "failed_counter_threshold"; + public static final String TEST_TRANS_INTERVAL = "test_trans_interval"; + public static final String WRITE_FPC_INTERVAL = "write_fpc_interval"; + + public static final String DEPENDENCY_GROUPS = "dependency_groups"; + public static final String SITE_NAME = "site_name"; + public static final String NODE_TYPE = "node_type"; + + public static final String TEST_VIA_JMX = "test_via_jmx"; + public static final String JMX_FQDN = "jmx_fqdn"; + public static final String MAX_FPC_UPDATE_INTERVAL = "max_fpc_update_interval"; + +} diff --git a/integrity-monitor/src/main/java/org/openecomp/policy/common/im/IntegrityMonitorPropertiesException.java b/integrity-monitor/src/main/java/org/openecomp/policy/common/im/IntegrityMonitorPropertiesException.java new file mode 100644 index 00000000..07737e14 --- /dev/null +++ b/integrity-monitor/src/main/java/org/openecomp/policy/common/im/IntegrityMonitorPropertiesException.java @@ -0,0 +1,37 @@ +/*- + * ============LICENSE_START======================================================= + * Integrity Monitor + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.policy.common.im; + +public class IntegrityMonitorPropertiesException extends Exception{ + private static final long serialVersionUID = 1L; + public IntegrityMonitorPropertiesException() { + } + public IntegrityMonitorPropertiesException(String message) { + super(message); + } + + public IntegrityMonitorPropertiesException(Throwable cause) { + super(cause); + } + public IntegrityMonitorPropertiesException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/integrity-monitor/src/main/java/org/openecomp/policy/common/im/StandbyStatusException.java b/integrity-monitor/src/main/java/org/openecomp/policy/common/im/StandbyStatusException.java new file mode 100644 index 00000000..3167dded --- /dev/null +++ b/integrity-monitor/src/main/java/org/openecomp/policy/common/im/StandbyStatusException.java @@ -0,0 +1,48 @@ +/*- + * ============LICENSE_START======================================================= + * Integrity Monitor + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.policy.common.im; + +public class StandbyStatusException extends Exception { + public StandbyStatusException() + { + } + + public StandbyStatusException(String message) + { + super(message); + } + + public StandbyStatusException(Throwable cause) + { + super(cause); + } + + public StandbyStatusException(String message, Throwable cause) + { + super(message, cause); + } + + public StandbyStatusException(String message, Throwable cause, + boolean enableSuppression, boolean writableStackTrace) + { + super(message, cause, enableSuppression, writableStackTrace); + } +} diff --git a/integrity-monitor/src/main/java/org/openecomp/policy/common/im/StateChangeNotifier.java b/integrity-monitor/src/main/java/org/openecomp/policy/common/im/StateChangeNotifier.java new file mode 100644 index 00000000..8906bb77 --- /dev/null +++ b/integrity-monitor/src/main/java/org/openecomp/policy/common/im/StateChangeNotifier.java @@ -0,0 +1,76 @@ +/*- + * ============LICENSE_START======================================================= + * Integrity Monitor + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.policy.common.im; + +import java.util.Observable; +import java.util.Observer; +/* + * This is implementing the Observer interface to make it specific for + * state management. + * + * It saves the StateManagement object and a String message that is + * passed in when notifyObservers is called by the Observable + * host class. + * + * It provides an abstract method for handling the state change + * so this class must be overwritten and made concrete for the + * Observer who is monitoring the state changes. + */ + +//import org.apache.log4j.Logger; +import org.openecomp.policy.common.logging.flexlogger.FlexLogger; +import org.openecomp.policy.common.logging.flexlogger.Logger; + +/** + * + * StateChangeNotifier class implements the Observer pattern and is used to distribute + * state change notifications to any entity that registers a derived class with an + * instance of the StateManagement class. + * + */ +public class StateChangeNotifier implements Observer { + private static final Logger logger = FlexLogger.getLogger(StateChangeNotifier.class); + //The observable class + StateManagement stateManagement; + + // A string argument passed by the observable class when + // Observable:notifyObservers(Object arg) is called + String message; + + @Override + public void update(Observable o, Object arg) { + this.stateManagement = (StateManagement) o; + this.message = (String) arg; + handleStateChange(); + } + + public void handleStateChange() { + logger.debug("handleStateChange, message: " + this.message); + } + + public StateManagement getStateManagement() { + return stateManagement; + } + + public String getMessage() { + return message; + } +} \ No newline at end of file diff --git a/integrity-monitor/src/main/java/org/openecomp/policy/common/im/StateElement.java b/integrity-monitor/src/main/java/org/openecomp/policy/common/im/StateElement.java new file mode 100644 index 00000000..6c6ce59c --- /dev/null +++ b/integrity-monitor/src/main/java/org/openecomp/policy/common/im/StateElement.java @@ -0,0 +1,160 @@ +/*- + * ============LICENSE_START======================================================= + * Integrity Monitor + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.policy.common.im; + +import java.util.*; + +//import org.apache.log4j.Logger; +import org.openecomp.policy.common.logging.flexlogger.FlexLogger; +import org.openecomp.policy.common.logging.flexlogger.Logger; + +public class StateElement { + private static final Logger logger = FlexLogger.getLogger(StateElement.class); + + String adminState = null; + String opState = null; + String availStatus = null; + String standbyStatus = null; + String actionName = null; + String endingAdminState = null; + String endingOpState = null; + String endingAvailStatus = null; + String endingStandbyStatus = null; + String exception = null; + + public void StateElement() + { + } + + public String getAdminState() + { + return this.adminState; + } + + public void setAdminState(String adminState) + { + this.adminState = adminState; + } + + public String getOpState() + { + return this.opState; + } + + public void setOpState(String opState) + { + this.opState = opState; + } + + public String getAvailStatus() + { + return this.availStatus; + } + + public void setAvailStatus(String availStatus) + { + this.availStatus = availStatus; + } + + public String getStandbyStatus() + { + return this.standbyStatus; + } + + public void setStandbyStatus(String standbyStatus) + { + this.standbyStatus = standbyStatus; + } + + public String getActionName() + { + return this.actionName; + } + + public void setActionName(String actionName) + { + this.actionName = actionName; + } + + public String getEndingAdminState() + { + return this.endingAdminState; + } + + public void setEndingAdminState(String endingAdminState) + { + this.endingAdminState = endingAdminState; + } + + public String getEndingOpState() + { + return this.endingOpState; + } + + public void setEndingOpState(String endingOpState) + { + this.endingOpState = endingOpState; + } + + public String getEndingAvailStatus() + { + return this.endingAvailStatus; + } + + public void setEndingAvailStatus(String endingAvailStatus) + { + this.endingAvailStatus = endingAvailStatus; + } + + public String getEndingStandbyStatus() + { + return this.endingStandbyStatus; + } + + public void setEndingStandbyStatus(String endingStandbyStatus) + { + this.endingStandbyStatus = endingStandbyStatus; + } + + public String getException() + { + return this.exception; + } + + public void setException(String exception) + { + this.exception = exception; + } + + public void displayStateElement() + { + logger.debug("adminState=[" + getAdminState() + + "], opState=[" + getOpState() + + "], availStatus=[" + getAvailStatus() + + "], standbyStatus=[" + getStandbyStatus() + + "], actionName=[" + getActionName() + + "], endingAdminState=[" + getEndingAdminState() + + "], endingOpState=[" + getEndingOpState() + + "], endingAvailStatus=[" + getEndingAvailStatus() + + "], endingStandbyStatus=[" + getEndingStandbyStatus() + + "], exception=[" + getException() + "]"); + } +} diff --git a/integrity-monitor/src/main/java/org/openecomp/policy/common/im/StateManagement.java b/integrity-monitor/src/main/java/org/openecomp/policy/common/im/StateManagement.java new file mode 100644 index 00000000..14d35e1d --- /dev/null +++ b/integrity-monitor/src/main/java/org/openecomp/policy/common/im/StateManagement.java @@ -0,0 +1,1015 @@ +/*- + * ============LICENSE_START======================================================= + * Integrity Monitor + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.policy.common.im; + +import java.util.*; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.EntityTransaction; +import javax.persistence.FlushModeType; +import javax.persistence.LockModeType; +import javax.persistence.Query; + +//import org.apache.log4j.Logger; + +import org.openecomp.policy.common.im.jpa.StateManagementEntity; +import org.openecomp.policy.common.im.StateElement; +import org.openecomp.policy.common.im.StandbyStatusException; +import org.openecomp.policy.common.im.StateChangeNotifier; +import org.openecomp.policy.common.logging.flexlogger.FlexLogger; +import org.openecomp.policy.common.logging.flexlogger.Logger; + +/** + * + * StateManagement class handles all state changes per the Telecom standard X.731. + * It extends the Observable class and, thus, has an interface to register + * instances of the StateChangeNotifier/Observer class. When any state change + * occurs, the registered observers are notified. + * + */ +public class StateManagement extends Observable { + private static final Logger logger = FlexLogger.getLogger(StateManagement.class); + public static final String LOCKED = "locked"; + public static final String UNLOCKED = "unlocked"; + public static final String ENABLED = "enabled"; + public static final String DISABLED = "disabled"; + public static final String ENABLE_NOT_FAILED = "enableNotFailed"; + public static final String DISABLE_FAILED = "disableFailed"; + public static final String FAILED = "failed"; + public static final String DEPENDENCY = "dependency"; + public static final String DEPENDENCY_FAILED = "dependency,failed"; + public static final String DISABLE_DEPENDENCY = "disableDependency"; + public static final String ENABLE_NO_DEPENDENCY = "enableNoDependency"; + public static final String NULL_VALUE = "null"; + public static final String LOCK = "lock"; + public static final String UNLOCK = "unlock"; + public static final String PROMOTE = "promote"; + public static final String DEMOTE = "demote"; + public static final String HOT_STANDBY = "hotstandby"; + public static final String COLD_STANDBY = "coldstandby"; + public static final String PROVIDING_SERVICE = "providingservice"; + + public static final String ADMIN_STATE = "adminState"; + public static final String OPERATION_STATE = "opState"; + public static final String AVAILABLE_STATUS= "availStatus"; + public static final String STANDBY_STATUS = "standbyStatus"; + + private static final String REMOVE = "remove"; + private static final String ADD = "add"; + + private String resourceName = null; + private String adminState = null; + private String opState = null; + private String availStatus = null; + private String standbyStatus = null; + private EntityManager em; + private EntityManagerFactory emf = null; + private StateTransition st = null; + + /* + * Guarantees single-threadedness of all actions. Only one action can execute + * at a time. That avoids race conditions between actions being called + * from different places. + * + * Some actions can take significant time to complete and, if another conflicting + * action is called during its execution, it could put the system in an inconsistent + * state. This very thing happened when demote was called and the active/standby + * algorithm, seeing the state attempted to promote the PDP-D. + * + */ + private static final Object SYNCLOCK = new Object(); + private static final Object FLUSHLOCK = new Object(); + + /** + * StateManagement constructor + * @param emf + * @param resourceName + * @throws Exception + */ + public StateManagement(EntityManagerFactory emf, String resourceName) throws Exception + { + logger.debug("StateManagement: constructor, resourceName: " + resourceName); + this.emf = emf; + em = emf.createEntityManager(); + EntityTransaction et = em.getTransaction(); + + if(!et.isActive()){ + et.begin(); + } + this.resourceName = resourceName; + logger.info("resourceName = " + this.resourceName); + + + try { + //Create a StateManagementEntity object + logger.debug("findStateManagementEntity for " + this.resourceName); + StateManagementEntity sm = findStateManagementEntity(em, this.resourceName); + + //persist the administrative state + if (sm != null) { + logger.debug("Persist adminstrative state, resourceName = " + this.resourceName); + em.persist(sm); + synchronized(FLUSHLOCK){ + em.flush(); + if(et.isActive()){ + et.commit(); + } + } + } else { + synchronized(FLUSHLOCK){ + if(et.isActive()){ + et.commit(); + } + } + } + + //Load the StateTransition hash table + st = new StateTransition(); + + logger.debug("StateManagement: constructor end, resourceName: " + this.resourceName); + } catch(Exception ex) { + synchronized(FLUSHLOCK){ + if(et.isActive()){ + et.commit(); + } + } + ex.printStackTrace(); + logger.error("StateManagement: constructor caught unexpected exception: " + ex); + throw new Exception("StateManagement: Exception: " + ex.toString()); + } + } + + /** + * initializeState() is called when it is necessary to set the StateManagement to a known initial state. + * It preserves the Administrative State since it must persist across node reboots. + * Starting from this state, the IntegrityMonitory will determine the Operational State and the + * owning application will set the StandbyStatus. + */ + public void initializeState() throws Exception + { + synchronized (SYNCLOCK){ + logger.debug("\nStateManagement: SYNCLOCK initializeState() operation for resourceName = " + this.resourceName + "\n"); + logger.debug("StateManagement: initializeState() operation started, resourceName = " + this.resourceName); + EntityTransaction et = em.getTransaction(); + + if(!et.isActive()){ + et.begin(); + } + + try { + logger.debug("findStateManagementEntity for " + this.resourceName); + StateManagementEntity sm = findStateManagementEntity(em, this.resourceName); + // set state + sm.setAdminState(sm.getAdminState()); //preserve the Admin state + sm.setOpState(StateManagement.ENABLED); + sm.setAvailStatus(StateManagement.NULL_VALUE); + sm.setStandbyStatus(StateManagement.NULL_VALUE); + + em.persist(sm); + synchronized(FLUSHLOCK){ + em.flush(); + if(et.isActive()){ + et.commit(); + } + } + setChanged(); + notifyObservers(ADMIN_STATE); + + logger.debug("StateManagement: initializeState() operation completed, resourceName = " + this.resourceName); + } catch(Exception ex) { + synchronized(FLUSHLOCK){ + if(et.isActive()){ + et.commit(); + } + } + ex.printStackTrace(); + logger.error("StateManagement.initializeState() caught unexpected exception: " + ex); + throw new Exception("StateManagement.initializeState() Exception: " + ex); + } + } + } + + /** + * lock() changes the administrative state to locked. + * @throws Exception + */ + public void lock() throws Exception + { + synchronized (SYNCLOCK){ + logger.debug("\nStateManagement: SYNCLOCK lock() operation for resourceName = " + this.resourceName + "\n"); + logger.debug("StateManagement: lock() operation started, resourceName = " + this.resourceName); + EntityTransaction et = em.getTransaction(); + + if(!et.isActive()){ + et.begin(); + } + + try { + logger.debug("findStateManagementEntity for " + this.resourceName); + StateManagementEntity sm = findStateManagementEntity(em, this.resourceName); + + StateElement stateElement = st.getEndingState(sm.getAdminState(), sm.getOpState(), + sm.getAvailStatus(), sm.getStandbyStatus(), LOCK); + + sm.setAdminState(stateElement.getEndingAdminState()); + sm.setOpState(stateElement.getEndingOpState()); + sm.setAvailStatus(stateElement.getEndingAvailStatus()); + sm.setStandbyStatus(stateElement.getEndingStandbyStatus()); + + em.persist(sm); + synchronized(FLUSHLOCK){ + em.flush(); + if(et.isActive()){ + et.commit(); + } + } + setChanged(); + notifyObservers(ADMIN_STATE); + + logger.debug("StateManagement: lock() operation completed, resourceName = " + this.resourceName); + } catch(Exception ex) { + synchronized(FLUSHLOCK){ + if(et.isActive()){ + et.commit(); + } + } + ex.printStackTrace(); + logger.error("StateManagement.lock() caught unexpected exception: " + ex); + throw new Exception("StateManagement.lock() Exception: " + ex.toString()); + } + } + } + + /** + * unlock() changes the administrative state to unlocked. + * @throws Exception + */ + public void unlock() throws Exception + { + synchronized (SYNCLOCK){ + logger.debug("\nStateManagement: SYNCLOCK unlock() operation for resourceName = " + this.resourceName + "\n"); + logger.debug("StateManagement: unlock() operation started, resourceName = " + this.resourceName); + EntityTransaction et = em.getTransaction(); + + if(!et.isActive()){ + et.begin(); + } + + try { + logger.debug("findStateManagementEntity for " + this.resourceName); + StateManagementEntity sm = findStateManagementEntity(em, this.resourceName); + StateElement stateElement = st.getEndingState(sm.getAdminState(), sm.getOpState(), + sm.getAvailStatus(), sm.getStandbyStatus(), UNLOCK); + // set transition state + sm.setAdminState(stateElement.getEndingAdminState()); + sm.setOpState(stateElement.getEndingOpState()); + sm.setAvailStatus(stateElement.getEndingAvailStatus()); + sm.setStandbyStatus(stateElement.getEndingStandbyStatus()); + + em.persist(sm); + synchronized(FLUSHLOCK){ + em.flush(); + if(et.isActive()){ + et.commit(); + } + } + setChanged(); + notifyObservers(ADMIN_STATE); + + logger.debug("StateManagement: unlock() operation completed, resourceName = " + this.resourceName); + } catch(Exception ex) { + synchronized(FLUSHLOCK){ + if(et.isActive()){ + et.commit(); + } + } + ex.printStackTrace(); + logger.error("StateManagement.unlock() caught unexpected exception: " + ex); + throw new Exception("StateManagement.unlock() Exception: " + ex); + } + } + } + + /** + * enableNotFailed() removes the "failed" availability status and changes the operational + * state to enabled if no dependency is also failed. + * @throws Exception + */ + public void enableNotFailed() throws Exception + { + synchronized (SYNCLOCK){ + logger.debug("\nStateManagement: SYNCLOCK enabledNotFailed() operation for resourceName = " + this.resourceName + "\n"); + logger.debug("StateManagement: enableNotFailed() operation started, resourceName = " + this.resourceName); + EntityTransaction et = em.getTransaction(); + + if(!et.isActive()){ + et.begin(); + } + + try { + logger.debug("findStateManagementEntity for " + this.resourceName); + StateManagementEntity sm = findStateManagementEntity(em, this.resourceName); + StateElement stateElement = st.getEndingState(sm.getAdminState(), sm.getOpState(), + sm.getAvailStatus(), sm.getStandbyStatus(), ENABLE_NOT_FAILED); + // set transition state + sm.setAdminState(stateElement.getEndingAdminState()); + sm.setOpState(stateElement.getEndingOpState()); + sm.setAvailStatus(stateElement.getEndingAvailStatus()); + sm.setStandbyStatus(stateElement.getEndingStandbyStatus()); + + em.persist(sm); + synchronized(FLUSHLOCK){ + em.flush(); + if(et.isActive()){ + et.commit(); + } + } + setChanged(); + notifyObservers(OPERATION_STATE); + + logger.debug("StateManagement enableNotFailed() operation completed, resourceName = " + this.resourceName); + } catch(Exception ex) { + synchronized(FLUSHLOCK){ + if(et.isActive()){ + et.commit(); + } + } + ex.printStackTrace(); + logger.error("StateManagement.enableNotFailed() caught unexpected exception: " + ex); + throw new Exception("StateManagement.enableNotFailed() Exception: " + ex); + } + } + } + + /** + * disableFailed() changes the operational state to disabled and adds availability status of "failed" + * @throws Exception + */ + public void disableFailed() throws Exception + { + synchronized (SYNCLOCK){ + logger.debug("\nStateManagement: SYNCLOCK disabledFailed() operation for resourceName = " + this.resourceName + "\n"); + logger.debug("StateManagement: disableFailed() operation started, resourceName = " + this.resourceName); + EntityTransaction et = em.getTransaction(); + if(!et.isActive()){ + et.begin(); + } + + try { + logger.debug("findStateManagementEntity for " + this.resourceName); + StateManagementEntity sm = findStateManagementEntity(em, this.resourceName); + StateElement stateElement = st.getEndingState(sm.getAdminState(), sm.getOpState(), + sm.getAvailStatus(), sm.getStandbyStatus(), DISABLE_FAILED); + // set transition state + sm.setAdminState(stateElement.getEndingAdminState()); + sm.setOpState(stateElement.getEndingOpState()); + sm.setAvailStatus(stateElement.getEndingAvailStatus()); + sm.setStandbyStatus(stateElement.getEndingStandbyStatus()); + + em.persist(sm); + synchronized(FLUSHLOCK){ + em.flush(); + if(et.isActive()){ + et.commit(); + } + } + setChanged(); + notifyObservers(OPERATION_STATE); + + logger.debug("StateManagement: disableFailed() operation completed, resourceName = " + this.resourceName); + } catch(Exception ex) { + synchronized(FLUSHLOCK){ + if(et.isActive()){ + et.commit(); + } + } + ex.printStackTrace(); + logger.error("StateManagement.disableFailed() caught unexpected exception: " + ex); + throw new Exception("StateManagement.disableFailed() Exception: " + ex); + } + } + } + /** + * This version of disableFailed is to be used to manipulate the state of a remote resource in the event + * that remote resource has failed but its state is still showing that it is viable. + * @throws Exception + */ + public void disableFailed(String otherResourceName) throws Exception + { + synchronized (SYNCLOCK){ + if(otherResourceName == null){ + logger.error("\nStateManagement: SYNCLOCK disableFailed(otherResourceName) operation: resourceName is NULL.\n"); + return; + } + logger.debug("\nStateManagement: SYNCLOCK disabledFailed(otherResourceName) operation for resourceName = " + + otherResourceName + "\n"); + logger.debug("StateManagement: disableFailed(otherResourceName) operation started, resourceName = " + + otherResourceName); + EntityTransaction et = em.getTransaction(); + if(!et.isActive()){ + et.begin(); + } + + try { + logger.debug("findStateManagementEntity for " + otherResourceName); + StateManagementEntity sm = findStateManagementEntity(em, otherResourceName); + StateElement stateElement = st.getEndingState(sm.getAdminState(), sm.getOpState(), + sm.getAvailStatus(), sm.getStandbyStatus(), DISABLE_FAILED); + // set transition state + sm.setAdminState(stateElement.getEndingAdminState()); + sm.setOpState(stateElement.getEndingOpState()); + sm.setAvailStatus(stateElement.getEndingAvailStatus()); + sm.setStandbyStatus(stateElement.getEndingStandbyStatus()); + + em.persist(sm); + synchronized(FLUSHLOCK){ + em.flush(); + if(et.isActive()){ + et.commit(); + } + } + setChanged(); + notifyObservers(OPERATION_STATE); + + logger.debug("StateManagement: disableFailed(otherResourceName) operation completed, resourceName = " + + otherResourceName); + } catch(Exception ex) { + synchronized(FLUSHLOCK){ + if(et.isActive()){ + et.commit(); + } + } + ex.printStackTrace(); + logger.error("StateManagement.disableFailed(otherResourceName) caught unexpected exception: " + ex); + throw new Exception("StateManagement.disableFailed(otherResourceName) Exception: " + ex); + } + } + } + + /** + * disableDependency() changes operational state to disabled and adds availability status of "dependency" + * @throws Exception + */ + public void disableDependency() throws Exception + { + synchronized (SYNCLOCK){ + logger.debug("\nStateManagement: SYNCLOCK disableDependency() operation for resourceName = " + this.resourceName + "\n"); + logger.debug("StateManagement: disableDependency() operation started, resourceName = " + this.resourceName); + EntityTransaction et = em.getTransaction(); + + if(!et.isActive()){ + et.begin(); + } + + try { + logger.debug("findStateManagementEntity for " + this.resourceName); + StateManagementEntity sm = findStateManagementEntity(em, this.resourceName); + StateElement stateElement = st.getEndingState(sm.getAdminState(), sm.getOpState(), + sm.getAvailStatus(), sm.getStandbyStatus(), DISABLE_DEPENDENCY); + // set transition state + sm.setAdminState(stateElement.getEndingAdminState()); + sm.setOpState(stateElement.getEndingOpState()); + sm.setAvailStatus(stateElement.getEndingAvailStatus()); + sm.setStandbyStatus(stateElement.getEndingStandbyStatus()); + + em.persist(sm); + synchronized(FLUSHLOCK){ + em.flush(); + if(et.isActive()){ + et.commit(); + } + } + setChanged(); + notifyObservers(OPERATION_STATE); + + logger.debug("StateManagement: disableDependency() operation completed, resourceName = " + this.resourceName); + } catch(Exception ex) { + synchronized(FLUSHLOCK){ + if(et.isActive()){ + et.commit(); + } + } + ex.printStackTrace(); + logger.error("StateManagement.disableDependency() caught unexpected exception: " + ex); + throw new Exception("StateManagement.disableDependency() Exception: " + ex); + } + } + } + + /** + * enableNoDependency() removes the availability status of "dependency " and will change the + * operational state to enabled if not otherwise failed. + * @throws Exception + */ + public void enableNoDependency() throws Exception + { + synchronized (SYNCLOCK){ + logger.debug("\nStateManagement: SYNCLOCK enableNoDependency() operation for resourceName = " + this.resourceName + "\n"); + logger.debug("StateManagement: enableNoDependency() operation started, resourceName = " + this.resourceName); + EntityTransaction et = em.getTransaction(); + + if(!et.isActive()){ + et.begin(); + } + + try { + logger.debug("findStateManagementEntity for " + this.resourceName); + StateManagementEntity sm = findStateManagementEntity(em, this.resourceName); + StateElement stateElement = st.getEndingState(sm.getAdminState(), sm.getOpState(), + sm.getAvailStatus(), sm.getStandbyStatus(), ENABLE_NO_DEPENDENCY); + // set transition state + sm.setAdminState(stateElement.getEndingAdminState()); + sm.setOpState(stateElement.getEndingOpState()); + sm.setAvailStatus(stateElement.getEndingAvailStatus()); + sm.setStandbyStatus(stateElement.getEndingStandbyStatus()); + + em.persist(sm); + synchronized(FLUSHLOCK){ + em.flush(); + if(et.isActive()){ + et.commit(); + } + } + setChanged(); + notifyObservers(OPERATION_STATE); + + logger.debug("StateManagement: enableNoDependency() operation completed, resourceName = " + this.resourceName); + } catch(Exception ex) { + synchronized(FLUSHLOCK){ + if(et.isActive()){ + et.commit(); + } + } + ex.printStackTrace(); + logger.error("StateManagement.enableNoDependency() caught unexpected exception: " + ex); + throw new Exception("StateManagement.enableNoDependency() Exception: " + ex); + } + } + } + + /** + * promote() changes the standby status to providingservice if not otherwise failed. + * @throws StandbyStatusException + * @throws Exception + */ + public void promote() throws StandbyStatusException, Exception + { + synchronized (SYNCLOCK){ + logger.debug("\nStateManagement: SYNCLOCK promote() operation for resourceName = " + this.resourceName + "\n"); + logger.debug("StateManagement: promote() operation started, resourceName = " + this.resourceName); + EntityTransaction et = em.getTransaction(); + + if(!et.isActive()){ + et.begin(); + } + + StateManagementEntity sm; + + try{ + logger.debug("findStateManagementEntity for " + this.resourceName); + sm = findStateManagementEntity(em, this.resourceName); + StateElement stateElement = st.getEndingState(sm.getAdminState(), sm.getOpState(), + sm.getAvailStatus(), sm.getStandbyStatus(), PROMOTE); + // set transition state + sm.setAdminState(stateElement.getEndingAdminState()); + sm.setOpState(stateElement.getEndingOpState()); + sm.setAvailStatus(stateElement.getEndingAvailStatus()); + sm.setStandbyStatus(stateElement.getEndingStandbyStatus()); + + em.persist(sm); + synchronized(FLUSHLOCK){ + em.flush(); + if(et.isActive()){ + et.commit(); + } + } + setChanged(); + notifyObservers(STANDBY_STATUS); + }catch(Exception ex){ + synchronized(FLUSHLOCK){ + if(et.isActive()){ + et.commit(); + } + } + ex.printStackTrace(); + logger.error("StateManagement.promote() caught unexpected exception: " + ex); + throw new Exception("StateManagement.promote() Exception: " + ex); + } + + logger.debug("StateManagement: promote() operation completed, resourceName = " + this.resourceName); + if (sm.getStandbyStatus().equals(StateManagement.COLD_STANDBY)){ + String msg = "Failure to promote " + this.resourceName + " StandbyStatus = " + StateManagement.COLD_STANDBY; + throw new StandbyStatusException(msg); + } + } + } + + /** + * demote() changes standbystatus to hotstandby or, if failed, coldstandby + * @throws Exception + */ + public void demote() throws Exception + { + synchronized (SYNCLOCK){ + logger.debug("\nStateManagement: SYNCLOCK demote() operation for resourceName = " + this.resourceName + "\n"); + logger.debug("StateManagement: demote() operation started, resourceName = " + this.resourceName); + EntityTransaction et = em.getTransaction(); + + if(!et.isActive()){ + et.begin(); + } + + try { + logger.debug("findStateManagementEntity for " + this.resourceName); + StateManagementEntity sm = findStateManagementEntity(em, this.resourceName); + StateElement stateElement = st.getEndingState(sm.getAdminState(), sm.getOpState(), + sm.getAvailStatus(), sm.getStandbyStatus(), DEMOTE); + // set transition state + sm.setAdminState(stateElement.getEndingAdminState()); + sm.setOpState(stateElement.getEndingOpState()); + sm.setAvailStatus(stateElement.getEndingAvailStatus()); + sm.setStandbyStatus(stateElement.getEndingStandbyStatus()); + + em.persist(sm); + synchronized(FLUSHLOCK){ + em.flush(); + if(et.isActive()){ + et.commit(); + } + } + setChanged(); + notifyObservers(STANDBY_STATUS); + + logger.debug("StateManagement: demote() operation completed, resourceName = " + this.resourceName); + } catch(Exception ex) { + synchronized(FLUSHLOCK){ + if(et.isActive()){ + et.commit(); + } + } + ex.printStackTrace(); + logger.error("StateManagement.demote() caught unexpected exception: " + ex); + throw new Exception("StateManagement.demote() Exception: " + ex); + } + } + } + + /** + * + * Only used for a remote resource. It will not notify observers. It is used only in cases where + * the remote resource has failed is such a way that it cannot update its own states. In particular + * this is observed by PDP-D DroolsPdpsElectionHandler when it is trying to determine which PDP-D should + * be designated as the lead. + * @param otherResourceName + * @throws Exception + */ + public void demote(String otherResourceName) throws Exception + { + synchronized (SYNCLOCK){ + if(otherResourceName==null){ + logger.error("\nStateManagement: SYNCLOCK demote(otherResourceName) operation: resourceName is NULL.\n"); + return; + } + logger.debug("\nStateManagement: SYNCLOCK demote(otherResourceName) operation for resourceName = " + otherResourceName + "\n"); + + EntityTransaction et = em.getTransaction(); + + if(!et.isActive()){ + et.begin(); + } + + try { + logger.debug("StateManagement: SYNCLOCK demote(otherResourceName) findStateManagementEntity for " + otherResourceName); + StateManagementEntity sm = findStateManagementEntity(em, otherResourceName); + StateElement stateElement = st.getEndingState(sm.getAdminState(), sm.getOpState(), + sm.getAvailStatus(), sm.getStandbyStatus(), DEMOTE); + // set transition state + sm.setAdminState(stateElement.getEndingAdminState()); + sm.setOpState(stateElement.getEndingOpState()); + sm.setAvailStatus(stateElement.getEndingAvailStatus()); + sm.setStandbyStatus(stateElement.getEndingStandbyStatus()); + + em.persist(sm); + synchronized(FLUSHLOCK){ + em.flush(); + if(et.isActive()){ + et.commit(); + } + } + //We don't notify observers because this is assumed to be a remote resource + + logger.debug("StateManagement: demote(otherResourceName) operation completed, resourceName = " + otherResourceName); + } catch(Exception ex) { + synchronized(FLUSHLOCK){ + if(et.isActive()){ + et.commit(); + } + } + ex.printStackTrace(); + logger.error("StateManagement.demote(otherResourceName) caught unexpected exception: " + ex); + throw new Exception("StateManagement.demote(otherResourceName) Exception: " + ex); + } + } + } + + /** + * @return + */ +public String getAdminState() + { + logger.debug("StateManagement(6/1/16): getAdminState for resourceName " + this.resourceName); + try { + Query query = em.createQuery("Select p from StateManagementEntity p where p.resourceName=:resource"); + + query.setParameter("resource", this.resourceName); + + //Just test that we are retrieving the right object + @SuppressWarnings("rawtypes") + List resourceList = query.setLockMode( + LockModeType.NONE).setFlushMode(FlushModeType.COMMIT).getResultList(); + if (!resourceList.isEmpty()) { + // exist + StateManagementEntity stateManagementEntity = (StateManagementEntity) resourceList.get(0); + // refresh the object from DB in case cached data was returned + em.refresh(stateManagementEntity); + this.adminState = stateManagementEntity.getAdminState(); + } else { + this.adminState = null; + } + } catch(Exception ex) { + ex.printStackTrace(); + logger.error("StateManagement: getAdminState exception: " + ex.toString()); + } + + return this.adminState; + } + + /** + * @return + */ +public String getOpState() + { + logger.debug("StateManagement(6/1/16): getOpState for resourceName " + this.resourceName); + try { + Query query = em.createQuery("Select p from StateManagementEntity p where p.resourceName=:resource"); + + query.setParameter("resource", this.resourceName); + + //Just test that we are retrieving the right object + @SuppressWarnings("rawtypes") + List resourceList = query.setLockMode( + LockModeType.NONE).setFlushMode(FlushModeType.COMMIT).getResultList(); + if (!resourceList.isEmpty()) { + // exist + StateManagementEntity stateManagementEntity = (StateManagementEntity) resourceList.get(0); + // refresh the object from DB in case cached data was returned + em.refresh(stateManagementEntity); + this.opState = stateManagementEntity.getOpState(); + } else { + this.opState = null; + } + } catch(Exception ex) { + ex.printStackTrace(); + logger.error("StateManagement: getOpState exception: " + ex.toString()); + } + + return this.opState; + } + + /** + * @return + */ + public String getAvailStatus() + { + logger.debug("StateManagement(6/1/16): getAvailStatus for resourceName " + this.resourceName); + try { + Query query = em.createQuery("Select p from StateManagementEntity p where p.resourceName=:resource"); + + query.setParameter("resource", this.resourceName); + + //Just test that we are retrieving the right object + @SuppressWarnings("rawtypes") + List resourceList = query.setLockMode( + LockModeType.NONE).setFlushMode(FlushModeType.COMMIT).getResultList(); + if (!resourceList.isEmpty()) { + // exist + StateManagementEntity stateManagementEntity = (StateManagementEntity) resourceList.get(0); + // refresh the object from DB in case cached data was returned + em.refresh(stateManagementEntity); + this.availStatus = stateManagementEntity.getAvailStatus(); + } else { + this.availStatus = null; + } + } catch(Exception ex) { + ex.printStackTrace(); + logger.error("StateManagement: getAvailStatus exception: " + ex.toString()); + } + + return this.availStatus; + } + + /** + * @return + */ + public String getStandbyStatus() + { + logger.debug("StateManagement(6/1/16): getStandbyStatus for resourceName " + this.resourceName); + try { + Query query = em.createQuery("Select p from StateManagementEntity p where p.resourceName=:resource"); + + query.setParameter("resource", this.resourceName); + + //Just test that we are retrieving the right object + @SuppressWarnings("rawtypes") + List resourceList = query.setLockMode( + LockModeType.NONE).setFlushMode(FlushModeType.COMMIT).getResultList(); + if (!resourceList.isEmpty()) { + // exist + StateManagementEntity stateManagementEntity = (StateManagementEntity) resourceList.get(0); + // refresh the object from DB in case cached data was returned + em.refresh(stateManagementEntity); + this.standbyStatus = stateManagementEntity.getStandbyStatus(); + } else { + this.standbyStatus = null; + } + } catch(Exception ex) { + ex.printStackTrace(); + logger.error("StateManagement: getStandbyStatus exception: " + ex.toString()); + } + + return this.standbyStatus; + } + + /** + * Find a StateManagementEntity + * @param em + * @param otherResourceName + * @return + */ + private static StateManagementEntity findStateManagementEntity(EntityManager em, String otherResourceName) + { + logger.debug("StateManagementEntity: findStateManagementEntity: Entry"); + StateManagementEntity stateManagementEntity = null; + try { + Query query = em.createQuery("Select p from StateManagementEntity p where p.resourceName=:resource"); + + query.setParameter("resource", otherResourceName); + + //Just test that we are retrieving the right object + @SuppressWarnings("rawtypes") + List resourceList = query.setLockMode( + LockModeType.NONE).setFlushMode(FlushModeType.COMMIT).getResultList(); + if (!resourceList.isEmpty()) { + // exist + stateManagementEntity = (StateManagementEntity) resourceList.get(0); + // refresh the object from DB in case cached data was returned + em.refresh(stateManagementEntity); + stateManagementEntity.setModifiedDate(new Date()); + } else { + // not exist - create one + stateManagementEntity = new StateManagementEntity(); + stateManagementEntity.setResourceName(otherResourceName); + stateManagementEntity.setAdminState(UNLOCKED); + stateManagementEntity.setOpState(ENABLED); + stateManagementEntity.setAvailStatus(NULL_VALUE); + stateManagementEntity.setStandbyStatus(NULL_VALUE); // default + } + } catch(Exception ex) { + ex.printStackTrace(); + logger.error("findStateManagementEntity exception: " + ex.toString()); + } + return stateManagementEntity; + } + + /** + * Get the standbystatus of a particular resource + * @param otherResourceName + * @return + */ + public String getStandbyStatus(String otherResourceName) { + + if (logger.isDebugEnabled()) { + logger.debug("StateManagement: getStandbyStatus: Entering, resourceName='" + + otherResourceName + "'"); + } + + String standbyStatus = null; + + EntityTransaction et = em.getTransaction(); + if(!et.isActive()){ + et.begin(); + } + try { + + Query stateManagementListQuery = em + .createQuery("SELECT p FROM StateManagementEntity p WHERE p.resourceName=:resource"); + stateManagementListQuery.setParameter("resource", otherResourceName); + List stateManagementList = stateManagementListQuery.setLockMode( + LockModeType.NONE).setFlushMode(FlushModeType.COMMIT).getResultList(); + if (stateManagementList.size() == 1 + && stateManagementList.get(0) instanceof StateManagementEntity) { + StateManagementEntity stateManagementEntity = (StateManagementEntity) stateManagementList + .get(0); + // refresh the object from DB in case cached data was returned + em.refresh(stateManagementEntity); + standbyStatus = stateManagementEntity.getStandbyStatus(); + if (logger.isDebugEnabled()) { + logger.debug("getStandbyStatus: resourceName =" + otherResourceName + + " has standbyStatus=" + standbyStatus); + } + } else { + logger.error("getStandbyStatus: resourceName =" + otherResourceName + + " not found in statemanagemententity table"); + } + } catch (Exception e) { + e.printStackTrace(); + logger.error("getStandbyStatus: Caught Exception attempting to get statemanagemententity record, message='" + + e.getMessage() + "'"); + } + synchronized(FLUSHLOCK){ + if(et.isActive()){ + et.commit(); + } + } + + if (logger.isDebugEnabled()) { + logger.debug("getStandbyStatus: Returning standbyStatus=" + + standbyStatus); + } + + return standbyStatus; + } + + /** + * Clean up all the StateManagementEntities + */ + public void deleteAllStateManagementEntities() { + + logger.info("StateManagement: deleteAllStateManagementEntities: Entering"); + + /* + * Start transaction + */ + EntityTransaction et = em.getTransaction(); + if(!et.isActive()){ + et.begin(); + } + + try{ + Query stateManagementEntityListQuery = em + .createQuery("SELECT p FROM StateManagementEntity p"); + @SuppressWarnings("unchecked") + List stateManagementEntityList = stateManagementEntityListQuery.setLockMode( + LockModeType.NONE).setFlushMode(FlushModeType.COMMIT).getResultList(); + logger.info("deleteAllStateManagementEntities: Deleting " + + stateManagementEntityList.size() + + " StateManagementEntity records"); + for (StateManagementEntity stateManagementEntity : stateManagementEntityList) { + logger.info("deleteAllStateManagementEntities: Deleting statemanagemententity with resourceName=" + + stateManagementEntity.getResourceName() + " and standbyStatus=" + + stateManagementEntity.getStandbyStatus()); + em.remove(stateManagementEntity); + } + }catch(Exception ex){ + synchronized(FLUSHLOCK){ + if(et.isActive()){ + et.commit(); + } + } + ex.printStackTrace(); + logger.error("StateManagement.deleteAllStateManagementEntities() caught Exception: " + ex); + } + + /* + * End transaction. + */ + synchronized(FLUSHLOCK){ + if(et.isActive()){ + et.commit(); + } + } + + logger.info("deleteAllStateManagementEntities: Exiting"); + + } + +} diff --git a/integrity-monitor/src/main/java/org/openecomp/policy/common/im/StateTransition.java b/integrity-monitor/src/main/java/org/openecomp/policy/common/im/StateTransition.java new file mode 100644 index 00000000..3bc5bbc7 --- /dev/null +++ b/integrity-monitor/src/main/java/org/openecomp/policy/common/im/StateTransition.java @@ -0,0 +1,726 @@ +/*- + * ============LICENSE_START======================================================= + * Integrity Monitor + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.policy.common.im; + +import java.util.*; + +//import org.apache.log4j.Logger; + +import org.openecomp.policy.common.im.StateElement; +import org.openecomp.policy.common.im.StateManagement; +import org.openecomp.policy.common.logging.flexlogger.FlexLogger; +import org.openecomp.policy.common.logging.flexlogger.Logger; + +/** + * The StateTransition class coordinates all state transitions. + */ +public class StateTransition { + private static final Logger logger = FlexLogger.getLogger(StateTransition.class); + + public static final String ADMIN_STATE = "adminState"; + public static final String OPERATION_STATE = "opState"; + public static final String AVAILABLE_STATUS= "availStatus"; + public static final String STANDBY_STATUS = "standbyStatus"; + public static final String ACTOIN_NAME = "actionName"; + + private HashMap StateTable = new HashMap(); + + /** + * StateTransition constructor + * @throws Exception + */ + public StateTransition() throws Exception + { + logger.debug("StateTransition constructor"); + + try { + logger.debug("Load StateTable started"); + + setupStateTable(); // + //displayStateTable(); + } catch(Exception ex) { + throw new Exception("StateTransition Exception: " + ex.toString()); + } + } + + /** + * Calculates the state transition and returns the end state + * @param adminState + * @param opState + * @param availStatus + * @param standbyStatus + * @param actionName + * @return + * @throws Exception + */ + public StateElement getEndingState(String adminState, String opState, String availStatus, + String standbyStatus, String actionName) throws Exception + { + logger.info("getEndingState"); + logger.info("adminState=[" + adminState + "], opState=[" + opState + "], availStatus=[" + + availStatus + "], standbyStatus=[" + standbyStatus + "], actionName=[" + actionName + "]"); + if(availStatus==null){ + availStatus="null"; + } + if(standbyStatus==null){ + standbyStatus="null"; + } + if(adminState==null || opState==null || actionName==null){ + throw new Exception("Exception:StateTransition unable to process state: adminState=[" + adminState + "], opState=[" + opState + "], availStatus=[" + + availStatus + "], standbyStatus=[" + standbyStatus + "], actionName=[" + actionName + "]"); + }else if(!(adminState.equals(StateManagement.LOCKED) || adminState.equals(StateManagement.UNLOCKED))){ + throw new Exception("Exception:StateTransition unable to process state: adminState=[" + adminState + "], opState=[" + opState + "], availStatus=[" + + availStatus + "], standbyStatus=[" + standbyStatus + "], actionName=[" + actionName + "]"); + }else if(!(opState.equals(StateManagement.ENABLED) || opState.equals(StateManagement.DISABLED))){ + throw new Exception("Exception:StateTransition unable to process state: adminState=[" + adminState + "], opState=[" + opState + "], availStatus=[" + + availStatus + "], standbyStatus=[" + standbyStatus + "], actionName=[" + actionName + "]"); + }else if(!(standbyStatus.equals(StateManagement.NULL_VALUE) || + standbyStatus.equals(StateManagement.COLD_STANDBY) || + standbyStatus.equals(StateManagement.HOT_STANDBY) || + standbyStatus.equals(StateManagement.PROVIDING_SERVICE))){ + throw new Exception("Exception:StateTransition unable to process state: adminState=[" + adminState + "], opState=[" + opState + "], availStatus=[" + + availStatus + "], standbyStatus=[" + standbyStatus + "], actionName=[" + actionName + "]"); + }else if(!(availStatus.equals(StateManagement.NULL_VALUE) || + availStatus.equals(StateManagement.DEPENDENCY) || + availStatus.equals(StateManagement.DEPENDENCY_FAILED) || + availStatus.equals(StateManagement.FAILED))){ + throw new Exception("Exception:StateTransition unable to process state: adminState=[" + adminState + "], opState=[" + opState + "], availStatus=[" + + availStatus + "], standbyStatus=[" + standbyStatus + "], actionName=[" + actionName + "]"); + } + else if(!(actionName.equals(StateManagement.DEMOTE) || + actionName.equals(StateManagement.DISABLE_DEPENDENCY) || + actionName.equals(StateManagement.DISABLE_FAILED) || + actionName.equals(StateManagement.ENABLE_NO_DEPENDENCY) || + actionName.equals(StateManagement.ENABLE_NOT_FAILED) || + actionName.equals(StateManagement.LOCK) || + actionName.equals(StateManagement.PROMOTE) || + actionName.equals(StateManagement.UNLOCK))){ + throw new Exception("Exception:StateTransition unable to process state: adminState=[" + adminState + "], opState=[" + opState + "], availStatus=[" + + availStatus + "], standbyStatus=[" + standbyStatus + "], actionName=[" + actionName + "]"); + } + + StateElement stateElement = new StateElement(); + try { + // dependency,failed is stored as dependency.failed in StateTable + String availStatus2 = availStatus; + if (availStatus2 != null) { + availStatus2 = availStatus.replace(",", "."); + } + String key = adminState + "," + opState + "," + availStatus2 + "," + standbyStatus + "," + actionName; + logger.debug("Ending State search key: " + key); + String value = (String)StateTable.get(key); + + if (value != null) { + try { + String parts[] = value.split(",", 5); + stateElement.setEndingAdminState(parts[0].trim()); + stateElement.setEndingOpState(parts[1].trim()); + stateElement.setEndingAvailStatus(parts[2].trim().replace(".", ",")); + stateElement.setEndingStandbyStatus(parts[3].trim()); + stateElement.setException(parts[4].trim()); + stateElement.setAdminState(adminState); + stateElement.setOpState(opState); + stateElement.setAvailStatus(availStatus); + stateElement.setStandbyStatus(standbyStatus); + stateElement.setActionName(actionName); + + stateElement.displayStateElement(); + } catch(Exception ex) { + logger.error("String split exception: " + ex.toString()); + } + + } else { + String msg = "Ending state not found, adminState=[" + adminState + "], opState=[" + opState + "], availStatus=[" + + availStatus + "], standbyStatus=[" + standbyStatus + "], actionName=[" + actionName + "]"; + logger.error(msg); + throw new Exception(msg); + } + } catch (Exception ex) { + throw new Exception("Exception: " + ex.toString() + ", adminState=[" + adminState + "], opState=[" + opState + "], availStatus=[" + + availStatus + "], standbyStatus=[" + standbyStatus + "], actionName=[" + actionName + "]"); + } + + return stateElement; + } + + /** + * Adding State Transition info into HashMap. It includes all state/status and action combinations + * key : adminState,opState,availStatus,standbyStatus,actionName + * value: endingAdminState,endingOpState,endingAvailStatus,endingStandbyStatus,exception + * Note : Use period instead of comma as seperator when store multi-value endingStandbyStatus (convert to + * comma during retrieval) + * + * Note on illegal state/status combinations: This table has many state/status combinations that should never occur. + * However, they *may* occur due to corruption or manual manipulation of the DB. So, in each case of an illegal + * combination, the state/status is first corrected before applying the action. It is assumed that the administrative + * and operational states are always correct. Second, if the availability status is in "agreement" with the operational + * state, it is assumed correct. If it is null and the operational state is disabled, the availability status + * is left null until a disabledfailed or disableddependency action is received. Or, if a enableNotFailed or + * enableNoDependency is received while the availability status is null, it will remain null, but the Operational state + * will change to enabled. + * + * If the standby status is not in agreement with the administrative and/or operational states, it is brought into + * agreement. For example, if the administrative state is locked and the standby status is providingservice, the + * standby status is changed to coldstandby. + * + * After bringing the states/status attributes into agreement, *then* the action is applied to them. For example, if + * the administrative state is locked, the operational state is enabled, the availability status is null, the standby + * status is providingservice and the action is unlock, the standby status is changed to coldstandby and then the + * unlock action is applied. This will change the final state/status to administrative state = unlocked, operational + * state = disabled, availability status = null and standby status = hotstandby. + * + * Note on standby status: If the starting state of standby status is null and either a promote or demote action is + * made, the assumption is that standbystatus is supported and therefore, the standby status will be changed to + * providingservice, hotstandby or coldstandby - depending on the value of the administrative and operational states. + * If an attempt to promote is made when the administrative state is locked or operational state is disabled, + * a StandbyStatusException will be thrown since promotion (state transition) is not possible. If the standby status + * is coldstandby and a transition occurs on the administrative or operational state such that they are unlocked and + * enabled, the standby status is automatically transitioned to hotstandby since it is only those two states that can + * hold the statndby status in the coldstandby value. + */ + + private void setupStateTable() + { + StateTable.put("unlocked,enabled,null,null,lock", "locked,enabled,null,null,"); + StateTable.put("unlocked,enabled,null,null,unlock", "unlocked,enabled,null,null,"); + StateTable.put("unlocked,enabled,null,null,disableFailed", "unlocked,disabled,failed,null,"); + StateTable.put("unlocked,enabled,null,null,enableNotFailed", "unlocked,enabled,null,null,"); + StateTable.put("unlocked,enabled,null,null,disableDependency", "unlocked,disabled,dependency,null,"); + StateTable.put("unlocked,enabled,null,null,enableNoDependency", "unlocked,enabled,null,null,"); + StateTable.put("unlocked,enabled,null,null,promote", "unlocked,enabled,null,providingservice,"); + StateTable.put("unlocked,enabled,null,null,demote", "unlocked,enabled,null,hotstandby,"); + StateTable.put("unlocked,enabled,null,coldstandby,lock", "locked,enabled,null,coldstandby,"); + StateTable.put("unlocked,enabled,null,coldstandby,unlock", "unlocked,enabled,null,hotstandby,"); + StateTable.put("unlocked,enabled,null,coldstandby,disableFailed", "unlocked,disabled,failed,coldstandby,"); + StateTable.put("unlocked,enabled,null,coldstandby,enableNotFailed", "unlocked,enabled,null,hotstandby,"); + StateTable.put("unlocked,enabled,null,coldstandby,disableDependency", "unlocked,disabled,dependency,coldstandby,"); + StateTable.put("unlocked,enabled,null,coldstandby,enableNoDependency", "unlocked,enabled,null,hotstandby,"); + StateTable.put("unlocked,enabled,null,coldstandby,promote", "unlocked,enabled,null,providingservice,"); + StateTable.put("unlocked,enabled,null,coldstandby,demote", "unlocked,enabled,null,hotstandby,"); + StateTable.put("unlocked,enabled,null,hotstandby,lock", "locked,enabled,null,coldstandby,"); + StateTable.put("unlocked,enabled,null,hotstandby,unlock", "unlocked,enabled,null,hotstandby,"); + StateTable.put("unlocked,enabled,null,hotstandby,disableFailed", "unlocked,disabled,failed,coldstandby,"); + StateTable.put("unlocked,enabled,null,hotstandby,enableNotFailed", "unlocked,enabled,null,hotstandby,"); + StateTable.put("unlocked,enabled,null,hotstandby,disableDependency", "unlocked,disabled,dependency,coldstandby,"); + StateTable.put("unlocked,enabled,null,hotstandby,enableNoDependency", "unlocked,enabled,null,hotstandby,"); + StateTable.put("unlocked,enabled,null,hotstandby,promote", "unlocked,enabled,null,providingservice,"); + StateTable.put("unlocked,enabled,null,hotstandby,demote", "unlocked,enabled,null,hotstandby,"); + StateTable.put("unlocked,enabled,null,providingservice,lock", "locked,enabled,null,coldstandby,"); + StateTable.put("unlocked,enabled,null,providingservice,unlock", "unlocked,enabled,null,providingservice,"); + StateTable.put("unlocked,enabled,null,providingservice,disableFailed", "unlocked,disabled,failed,coldstandby,"); + StateTable.put("unlocked,enabled,null,providingservice,enableNotFailed", "unlocked,enabled,null,providingservice,"); + StateTable.put("unlocked,enabled,null,providingservice,disableDependency", "unlocked,disabled,dependency,coldstandby,"); + StateTable.put("unlocked,enabled,null,providingservice,enableNoDependency", "unlocked,enabled,null,providingservice,"); + StateTable.put("unlocked,enabled,null,providingservice,promote", "unlocked,enabled,null,providingservice,"); + StateTable.put("unlocked,enabled,null,providingservice,demote", "unlocked,enabled,null,hotstandby,"); + StateTable.put("unlocked,enabled,failed,null,lock", "locked,enabled,null,null,"); + StateTable.put("unlocked,enabled,failed,null,unlock", "unlocked,enabled,null,null,"); + StateTable.put("unlocked,enabled,failed,null,disableFailed", "unlocked,disabled,failed,null,"); + StateTable.put("unlocked,enabled,failed,null,enableNotFailed", "unlocked,enabled,null,null,"); + StateTable.put("unlocked,enabled,failed,null,disableDependency", "unlocked,disabled,dependency,null,"); + StateTable.put("unlocked,enabled,failed,null,enableNoDependency", "unlocked,enabled,null,null,"); + StateTable.put("unlocked,enabled,failed,null,promote", "unlocked,enabled,null,providingservice,"); + StateTable.put("unlocked,enabled,failed,null,demote", "unlocked,enabled,null,hotstandby,"); + StateTable.put("unlocked,enabled,failed,coldstandby,lock", "locked,enabled,null,coldstandby,"); + StateTable.put("unlocked,enabled,failed,coldstandby,unlock", "unlocked,enabled,null,hotstandby,"); + StateTable.put("unlocked,enabled,failed,coldstandby,disableFailed", "unlocked,disabled,failed,coldstandby,"); + StateTable.put("unlocked,enabled,failed,coldstandby,enableNotFailed", "unlocked,enabled,null,hotstandby,"); + StateTable.put("unlocked,enabled,failed,coldstandby,disableDependency", "unlocked,disabled,dependency,coldstandby,"); + StateTable.put("unlocked,enabled,failed,coldstandby,enableNoDependency", "unlocked,enabled,null,hotstandby,"); + StateTable.put("unlocked,enabled,failed,coldstandby,promote", "unlocked,enabled,null,providingservice,"); + StateTable.put("unlocked,enabled,failed,coldstandby,demote", "unlocked,enabled,null,hotstandby,"); + StateTable.put("unlocked,enabled,failed,hotstandby,lock", "locked,enabled,null,coldstandby,"); + StateTable.put("unlocked,enabled,failed,hotstandby,unlock", "unlocked,enabled,null,hotstandby,"); + StateTable.put("unlocked,enabled,failed,hotstandby,disableFailed", "unlocked,disabled,failed,coldstandby,"); + StateTable.put("unlocked,enabled,failed,hotstandby,enableNotFailed", "unlocked,enabled,null,hotstandby,"); + StateTable.put("unlocked,enabled,failed,hotstandby,disableDependency", "unlocked,disabled,dependency,coldstandby,"); + StateTable.put("unlocked,enabled,failed,hotstandby,enableNoDependency", "unlocked,enabled,null,hotstandby,"); + StateTable.put("unlocked,enabled,failed,hotstandby,promote", "unlocked,enabled,null,providingservice,"); + StateTable.put("unlocked,enabled,failed,hotstandby,demote", "unlocked,enabled,null,hotstandby,"); + StateTable.put("unlocked,enabled,failed,providingservice,lock", "locked,enabled,null,coldstandby,"); + StateTable.put("unlocked,enabled,failed,providingservice,unlock", "unlocked,enabled,null,providingservice,"); + StateTable.put("unlocked,enabled,failed,providingservice,disableFailed", "unlocked,disabled,failed,coldstandby,"); + StateTable.put("unlocked,enabled,failed,providingservice,enableNotFailed", "unlocked,enabled,null,providingservice,"); + StateTable.put("unlocked,enabled,failed,providingservice,disableDependency", "unlocked,disabled,dependency,coldstandby,"); + StateTable.put("unlocked,enabled,failed,providingservice,enableNoDependency", "unlocked,enabled,null,providingservice,"); + StateTable.put("unlocked,enabled,failed,providingservice,promote", "unlocked,enabled,null,providingservice,"); + StateTable.put("unlocked,enabled,failed,providingservice,demote", "unlocked,enabled,null,hotstandby,"); + StateTable.put("unlocked,enabled,dependency,null,lock", "locked,enabled,null,null,"); + StateTable.put("unlocked,enabled,dependency,null,unlock", "unlocked,enabled,null,null,"); + StateTable.put("unlocked,enabled,dependency,null,disableFailed", "unlocked,disabled,failed,null,"); + StateTable.put("unlocked,enabled,dependency,null,enableNotFailed", "unlocked,enabled,null,null,"); + StateTable.put("unlocked,enabled,dependency,null,disableDependency", "unlocked,disabled,dependency,null,"); + StateTable.put("unlocked,enabled,dependency,null,enableNoDependency", "unlocked,enabled,null,null,"); + StateTable.put("unlocked,enabled,dependency,null,promote", "unlocked,enabled,null,providingservice,"); + StateTable.put("unlocked,enabled,dependency,null,demote", "unlocked,enabled,null,hotstandby,"); + StateTable.put("unlocked,enabled,dependency,coldstandby,lock", "locked,enabled,null,coldstandby,"); + StateTable.put("unlocked,enabled,dependency,coldstandby,unlock", "unlocked,enabled,null,hotstandby,"); + StateTable.put("unlocked,enabled,dependency,coldstandby,disableFailed", "unlocked,disabled,failed,coldstandby,"); + StateTable.put("unlocked,enabled,dependency,coldstandby,enableNotFailed", "unlocked,enabled,null,hotstandby,"); + StateTable.put("unlocked,enabled,dependency,coldstandby,disableDependency", "unlocked,disabled,dependency,coldstandby,"); + StateTable.put("unlocked,enabled,dependency,coldstandby,enableNoDependency", "unlocked,enabled,null,hotstandby,"); + StateTable.put("unlocked,enabled,dependency,coldstandby,promote", "unlocked,enabled,null,providingservice,"); + StateTable.put("unlocked,enabled,dependency,coldstandby,demote", "unlocked,enabled,null,hotstandby,"); + StateTable.put("unlocked,enabled,dependency,hotstandby,lock", "locked,enabled,null,coldstandby,"); + StateTable.put("unlocked,enabled,dependency,hotstandby,unlock", "unlocked,enabled,null,hotstandby,"); + StateTable.put("unlocked,enabled,dependency,hotstandby,disableFailed", "unlocked,disabled,failed,coldstandby,"); + StateTable.put("unlocked,enabled,dependency,hotstandby,enableNotFailed", "unlocked,enabled,null,hotstandby,"); + StateTable.put("unlocked,enabled,dependency,hotstandby,disableDependency", "unlocked,disabled,dependency,hotstandby,"); + StateTable.put("unlocked,enabled,dependency,hotstandby,enableNoDependency", "unlocked,enabled,null,hotstandby,"); + StateTable.put("unlocked,enabled,dependency,hotstandby,promote", "unlocked,enabled,null,providingservice,"); + StateTable.put("unlocked,enabled,dependency,hotstandby,demote", "unlocked,enabled,null,hotstandby,"); + StateTable.put("unlocked,enabled,dependency,providingservice,lock", "locked,enabled,null,coldstandby,"); + StateTable.put("unlocked,enabled,dependency,providingservice,unlock", "unlocked,enabled,null,providingservice,"); + StateTable.put("unlocked,enabled,dependency,providingservice,disableFailed", "unlocked,disabled,failed,coldstandby,"); + StateTable.put("unlocked,enabled,dependency,providingservice,enableNotFailed", "unlocked,enabled,null,providingservice,"); + StateTable.put("unlocked,enabled,dependency,providingservice,disableDependency", "unlocked,disabled,dependency,coldstandby,"); + StateTable.put("unlocked,enabled,dependency,providingservice,enableNoDependency", "unlocked,enabled,null,providingservice,"); + StateTable.put("unlocked,enabled,dependency,providingservice,promote", "unlocked,enabled,null,providingservice,"); + StateTable.put("unlocked,enabled,dependency,providingservice,demote", "unlocked,enabled,null,hotstandby,"); + StateTable.put("unlocked,enabled,dependency.failed,null,lock", "locked,enabled,null,null,"); + StateTable.put("unlocked,enabled,dependency.failed,null,unlock", "unlocked,enabled,null,null,"); + StateTable.put("unlocked,enabled,dependency.failed,null,disableFailed", "unlocked,disabled,failed,null,"); + StateTable.put("unlocked,enabled,dependency.failed,null,enableNotFailed", "unlocked,enabled,null,null,"); + StateTable.put("unlocked,enabled,dependency.failed,null,disableDependency", "unlocked,disabled,dependency,null,"); + StateTable.put("unlocked,enabled,dependency.failed,null,enableNoDependency", "unlocked,enabled,null,null,"); + StateTable.put("unlocked,enabled,dependency.failed,null,promote", "unlocked,enabled,null,providingservice,"); + StateTable.put("unlocked,enabled,dependency.failed,null,demote", "unlocked,enabled,null,hotstandby,"); + StateTable.put("unlocked,enabled,dependency.failed,coldstandby,lock", "locked,enabled,null,coldstandby,"); + StateTable.put("unlocked,enabled,dependency.failed,coldstandby,unlock", "unlocked,enabled,null,hotstandby,"); + StateTable.put("unlocked,enabled,dependency.failed,coldstandby,disableFailed", "unlocked,disabled,failed,coldstandby,"); + StateTable.put("unlocked,enabled,dependency.failed,coldstandby,enableNotFailed", "unlocked,enabled,null,hotstandby,"); + StateTable.put("unlocked,enabled,dependency.failed,coldstandby,disableDependency", "unlocked,disabled,dependency,coldstandby,"); + StateTable.put("unlocked,enabled,dependency.failed,coldstandby,enableNoDependency", "unlocked,enabled,null,hotstandby,"); + StateTable.put("unlocked,enabled,dependency.failed,coldstandby,promote", "unlocked,enabled,null,providingservice,"); + StateTable.put("unlocked,enabled,dependency.failed,coldstandby,demote", "unlocked,enabled,null,hotstandby,"); + StateTable.put("unlocked,enabled,dependency.failed,hotstandby,lock", "locked,enabled,null,coldstandby,"); + StateTable.put("unlocked,enabled,dependency.failed,hotstandby,unlock", "unlocked,enabled,null,hotstandby,"); + StateTable.put("unlocked,enabled,dependency.failed,hotstandby,disableFailed", "unlocked,disabled,failed,coldstandby,"); + StateTable.put("unlocked,enabled,dependency.failed,hotstandby,enableNotFailed", "unlocked,enabled,null,hotstandby,"); + StateTable.put("unlocked,enabled,dependency.failed,hotstandby,disableDependency", "unlocked,disabled,dependency,coldstandby,"); + StateTable.put("unlocked,enabled,dependency.failed,hotstandby,enableNoDependency", "unlocked,enabled,null,hotstandby,"); + StateTable.put("unlocked,enabled,dependency.failed,hotstandby,promote", "unlocked,enabled,null,providingservice,"); + StateTable.put("unlocked,enabled,dependency.failed,hotstandby,demote", "unlocked,enabled,null,hotstandby,"); + StateTable.put("unlocked,enabled,dependency.failed,providingservice,lock", "locked,enabled,null,coldstandby,"); + StateTable.put("unlocked,enabled,dependency.failed,providingservice,unlock", "unlocked,enabled,null,providingservice,"); + StateTable.put("unlocked,enabled,dependency.failed,providingservice,disableFailed", "unlocked,disabled,failed,coldstandby,"); + StateTable.put("unlocked,enabled,dependency.failed,providingservice,enableNotFailed", "unlocked,enabled,null,providingservice,"); + StateTable.put("unlocked,enabled,dependency.failed,providingservice,disableDependency", "unlocked,disabled,dependency,coldstandby,"); + StateTable.put("unlocked,enabled,dependency.failed,providingservice,enableNoDependency", "unlocked,enabled,null,providingservice,"); + StateTable.put("unlocked,enabled,dependency.failed,providingservice,promote", "unlocked,enabled,null,providingservice,"); + StateTable.put("unlocked,enabled,dependency.failed,providingservice,demote", "unlocked,enabled,null,hotstandby,"); + StateTable.put("unlocked,disabled,null,null,lock", "locked,disabled,null,null,"); + StateTable.put("unlocked,disabled,null,null,unlock", "unlocked,disabled,null,null,"); + StateTable.put("unlocked,disabled,null,null,disableFailed", "unlocked,disabled,failed,null,"); + StateTable.put("unlocked,disabled,null,null,enableNotFailed", "unlocked,enabled,null,null,"); + StateTable.put("unlocked,disabled,null,null,disableDependency", "unlocked,disabled,dependency,null,"); + StateTable.put("unlocked,disabled,null,null,enableNoDependency", "unlocked,enabled,null,null,"); + StateTable.put("unlocked,disabled,null,null,promote", "unlocked,disabled,null,coldstandby,StandbyStatusException"); + StateTable.put("unlocked,disabled,null,null,demote", "unlocked,disabled,null,coldstandby,"); + StateTable.put("unlocked,disabled,null,coldstandby,lock", "locked,disabled,null,coldstandby,"); + StateTable.put("unlocked,disabled,null,coldstandby,unlock", "unlocked,disabled,null,coldstandby,"); + StateTable.put("unlocked,disabled,null,coldstandby,disableFailed", "unlocked,disabled,failed,coldstandby,"); + StateTable.put("unlocked,disabled,null,coldstandby,enableNotFailed", "unlocked,enabled,null,hotstandby,"); + StateTable.put("unlocked,disabled,null,coldstandby,disableDependency", "unlocked,disabled,dependency,coldstandby,"); + StateTable.put("unlocked,disabled,null,coldstandby,enableNoDependency", "unlocked,enabled,null,hotstandby,"); + StateTable.put("unlocked,disabled,null,coldstandby,promote", "unlocked,disabled,null,coldstandby,StandbyStatusException"); + StateTable.put("unlocked,disabled,null,coldstandby,demote", "unlocked,disabled,null,coldstandby,"); + StateTable.put("unlocked,disabled,null,hotstandby,lock", "locked,disabled,null,coldstandby,"); + StateTable.put("unlocked,disabled,null,hotstandby,unlock", "unlocked,disabled,null,coldstandby,"); + StateTable.put("unlocked,disabled,null,hotstandby,disableFailed", "unlocked,disabled,failed,coldstandby,"); + StateTable.put("unlocked,disabled,null,hotstandby,enableNotFailed", "unlocked,enabled,null,hotstandby,"); + StateTable.put("unlocked,disabled,null,hotstandby,disableDependency", "unlocked,disabled,dependency,coldstandby,"); + StateTable.put("unlocked,disabled,null,hotstandby,enableNoDependency", "unlocked,enabled,null,hotstandby,"); + StateTable.put("unlocked,disabled,null,hotstandby,promote", "unlocked,disabled,null,coldstandby,StandbyStatusException"); + StateTable.put("unlocked,disabled,null,hotstandby,demote", "unlocked,disabled,null,coldstandby,"); + StateTable.put("unlocked,disabled,null,providingservice,lock", "locked,disabled,null,coldstandby,"); + StateTable.put("unlocked,disabled,null,providingservice,unlock", "unlocked,disabled,null,coldstandby,"); + StateTable.put("unlocked,disabled,null,providingservice,disableFailed", "unlocked,disabled,failed,coldstandby,"); + StateTable.put("unlocked,disabled,null,providingservice,enableNotFailed", "unlocked,enabled,null,hotstandby,"); + StateTable.put("unlocked,disabled,null,providingservice,disableDependency", "unlocked,disabled,dependency,coldstandby,"); + StateTable.put("unlocked,disabled,null,providingservice,enableNoDependency", "unlocked,enabled,null,hotstandby,"); + StateTable.put("unlocked,disabled,null,providingservice,promote", "unlocked,disabled,null,coldstandby,StandbyStatusException"); + StateTable.put("unlocked,disabled,null,providingservice,demote", "unlocked,disabled,null,coldstandby,"); + StateTable.put("unlocked,disabled,failed,null,lock", "locked,disabled,failed,null,"); + StateTable.put("unlocked,disabled,failed,null,unlock", "unlocked,disabled,failed,null,"); + StateTable.put("unlocked,disabled,failed,null,disableFailed", "unlocked,disabled,failed,null,"); + StateTable.put("unlocked,disabled,failed,null,enableNotFailed", "unlocked,enabled,null,null,"); + StateTable.put("unlocked,disabled,failed,null,disableDependency", "unlocked,disabled,dependency.failed,null,"); + StateTable.put("unlocked,disabled,failed,null,enableNoDependency", "unlocked,disabled,failed,null,"); + StateTable.put("unlocked,disabled,failed,null,promote", "unlocked,disabled,failed,coldstandby,StandbyStatusException"); + StateTable.put("unlocked,disabled,failed,null,demote", "unlocked,disabled,failed,coldstandby,"); + StateTable.put("unlocked,disabled,failed,coldstandby,lock", "locked,disabled,failed,coldstandby,"); + StateTable.put("unlocked,disabled,failed,coldstandby,unlock", "unlocked,disabled,failed,coldstandby,"); + StateTable.put("unlocked,disabled,failed,coldstandby,disableFailed", "unlocked,disabled,failed,coldstandby,"); + StateTable.put("unlocked,disabled,failed,coldstandby,enableNotFailed", "unlocked,enabled,null,hotstandby,"); + StateTable.put("unlocked,disabled,failed,coldstandby,disableDependency", "unlocked,disabled,dependency.failed,coldstandby,"); + StateTable.put("unlocked,disabled,failed,coldstandby,enableNoDependency", "unlocked,disabled,failed,coldstandby,"); + StateTable.put("unlocked,disabled,failed,coldstandby,promote", "unlocked,disabled,failed,coldstandby,StandbyStatusException"); + StateTable.put("unlocked,disabled,failed,coldstandby,demote", "unlocked,disabled,failed,coldstandby,"); + StateTable.put("unlocked,disabled,failed,hotstandby,lock", "locked,disabled,failed,coldstandby,"); + StateTable.put("unlocked,disabled,failed,hotstandby,unlock", "unlocked,disabled,failed,coldstandby,"); + StateTable.put("unlocked,disabled,failed,hotstandby,disableFailed", "unlocked,disabled,failed,coldstandby,"); + StateTable.put("unlocked,disabled,failed,hotstandby,enableNotFailed", "unlocked,enabled,null,hotstandby,"); + StateTable.put("unlocked,disabled,failed,hotstandby,disableDependency", "unlocked,disabled,dependency.failed,coldstandby,"); + StateTable.put("unlocked,disabled,failed,hotstandby,enableNoDependency", "unlocked,disabled,failed,coldstandby,"); + StateTable.put("unlocked,disabled,failed,hotstandby,promote", "unlocked,disabled,failed,coldstandby,StandbyStatusException"); + StateTable.put("unlocked,disabled,failed,hotstandby,demote", "unlocked,disabled,failed,coldstandby,"); + StateTable.put("unlocked,disabled,failed,providingservice,lock", "locked,disabled,failed,coldstandby,"); + StateTable.put("unlocked,disabled,failed,providingservice,unlock", "unlocked,disabled,failed,coldstandby,"); + StateTable.put("unlocked,disabled,failed,providingservice,disableFailed", "unlocked,disabled,failed,coldstandby,"); + StateTable.put("unlocked,disabled,failed,providingservice,enableNotFailed", "unlocked,enabled,null,hotstandby,"); + StateTable.put("unlocked,disabled,failed,providingservice,disableDependency", "unlocked,disabled,dependency.failed,coldstandby,"); + StateTable.put("unlocked,disabled,failed,providingservice,enableNoDependency", "unlocked,disabled,failed,coldstandby,"); + StateTable.put("unlocked,disabled,failed,providingservice,promote", "unlocked,disabled,failed,coldstandby,StandbyStatusException"); + StateTable.put("unlocked,disabled,failed,providingservice,demote", "unlocked,disabled,failed,coldstandby,"); + StateTable.put("unlocked,disabled,dependency,null,lock", "locked,disabled,dependency,null,"); + StateTable.put("unlocked,disabled,dependency,null,unlock", "unlocked,disabled,dependency,null,"); + StateTable.put("unlocked,disabled,dependency,null,disableFailed", "unlocked,disabled,dependency.failed,null,"); + StateTable.put("unlocked,disabled,dependency,null,enableNotFailed", "unlocked,disabled,dependency,null,"); + StateTable.put("unlocked,disabled,dependency,null,disableDependency", "unlocked,disabled,dependency,null,"); + StateTable.put("unlocked,disabled,dependency,null,enableNoDependency", "unlocked,enabled,null,null,"); + StateTable.put("unlocked,disabled,dependency,null,promote", "unlocked,disabled,dependency,coldstandby,StandbyStatusException"); + StateTable.put("unlocked,disabled,dependency,null,demote", "unlocked,disabled,dependency,coldstandby,"); + StateTable.put("unlocked,disabled,dependency,coldstandby,lock", "locked,disabled,dependency,coldstandby,"); + StateTable.put("unlocked,disabled,dependency,coldstandby,unlock", "unlocked,disabled,dependency,coldstandby,"); + StateTable.put("unlocked,disabled,dependency,coldstandby,disableFailed", "unlocked,disabled,dependency.failed,coldstandby,"); + StateTable.put("unlocked,disabled,dependency,coldstandby,enableNotFailed", "unlocked,disabled,dependency,coldstandby,"); + StateTable.put("unlocked,disabled,dependency,coldstandby,disableDependency", "unlocked,disabled,dependency,coldstandby,"); + StateTable.put("unlocked,disabled,dependency,coldstandby,enableNoDependency", "unlocked,enabled,null,hotstandby,"); + StateTable.put("unlocked,disabled,dependency,coldstandby,promote", "unlocked,disabled,dependency,coldstandby,StandbyStatusException"); + StateTable.put("unlocked,disabled,dependency,coldstandby,demote", "unlocked,disabled,dependency,coldstandby,"); + StateTable.put("unlocked,disabled,dependency,hotstandby,lock", "locked,disabled,dependency,coldstandby,"); + StateTable.put("unlocked,disabled,dependency,hotstandby,unlock", "unlocked,disabled,dependency,coldstandby,"); + StateTable.put("unlocked,disabled,dependency,hotstandby,disableFailed", "unlocked,disabled,dependency.failed,coldstandby,"); + StateTable.put("unlocked,disabled,dependency,hotstandby,enableNotFailed", "unlocked,disabled,dependency,coldstandby,"); + StateTable.put("unlocked,disabled,dependency,hotstandby,disableDependency", "unlocked,disabled,dependency,coldstandby,"); + StateTable.put("unlocked,disabled,dependency,hotstandby,enableNoDependency", "unlocked,enabled,null,hotstandby,"); + StateTable.put("unlocked,disabled,dependency,hotstandby,promote", "unlocked,disabled,dependency,coldstandby,StandbyStatusException"); + StateTable.put("unlocked,disabled,dependency,hotstandby,demote", "unlocked,disabled,dependency,coldstandby,"); + StateTable.put("unlocked,disabled,dependency,providingservice,lock", "locked,disabled,dependency,coldstandby,"); + StateTable.put("unlocked,disabled,dependency,providingservice,unlock", "unlocked,disabled,dependency,coldstandby,"); + StateTable.put("unlocked,disabled,dependency,providingservice,disableFailed", "unlocked,disabled,dependency.failed,coldstandby,"); + StateTable.put("unlocked,disabled,dependency,providingservice,enableNotFailed", "unlocked,disabled,dependency,coldstandby,"); + StateTable.put("unlocked,disabled,dependency,providingservice,disableDependency", "unlocked,disabled,dependency,coldstandby,"); + StateTable.put("unlocked,disabled,dependency,providingservice,enableNoDependency", "unlocked,enabled,null,hotstandby,"); + StateTable.put("unlocked,disabled,dependency,providingservice,promote", "unlocked,disabled,dependency,coldstandby,StandbyStatusException"); + StateTable.put("unlocked,disabled,dependency,providingservice,demote", "unlocked,disabled,dependency,coldstandby,"); + StateTable.put("unlocked,disabled,dependency.failed,null,lock", "locked,disabled,dependency.failed,null,"); + StateTable.put("unlocked,disabled,dependency.failed,null,unlock", "unlocked,disabled,dependency.failed,null,"); + StateTable.put("unlocked,disabled,dependency.failed,null,disableFailed", "unlocked,disabled,dependency.failed,null,"); + StateTable.put("unlocked,disabled,dependency.failed,null,enableNotFailed", "unlocked,disabled,dependency,null,"); + StateTable.put("unlocked,disabled,dependency.failed,null,disableDependency", "unlocked,disabled,dependency.failed,null,"); + StateTable.put("unlocked,disabled,dependency.failed,null,enableNoDependency", "unlocked,disabled,failed,null,"); + StateTable.put("unlocked,disabled,dependency.failed,null,promote", "unlocked,disabled,dependency.failed,coldstandby,StandbyStatusException"); + StateTable.put("unlocked,disabled,dependency.failed,null,demote", "unlocked,disabled,dependency.failed,coldstandby,"); + StateTable.put("unlocked,disabled,dependency.failed,coldstandby,lock", "locked,disabled,dependency.failed,coldstandby,"); + StateTable.put("unlocked,disabled,dependency.failed,coldstandby,unlock", "unlocked,disabled,dependency.failed,coldstandby,"); + StateTable.put("unlocked,disabled,dependency.failed,coldstandby,disableFailed", "unlocked,disabled,dependency.failed,coldstandby,"); + StateTable.put("unlocked,disabled,dependency.failed,coldstandby,enableNotFailed", "unlocked,disabled,dependency,coldstandby,"); + StateTable.put("unlocked,disabled,dependency.failed,coldstandby,disableDependency", "unlocked,disabled,dependency.failed,coldstandby,"); + StateTable.put("unlocked,disabled,dependency.failed,coldstandby,enableNoDependency", "unlocked,disabled,failed,coldstandby,"); + StateTable.put("unlocked,disabled,dependency.failed,coldstandby,promote", "unlocked,disabled,dependency.failed,coldstandby,StandbyStatusException"); + StateTable.put("unlocked,disabled,dependency.failed,coldstandby,demote", "unlocked,disabled,dependency.failed,coldstandby,"); + StateTable.put("unlocked,disabled,dependency.failed,hotstandby,lock", "locked,disabled,dependency.failed,coldstandby,"); + StateTable.put("unlocked,disabled,dependency.failed,hotstandby,unlock", "unlocked,disabled,dependency.failed,coldstandby,"); + StateTable.put("unlocked,disabled,dependency.failed,hotstandby,disableFailed", "unlocked,disabled,dependency.failed,coldstandby,"); + StateTable.put("unlocked,disabled,dependency.failed,hotstandby,enableNotFailed", "unlocked,disabled,dependency,coldstandby,"); + StateTable.put("unlocked,disabled,dependency.failed,hotstandby,disableDependency", "unlocked,disabled,dependency.failed,coldstandby,"); + StateTable.put("unlocked,disabled,dependency.failed,hotstandby,enableNoDependency", "unlocked,disabled,failed,coldstandby,"); + StateTable.put("unlocked,disabled,dependency.failed,hotstandby,promote", "unlocked,disabled,dependency.failed,coldstandby,StandbyStatusException"); + StateTable.put("unlocked,disabled,dependency.failed,hotstandby,demote", "unlocked,disabled,dependency.failed,coldstandby,"); + StateTable.put("unlocked,disabled,dependency.failed,providingservice,lock", "locked,disabled,dependency.failed,coldstandby,"); + StateTable.put("unlocked,disabled,dependency.failed,providingservice,unlock", "unlocked,disabled,dependency.failed,coldstandby,"); + StateTable.put("unlocked,disabled,dependency.failed,providingservice,disableFailed", "unlocked,disabled,dependency.failed,coldstandby,"); + StateTable.put("unlocked,disabled,dependency.failed,providingservice,enableNotFailed", "unlocked,disabled,dependency,coldstandby,"); + StateTable.put("unlocked,disabled,dependency.failed,providingservice,disableDependency", "unlocked,disabled,dependency.failed,coldstandby,"); + StateTable.put("unlocked,disabled,dependency.failed,providingservice,enableNoDependency", "unlocked,disabled,failed,coldstandby,"); + StateTable.put("unlocked,disabled,dependency.failed,providingservice,promote", "unlocked,disabled,dependency.failed,coldstandby,StandbyStatusException"); + StateTable.put("unlocked,disabled,dependency.failed,providingservice,demote", "unlocked,disabled,dependency.failed,coldstandby,"); + StateTable.put("locked,enabled,null,null,lock", "locked,enabled,null,null,"); + StateTable.put("locked,enabled,null,null,unlock", "unlocked,enabled,null,null,"); + StateTable.put("locked,enabled,null,null,disableFailed", "locked,disabled,failed,null,"); + StateTable.put("locked,enabled,null,null,enableNotFailed", "locked,enabled,null,null,"); + StateTable.put("locked,enabled,null,null,disableDependency", "locked,disabled,dependency,null,"); + StateTable.put("locked,enabled,null,null,enableNoDependency", "locked,enabled,null,null,"); + StateTable.put("locked,enabled,null,null,promote", "locked,enabled,null,coldstandby,StandbyStatusException"); + StateTable.put("locked,enabled,null,null,demote", "locked,enabled,null,coldstandby,"); + StateTable.put("locked,enabled,null,coldstandby,lock", "locked,enabled,null,coldstandby,"); + StateTable.put("locked,enabled,null,coldstandby,unlock", "unlocked,enabled,null,hotstandby,"); + StateTable.put("locked,enabled,null,coldstandby,disableFailed", "locked,disabled,failed,coldstandby,"); + StateTable.put("locked,enabled,null,coldstandby,enableNotFailed", "locked,enabled,null,coldstandby,"); + StateTable.put("locked,enabled,null,coldstandby,disableDependency", "locked,disabled,dependency,coldstandby,"); + StateTable.put("locked,enabled,null,coldstandby,enableNoDependency", "locked,enabled,null,coldstandby,"); + StateTable.put("locked,enabled,null,coldstandby,promote", "locked,enabled,null,coldstandby,StandbyStatusException"); + StateTable.put("locked,enabled,null,coldstandby,demote", "locked,enabled,null,coldstandby,"); + StateTable.put("locked,enabled,null,hotstandby,lock", "locked,enabled,null,coldstandby,"); + StateTable.put("locked,enabled,null,hotstandby,unlock", "unlocked,enabled,null,hotstandby,"); + StateTable.put("locked,enabled,null,hotstandby,disableFailed", "locked,disabled,failed,coldstandby,"); + StateTable.put("locked,enabled,null,hotstandby,enableNotFailed", "locked,enabled,null,coldstandby,"); + StateTable.put("locked,enabled,null,hotstandby,disableDependency", "locked,disabled,dependency,coldstandby,"); + StateTable.put("locked,enabled,null,hotstandby,enableNoDependency", "locked,enabled,null,coldstandby,"); + StateTable.put("locked,enabled,null,hotstandby,promote", "locked,enabled,null,coldstandby,StandbyStateException"); + StateTable.put("locked,enabled,null,hotstandby,demote", "locked,enabled,null,coldstandby,"); + StateTable.put("locked,enabled,null,providingservice,lock", "locked,enabled,null,coldstandby,"); + StateTable.put("locked,enabled,null,providingservice,unlock", "unlocked,enabled,null,hotstandby,"); + StateTable.put("locked,enabled,null,providingservice,disableFailed", "locked,disabled,failed,coldstandby,"); + StateTable.put("locked,enabled,null,providingservice,enableNotFailed", "locked,enabled,null,coldstandby,"); + StateTable.put("locked,enabled,null,providingservice,disableDependency", "locked,disabled,dependency,coldstandby,"); + StateTable.put("locked,enabled,null,providingservice,enableNoDependency", "locked,enabled,null,coldstandby,"); + StateTable.put("locked,enabled,null,providingservice,promote", "locked,enabled,null,coldstandby,StandbyStateException"); + StateTable.put("locked,enabled,null,providingservice,demote", "locked,enabled,null,coldstandby,"); + StateTable.put("locked,enabled,failed,null,lock", "locked,enabled,null,null,"); + StateTable.put("locked,enabled,failed,null,unlock", "unlocked,enabled,null,null,"); + StateTable.put("locked,enabled,failed,null,disableFailed", "locked,disabled,failed,null,"); + StateTable.put("locked,enabled,failed,null,enableNotFailed", "locked,enabled,null,null,"); + StateTable.put("locked,enabled,failed,null,disableDependency", "locked,disabled,dependency,null,"); + StateTable.put("locked,enabled,failed,null,enableNoDependency", "locked,enabled,null,null,"); + StateTable.put("locked,enabled,failed,null,promote", "locked,enabled,null,coldstandby,StandbyStatusException"); + StateTable.put("locked,enabled,failed,null,demote", "locked,enabled,null,coldstandby,"); + StateTable.put("locked,enabled,failed,coldstandby,lock", "locked,enabled,null,coldstandby,"); + StateTable.put("locked,enabled,failed,coldstandby,unlock", "unlocked,enabled,null,hotstandby,"); + StateTable.put("locked,enabled,failed,coldstandby,disableFailed", "locked,disabled,failed,coldstandby,"); + StateTable.put("locked,enabled,failed,coldstandby,enableNotFailed", "locked,enabled,null,coldstandby,"); + StateTable.put("locked,enabled,failed,coldstandby,disableDependency", "locked,disabled,dependency,coldstandby,"); + StateTable.put("locked,enabled,failed,coldstandby,enableNoDependency", "locked,enabled,null,coldstandby,"); + StateTable.put("locked,enabled,failed,coldstandby,promote", "locked,enabled,null,coldstandby,StandbyStatusException"); + StateTable.put("locked,enabled,failed,coldstandby,demote", "locked,enabled,null,coldstandby,"); + StateTable.put("locked,enabled,failed,hotstandby,lock", "locked,enabled,null,coldstandby,"); + StateTable.put("locked,enabled,failed,hotstandby,unlock", "unlocked,enabled,null,hotstandby,"); + StateTable.put("locked,enabled,failed,hotstandby,disableFailed", "locked,disabled,failed,coldstandby,"); + StateTable.put("locked,enabled,failed,hotstandby,enableNotFailed", "locked,enabled,null,coldstandby,"); + StateTable.put("locked,enabled,failed,hotstandby,disableDependency", "locked,disabled,dependency,coldstandby,"); + StateTable.put("locked,enabled,failed,hotstandby,enableNoDependency", "locked,enabled,null,coldstandby,"); + StateTable.put("locked,enabled,failed,hotstandby,promote", "locked,enabled,null,coldstandby,StandbyStatusException"); + StateTable.put("locked,enabled,failed,hotstandby,demote", "locked,enabled,null,coldstandby,"); + StateTable.put("locked,enabled,failed,providingservice,lock", "locked,enabled,null,coldstandby,"); + StateTable.put("locked,enabled,failed,providingservice,unlock", "unlocked,enabled,null,hotstandby,"); + StateTable.put("locked,enabled,failed,providingservice,disableFailed", "locked,disabled,failed,coldstandby,"); + StateTable.put("locked,enabled,failed,providingservice,enableNotFailed", "locked,enabled,null,coldstandby,"); + StateTable.put("locked,enabled,failed,providingservice,disableDependency", "locked,disabled,dependency,coldstandby,"); + StateTable.put("locked,enabled,failed,providingservice,enableNoDependency", "locked,enabled,null,coldstandby,"); + StateTable.put("locked,enabled,failed,providingservice,promote", "locked,enabled,null,coldstandby,StandbyStatusException"); + StateTable.put("locked,enabled,failed,providingservice,demote", "locked,enabled,null,coldstandby,"); + StateTable.put("locked,enabled,dependency,null,lock", "locked,enabled,null,null,"); + StateTable.put("locked,enabled,dependency,null,unlock", "unlocked,enabled,null,null,"); + StateTable.put("locked,enabled,dependency,null,disableFailed", "locked,disabled,failed,null,"); + StateTable.put("locked,enabled,dependency,null,enableNotFailed", "locked,enabled,null,null,"); + StateTable.put("locked,enabled,dependency,null,disableDependency", "locked,disabled,dependency,null,"); + StateTable.put("locked,enabled,dependency,null,enableNoDependency", "locked,enabled,null,null,"); + StateTable.put("locked,enabled,dependency,null,promote", "locked,enabled,null,coldstandby,StandbyStatusException"); + StateTable.put("locked,enabled,dependency,null,demote", "locked,enabled,null,coldstandby,"); + StateTable.put("locked,enabled,dependency,coldstandby,lock", "locked,enabled,null,coldstandby,"); + StateTable.put("locked,enabled,dependency,coldstandby,unlock", "unlocked,enabled,null,hotstandby,"); + StateTable.put("locked,enabled,dependency,coldstandby,disableFailed", "locked,disabled,failed,coldstandby,"); + StateTable.put("locked,enabled,dependency,coldstandby,enableNotFailed", "locked,enabled,null,coldstandby,"); + StateTable.put("locked,enabled,dependency,coldstandby,disableDependency", "locked,disabled,dependency,coldstandby,"); + StateTable.put("locked,enabled,dependency,coldstandby,enableNoDependency", "locked,enabled,null,coldstandby,"); + StateTable.put("locked,enabled,dependency,coldstandby,promote", "locked,enabled,null,coldstandby,StandbyStatusException"); + StateTable.put("locked,enabled,dependency,coldstandby,demote", "locked,enabled,null,coldstandby,"); + StateTable.put("locked,enabled,dependency,hotstandby,lock", "locked,enabled,null,coldstandby,"); + StateTable.put("locked,enabled,dependency,hotstandby,unlock", "unlocked,enabled,null,hotstandby,"); + StateTable.put("locked,enabled,dependency,hotstandby,disableFailed", "locked,disabled,failed,coldstandby,"); + StateTable.put("locked,enabled,dependency,hotstandby,enableNotFailed", "locked,enabled,null,coldstandby,"); + StateTable.put("locked,enabled,dependency,hotstandby,disableDependency", "locked,disabled,dependency,coldstandby,"); + StateTable.put("locked,enabled,dependency,hotstandby,enableNoDependency", "locked,enabled,null,coldstandby,"); + StateTable.put("locked,enabled,dependency,hotstandby,promote", "locked,enabled,null,coldstandby,StandbyStatusException"); + StateTable.put("locked,enabled,dependency,hotstandby,demote", "locked,enabled,null,coldstandby,"); + StateTable.put("locked,enabled,dependency,providingservice,lock", "locked,enabled,null,coldstandby,"); + StateTable.put("locked,enabled,dependency,providingservice,unlock", "unlocked,enabled,null,hotstandby,"); + StateTable.put("locked,enabled,dependency,providingservice,disableFailed", "locked,disabled,failed,coldstandby,"); + StateTable.put("locked,enabled,dependency,providingservice,enableNotFailed", "locked,enabled,null,coldstandby,"); + StateTable.put("locked,enabled,dependency,providingservice,disableDependency", "locked,disabled,dependency,coldstandby,"); + StateTable.put("locked,enabled,dependency,providingservice,enableNoDependency", "locked,enabled,null,coldstandby,"); + StateTable.put("locked,enabled,dependency,providingservice,promote", "locked,enabled,null,coldstandby,StandbyStatusException"); + StateTable.put("locked,enabled,dependency,providingservice,demote", "locked,enabled,null,coldstandby,"); + StateTable.put("locked,enabled,dependency.failed,null,lock", "locked,enabled,null,null,"); + StateTable.put("locked,enabled,dependency.failed,null,unlock", "unlocked,enabled,null,null,"); + StateTable.put("locked,enabled,dependency.failed,null,disableFailed", "locked,disabled,failed,null,"); + StateTable.put("locked,enabled,dependency.failed,null,enableNotFailed", "locked,enabled,null,null,"); + StateTable.put("locked,enabled,dependency.failed,null,disableDependency", "locked,disabled,dependency,null,"); + StateTable.put("locked,enabled,dependency.failed,null,enableNoDependency", "locked,enabled,null,null,"); + StateTable.put("locked,enabled,dependency.failed,null,promote", "locked,enabled,null,coldstandby,StandbyStatusException"); + StateTable.put("locked,enabled,dependency.failed,null,demote", "locked,enabled,null,coldstandby,"); + StateTable.put("locked,enabled,dependency.failed,coldstandby,lock", "locked,enabled,null,coldstandby,"); + StateTable.put("locked,enabled,dependency.failed,coldstandby,unlock", "unlocked,enabled,null,hotstandby,"); + StateTable.put("locked,enabled,dependency.failed,coldstandby,disableFailed", "locked,disabled,failed,coldstandby,"); + StateTable.put("locked,enabled,dependency.failed,coldstandby,enableNotFailed", "locked,enabled,null,coldstandby,"); + StateTable.put("locked,enabled,dependency.failed,coldstandby,disableDependency", "locked,disabled,dependency,coldstandby,"); + StateTable.put("locked,enabled,dependency.failed,coldstandby,enableNoDependency", "locked,enabled,null,coldstandby,"); + StateTable.put("locked,enabled,dependency.failed,coldstandby,promote", "locked,enabled,null,coldstandby,StandbyStatusException"); + StateTable.put("locked,enabled,dependency.failed,coldstandby,demote", "locked,enabled,null,coldstandby,"); + StateTable.put("locked,enabled,dependency.failed,hotstandby,lock", "locked,enabled,null,coldstandby,"); + StateTable.put("locked,enabled,dependency.failed,hotstandby,unlock", "unlocked,enabled,null,hotstandby,"); + StateTable.put("locked,enabled,dependency.failed,hotstandby,disableFailed", "locked,disabled,failed,coldstandby,"); + StateTable.put("locked,enabled,dependency.failed,hotstandby,enableNotFailed", "locked,enabled,null,coldstandby,"); + StateTable.put("locked,enabled,dependency.failed,hotstandby,disableDependency", "locked,disabled,dependency,coldstandby,"); + StateTable.put("locked,enabled,dependency.failed,hotstandby,enableNoDependency", "locked,enabled,null,coldstandby,"); + StateTable.put("locked,enabled,dependency.failed,hotstandby,promote", "locked,enabled,null,coldstandby,StandbyStatusException"); + StateTable.put("locked,enabled,dependency.failed,hotstandby,demote", "locked,enabled,null,coldstandby,"); + StateTable.put("locked,enabled,dependency.failed,providingservice,lock", "locked,enabled,null,coldstandby,"); + StateTable.put("locked,enabled,dependency.failed,providingservice,unlock", "unlocked,enabled,null,hotstandby,"); + StateTable.put("locked,enabled,dependency.failed,providingservice,disableFailed", "locked,disabled,failed,coldstandby,"); + StateTable.put("locked,enabled,dependency.failed,providingservice,enableNotFailed", "locked,enabled,null,coldstandby,"); + StateTable.put("locked,enabled,dependency.failed,providingservice,disableDependency", "locked,disabled,dependency,coldstandby,"); + StateTable.put("locked,enabled,dependency.failed,providingservice,enableNoDependency", "locked,enabled,null,coldstandby,"); + StateTable.put("locked,enabled,dependency.failed,providingservice,promote", "locked,enabled,null,coldstandby,StandbyStatusException"); + StateTable.put("locked,enabled,dependency.failed,providingservice,demote", "locked,enabled,null,coldstandby,"); + StateTable.put("locked,disabled,null,null,lock", "locked,disabled,null,null,"); + StateTable.put("locked,disabled,null,null,unlock", "unlocked,disabled,null,null,"); + StateTable.put("locked,disabled,null,null,disableFailed", "locked,disabled,failed,null,"); + StateTable.put("locked,disabled,null,null,enableNotFailed", "locked,enabled,null,null,"); + StateTable.put("locked,disabled,null,null,disableDependency", "locked,disabled,dependency,null,"); + StateTable.put("locked,disabled,null,null,enableNoDependency", "locked,enabled,null,null,"); + StateTable.put("locked,disabled,null,null,promote", "locked,disabled,null,coldstandby,StandbyStatusException"); + StateTable.put("locked,disabled,null,null,demote", "locked,disabled,null,coldstandby,"); + StateTable.put("locked,disabled,null,coldstandby,lock", "locked,disabled,null,coldstandby,"); + StateTable.put("locked,disabled,null,coldstandby,unlock", "unlocked,disabled,null,coldstandby,"); + StateTable.put("locked,disabled,null,coldstandby,disableFailed", "locked,disabled,failed,coldstandby,"); + StateTable.put("locked,disabled,null,coldstandby,enableNotFailed", "locked,enabled,null,coldstandby,"); + StateTable.put("locked,disabled,null,coldstandby,disableDependency", "locked,disabled,dependency,coldstandby,"); + StateTable.put("locked,disabled,null,coldstandby,enableNoDependency", "locked,enabled,null,coldstandby,"); + StateTable.put("locked,disabled,null,coldstandby,promote", "locked,disabled,null,coldstandby,StandbyStatusException"); + StateTable.put("locked,disabled,null,coldstandby,demote", "locked,disabled,null,coldstandby,"); + StateTable.put("locked,disabled,null,hotstandby,lock", "locked,disabled,null,coldstandby,"); + StateTable.put("locked,disabled,null,hotstandby,unlock", "unlocked,disabled,null,coldstandby,"); + StateTable.put("locked,disabled,null,hotstandby,disableFailed", "locked,disabled,failed,coldstandby,"); + StateTable.put("locked,disabled,null,hotstandby,enableNotFailed", "locked,enabled,null,coldstandby,"); + StateTable.put("locked,disabled,null,hotstandby,disableDependency", "locked,disabled,dependency,coldstandby,"); + StateTable.put("locked,disabled,null,hotstandby,enableNoDependency", "locked,enabled,null,coldstandby,"); + StateTable.put("locked,disabled,null,hotstandby,promote", "locked,disabled,null,coldstandby,StandbyStatusException"); + StateTable.put("locked,disabled,null,hotstandby,demote", "locked,disabled,null,coldstandby,"); + StateTable.put("locked,disabled,null,providingservice,lock", "locked,disabled,null,coldstandby,"); + StateTable.put("locked,disabled,null,providingservice,unlock", "unlocked,disabled,null,coldstandby,"); + StateTable.put("locked,disabled,null,providingservice,disableFailed", "locked,disabled,failed,coldstandby,"); + StateTable.put("locked,disabled,null,providingservice,enableNotFailed", "locked,enabled,null,coldstandby,"); + StateTable.put("locked,disabled,null,providingservice,disableDependency", "locked,disabled,dependency,coldstandby,"); + StateTable.put("locked,disabled,null,providingservice,enableNoDependency", "locked,enabled,null,coldstandby,"); + StateTable.put("locked,disabled,null,providingservice,promote", "locked,disabled,null,coldstandby,StandbyStatusException"); + StateTable.put("locked,disabled,null,providingservice,demote", "locked,disabled,null,coldstandby,"); + StateTable.put("locked,disabled,failed,null,lock", "locked,disabled,failed,null,"); + StateTable.put("locked,disabled,failed,null,unlock", "unlocked,disabled,failed,null,"); + StateTable.put("locked,disabled,failed,null,disableFailed", "locked,disabled,failed,null,"); + StateTable.put("locked,disabled,failed,null,enableNotFailed", "locked,enabled,null,null,"); + StateTable.put("locked,disabled,failed,null,disableDependency", "locked,disabled,dependency.failed,null,"); + StateTable.put("locked,disabled,failed,null,enableNoDependency", "locked,disabled,failed,null,"); + StateTable.put("locked,disabled,failed,null,promote", "locked,disabled,failed,coldstandby,StandbyStatusException"); + StateTable.put("locked,disabled,failed,null,demote", "locked,disabled,failed,coldstandby,"); + StateTable.put("locked,disabled,failed,coldstandby,lock", "locked,disabled,failed,coldstandby,"); + StateTable.put("locked,disabled,failed,coldstandby,unlock", "unlocked,disabled,failed,coldstandby,"); + StateTable.put("locked,disabled,failed,coldstandby,disableFailed", "locked,disabled,failed,coldstandby,"); + StateTable.put("locked,disabled,failed,coldstandby,enableNotFailed", "locked,enabled,null,coldstandby,"); + StateTable.put("locked,disabled,failed,coldstandby,disableDependency", "locked,disabled,dependency.failed,coldstandby,"); + StateTable.put("locked,disabled,failed,coldstandby,enableNoDependency", "locked,disabled,failed,coldstandby,"); + StateTable.put("locked,disabled,failed,coldstandby,promote", "locked,disabled,failed,coldstandby,StandbyStatusException"); + StateTable.put("locked,disabled,failed,coldstandby,demote", "locked,disabled,failed,coldstandby,"); + StateTable.put("locked,disabled,failed,hotstandby,lock", "locked,disabled,failed,coldstandby,"); + StateTable.put("locked,disabled,failed,hotstandby,unlock", "unlocked,disabled,failed,coldstandby,"); + StateTable.put("locked,disabled,failed,hotstandby,disableFailed", "locked,disabled,failed,coldstandby,"); + StateTable.put("locked,disabled,failed,hotstandby,enableNotFailed", "locked,enabled,null,coldstandby,"); + StateTable.put("locked,disabled,failed,hotstandby,disableDependency", "locked,disabled,dependency.failed,coldstandby,"); + StateTable.put("locked,disabled,failed,hotstandby,enableNoDependency", "locked,disabled,failed,coldstandby,"); + StateTable.put("locked,disabled,failed,hotstandby,promote", "locked,disabled,failed,coldstandby,StandbyStatusException"); + StateTable.put("locked,disabled,failed,hotstandby,demote", "locked,disabled,failed,coldstandby,"); + StateTable.put("locked,disabled,failed,providingservice,lock", "locked,disabled,failed,coldstandby,"); + StateTable.put("locked,disabled,failed,providingservice,unlock", "unlocked,disabled,failed,coldstandby,"); + StateTable.put("locked,disabled,failed,providingservice,disableFailed", "locked,disabled,failed,coldstandby,"); + StateTable.put("locked,disabled,failed,providingservice,enableNotFailed", "locked,enabled,null,coldstandby,"); + StateTable.put("locked,disabled,failed,providingservice,disableDependency", "locked,disabled,dependency.failed,coldstandby,"); + StateTable.put("locked,disabled,failed,providingservice,enableNoDependency", "locked,disabled,failed,coldstandby,"); + StateTable.put("locked,disabled,failed,providingservice,promote", "locked,disabled,failed,coldstandby,StandbyStatusException"); + StateTable.put("locked,disabled,failed,providingservice,demote", "locked,disabled,failed,coldstandby,"); + StateTable.put("locked,disabled,dependency,null,lock", "locked,disabled,dependency,null,"); + StateTable.put("locked,disabled,dependency,null,unlock", "unlocked,disabled,dependency,null,"); + StateTable.put("locked,disabled,dependency,null,disableFailed", "locked,disabled,dependency.failed,null,"); + StateTable.put("locked,disabled,dependency,null,enableNotFailed", "locked,disabled,dependency,null,"); + StateTable.put("locked,disabled,dependency,null,disableDependency", "locked,disabled,dependency,null,"); + StateTable.put("locked,disabled,dependency,null,enableNoDependency", "locked,enabled,null,null,"); + StateTable.put("locked,disabled,dependency,null,promote", "locked,disabled,dependency,coldstandby,StandbyStatusException"); + StateTable.put("locked,disabled,dependency,null,demote", "locked,disabled,dependency,coldstandby,"); + StateTable.put("locked,disabled,dependency,coldstandby,lock", "locked,disabled,dependency,coldstandby,"); + StateTable.put("locked,disabled,dependency,coldstandby,unlock", "unlocked,disabled,dependency,coldstandby,"); + StateTable.put("locked,disabled,dependency,coldstandby,disableFailed", "locked,disabled,dependency.failed,coldstandby,"); + StateTable.put("locked,disabled,dependency,coldstandby,enableNotFailed", "locked,disabled,dependency,coldstandby,"); + StateTable.put("locked,disabled,dependency,coldstandby,disableDependency", "locked,disabled,dependency,coldstandby,"); + StateTable.put("locked,disabled,dependency,coldstandby,enableNoDependency", "locked,enabled,null,coldstandby,"); + StateTable.put("locked,disabled,dependency,coldstandby,promote", "locked,disabled,dependency,coldstandby,StandbyStatusException"); + StateTable.put("locked,disabled,dependency,coldstandby,demote", "locked,disabled,dependency,coldstandby,"); + StateTable.put("locked,disabled,dependency,hotstandby,lock", "locked,disabled,dependency,coldstandby,"); + StateTable.put("locked,disabled,dependency,hotstandby,unlock", "unlocked,disabled,dependency,coldstandby,"); + StateTable.put("locked,disabled,dependency,hotstandby,disableFailed", "locked,disabled,dependency.failed,coldstandby,"); + StateTable.put("locked,disabled,dependency,hotstandby,enableNotFailed", "locked,disabled,dependency,coldstandby,"); + StateTable.put("locked,disabled,dependency,hotstandby,disableDependency", "locked,disabled,dependency,coldstandby,"); + StateTable.put("locked,disabled,dependency,hotstandby,enableNoDependency", "locked,enabled,null,coldstandby,"); + StateTable.put("locked,disabled,dependency,hotstandby,promote", "locked,disabled,dependency,coldstandby,StandbyStatusException"); + StateTable.put("locked,disabled,dependency,hotstandby,demote", "locked,disabled,dependency,coldstandby,"); + StateTable.put("locked,disabled,dependency,providingservice,lock", "locked,disabled,dependency,coldstandby,"); + StateTable.put("locked,disabled,dependency,providingservice,unlock", "unlocked,disabled,dependency,coldstandby,"); + StateTable.put("locked,disabled,dependency,providingservice,disableFailed", "locked,disabled,dependency.failed,coldstandby,"); + StateTable.put("locked,disabled,dependency,providingservice,enableNotFailed", "locked,disabled,dependency,coldstandby,"); + StateTable.put("locked,disabled,dependency,providingservice,disableDependency", "locked,disabled,dependency,coldstandby,"); + StateTable.put("locked,disabled,dependency,providingservice,enableNoDependency", "locked,enabled,null,coldstandby,"); + StateTable.put("locked,disabled,dependency,providingservice,promote", "locked,disabled,dependency,coldstandby,StandbyStatusException"); + StateTable.put("locked,disabled,dependency,providingservice,demote", "locked,disabled,dependency,coldstandby,"); + StateTable.put("locked,disabled,dependency.failed,null,lock", "locked,disabled,dependency.failed,null,"); + StateTable.put("locked,disabled,dependency.failed,null,unlock", "unlocked,disabled,dependency.failed,null,"); + StateTable.put("locked,disabled,dependency.failed,null,disableFailed", "locked,disabled,dependency.failed,null,"); + StateTable.put("locked,disabled,dependency.failed,null,enableNotFailed", "locked,disabled,dependency,null,"); + StateTable.put("locked,disabled,dependency.failed,null,disableDependency", "locked,disabled,dependency.failed,null,"); + StateTable.put("locked,disabled,dependency.failed,null,enableNoDependency", "locked,disabled,failed,null,"); + StateTable.put("locked,disabled,dependency.failed,null,promote", "locked,disabled,dependency.failed,coldstandby,StandbyStatusException"); + StateTable.put("locked,disabled,dependency.failed,null,demote", "locked,disabled,dependency.failed,coldstandby,"); + StateTable.put("locked,disabled,dependency.failed,coldstandby,lock", "locked,disabled,dependency.failed,coldstandby,"); + StateTable.put("locked,disabled,dependency.failed,coldstandby,unlock", "unlocked,disabled,dependency.failed,coldstandby,"); + StateTable.put("locked,disabled,dependency.failed,coldstandby,disableFailed", "locked,disabled,dependency.failed,coldstandby,"); + StateTable.put("locked,disabled,dependency.failed,coldstandby,enableNotFailed", "locked,disabled,dependency,coldstandby,"); + StateTable.put("locked,disabled,dependency.failed,coldstandby,disableDependency", "locked,disabled,dependency.failed,coldstandby,"); + StateTable.put("locked,disabled,dependency.failed,coldstandby,enableNoDependency", "locked,disabled,failed,coldstandby,"); + StateTable.put("locked,disabled,dependency.failed,coldstandby,promote", "locked,disabled,dependency.failed,coldstandby,StandbyStatusException"); + StateTable.put("locked,disabled,dependency.failed,coldstandby,demote", "locked,disabled,dependency.failed,coldstandby,"); + StateTable.put("locked,disabled,dependency.failed,hotstandby,lock", "locked,disabled,dependency.failed,coldstandby,"); + StateTable.put("locked,disabled,dependency.failed,hotstandby,unlock", "unlocked,disabled,dependency.failed,coldstandby,"); + StateTable.put("locked,disabled,dependency.failed,hotstandby,disableFailed", "locked,disabled,dependency.failed,coldstandby,"); + StateTable.put("locked,disabled,dependency.failed,hotstandby,enableNotFailed", "locked,disabled,dependency,coldstandby,"); + StateTable.put("locked,disabled,dependency.failed,hotstandby,disableDependency", "locked,disabled,dependency.failed,coldstandby,"); + StateTable.put("locked,disabled,dependency.failed,hotstandby,enableNoDependency", "locked,disabled,failed,coldstandby,"); + StateTable.put("locked,disabled,dependency.failed,hotstandby,promote", "locked,disabled,dependency.failed,coldstandby,StandbyStatusException"); + StateTable.put("locked,disabled,dependency.failed,hotstandby,demote", "locked,disabled,dependency.failed,coldstandby,"); + StateTable.put("locked,disabled,dependency.failed,providingservice,lock", "locked,disabled,dependency.failed,coldstandby,"); + StateTable.put("locked,disabled,dependency.failed,providingservice,unlock", "unlocked,disabled,dependency.failed,coldstandby,"); + StateTable.put("locked,disabled,dependency.failed,providingservice,disableFailed", "locked,disabled,dependency.failed,coldstandby,"); + StateTable.put("locked,disabled,dependency.failed,providingservice,enableNotFailed", "locked,disabled,dependency,coldstandby,"); + StateTable.put("locked,disabled,dependency.failed,providingservice,disableDependency", "locked,disabled,dependency.failed,coldstandby,"); + StateTable.put("locked,disabled,dependency.failed,providingservice,enableNoDependency", "locked,disabled,failed,coldstandby,"); + StateTable.put("locked,disabled,dependency.failed,providingservice,promote", "locked,disabled,dependency.failed,coldstandby,StandbyStatusException"); + StateTable.put("locked,disabled,dependency.failed,providingservice,demote", "locked,disabled,dependency.failed,coldstandby,"); + } + + public void displayStateTable() + { + Set set = StateTable.entrySet(); + Iterator iter = set.iterator(); + + while(iter.hasNext()) { + Map.Entry me = (Map.Entry)iter.next(); + logger.debug((String)me.getKey() + ((String)me.getValue()).replace(".", ",")); + } + } +} diff --git a/integrity-monitor/src/main/java/org/openecomp/policy/common/im/jmx/ComponentAdmin.java b/integrity-monitor/src/main/java/org/openecomp/policy/common/im/jmx/ComponentAdmin.java new file mode 100644 index 00000000..4d8399a1 --- /dev/null +++ b/integrity-monitor/src/main/java/org/openecomp/policy/common/im/jmx/ComponentAdmin.java @@ -0,0 +1,227 @@ +/*- + * ============LICENSE_START======================================================= + * Integrity Monitor + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.policy.common.im.jmx; + +import java.util.ArrayList; +import java.util.Iterator; + +import javax.management.InstanceAlreadyExistsException; +import javax.management.InstanceNotFoundException; +import javax.management.MBeanRegistrationException; +import javax.management.MBeanServer; +import javax.management.MBeanServerFactory; +import javax.management.MalformedObjectNameException; +import javax.management.NotCompliantMBeanException; +import javax.management.ObjectName; + +import org.apache.log4j.Logger; + +import org.openecomp.policy.common.im.IntegrityMonitor; +import org.openecomp.policy.common.im.StateManagement; + +/** + * Base class for component MBeans. + */ +public class ComponentAdmin implements ComponentAdminMBean { + private static final Logger logger = Logger.getLogger(ComponentAdmin.class.getName()); + + private final String name; + private MBeanServer registeredMBeanServer; + private ObjectName registeredObjectName; + private IntegrityMonitor integrityMonitor = null; + private StateManagement stateManager = null; + + /** + * Constructor. + * @param name the MBean name + * @param integrityMonitor + * @param stateManager + * @throws Exception + */ + public ComponentAdmin(String name, IntegrityMonitor integrityMonitor, StateManagement stateManager) throws Exception { + if ((name == null) || (integrityMonitor == null) || (stateManager == null)) { + logger.error("Error: ComponentAdmin constructor called with invalid input"); + throw new NullPointerException("null input"); + } + + this.name = "ECOMP_POLICY_COMP:name=" + name; + this.integrityMonitor = integrityMonitor; + this.stateManager = stateManager; + + try { + register(); + } catch (Exception e) { + logger.info("Failed to register ComponentAdmin MBean"); + throw e; + } + } + + /** + * Registers with the MBean server. + * @throws MalformedObjectNameException a JMX exception + * @throws InstanceNotFoundException a JMX exception + * @throws MBeanRegistrationException a JMX exception + * @throws NotCompliantMBeanException a JMX exception + * @throws InstanceAlreadyExistsException a JMX exception + */ + public synchronized void register() throws MalformedObjectNameException, + MBeanRegistrationException, InstanceNotFoundException, + InstanceAlreadyExistsException, NotCompliantMBeanException { + + //if (LOGGER.isDebugEnabled()) { + logger.info("Registering " + name + " MBean"); + //} + + MBeanServer mbeanServer = findMBeanServer(); + + if (mbeanServer == null) { + //LOGGER.warn("No MBeanServer to register " + name + " MBean"); + return; + } + + ObjectName objectName = new ObjectName(name); + + if (mbeanServer.isRegistered(objectName)) { + logger.info("Unregistering a previously registered " + + name + " MBean"); + mbeanServer.unregisterMBean(objectName); + } + + mbeanServer.registerMBean(this, objectName); + registeredMBeanServer = mbeanServer; + registeredObjectName = objectName; + } + + /** + * Checks if this MBean is registered with the MBeanServer. + * @return true if this MBean is registered with the MBeanServer. + */ + public boolean isRegistered() { + return registeredObjectName != null; + } + + /** + * Unregisters with the MBean server. + * @throws InstanceNotFoundException a JMX exception + * @throws MBeanRegistrationException a JMX exception + */ + public synchronized void unregister() throws MBeanRegistrationException, + InstanceNotFoundException { + + if (registeredObjectName == null) { + return; + } + + //if (LOGGER.isDebugEnabled()) { + //LOGGER.debug("Unregistering " + name + " MBean"); + //} + + registeredMBeanServer.unregisterMBean(registeredObjectName); + registeredMBeanServer = null; + registeredObjectName = null; + } + + /** + * {@inheritDoc} + */ + public String toString() { + return ComponentAdmin.class.getSimpleName() + "[" + name + "]"; + } + + /** + * Finds the MBeanServer. + * @return the MBeanServer, or null if it is not found + */ + public static MBeanServer findMBeanServer() { + ArrayList mbeanServers = + MBeanServerFactory.findMBeanServer(null); + + Iterator iter = mbeanServers.iterator(); + MBeanServer mbeanServer = null; + + while (iter.hasNext()) { + mbeanServer = iter.next(); + if (mbeanServer.getDefaultDomain().equals("DefaultDomain")) { + return mbeanServer; + } + } + + return null; + } + + /** + * Creates the MBeanServer (intended for unit testing only). + * @return the MBeanServer + */ + public static MBeanServer createMBeanServer() { + return MBeanServerFactory.createMBeanServer("DefaultDomain"); + } + + /** + * Get the MBean object name for the specified feature name. + * @param componentName component name + * @return the object name + * @throws MalformedObjectNameException a JMX exception + */ + public static ObjectName getObjectName(String componentName) + throws MalformedObjectNameException { + return new ObjectName("ECOMP_POLICY_COMP:name=" + componentName); + } + + @Override + public void test() throws Exception { + // Call evaluateSanity on IntegrityMonitor to run the test + logger.info("test() called..."); + if (integrityMonitor != null) { + integrityMonitor.evaluateSanity(); + } + else { + logger.error("Unable to invoke test() - state manager instance is null"); + throw new NullPointerException("stateManager"); + } + + } + + @Override + public void lock() throws Exception { + logger.info("lock() called..."); + if (stateManager != null) { + stateManager.lock(); + } + else { + logger.error("Unable to invoke lock() - state manager instance is null"); + throw new NullPointerException("stateManager"); + } + } + + @Override + public void unlock() throws Exception { + logger.info("unlock() called..."); + if (stateManager != null) { + stateManager.unlock(); + } + else { + logger.error("Unable to invoke unlock() - state manager instance is null"); + throw new NullPointerException("stateManager"); + } + + } +} diff --git a/integrity-monitor/src/main/java/org/openecomp/policy/common/im/jmx/ComponentAdminMBean.java b/integrity-monitor/src/main/java/org/openecomp/policy/common/im/jmx/ComponentAdminMBean.java new file mode 100644 index 00000000..5cf24b6b --- /dev/null +++ b/integrity-monitor/src/main/java/org/openecomp/policy/common/im/jmx/ComponentAdminMBean.java @@ -0,0 +1,50 @@ +/*- + * ============LICENSE_START======================================================= + * Integrity Monitor + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.policy.common.im.jmx; + +/** + * Provides operations to test health, lock and unlock components. + */ +public interface ComponentAdminMBean { + /** + * Test health of component. + * + * @throws Exception + * if the component fails the health check + */ + void test() throws Exception; + + /** + * Administratively lock component. + * + * @throws Exception + * if the component lock fails + */ + void lock() throws Exception; + + /** + * Administratively unlock component. + * + * @throws Exception + * if the component unlock fails + */ + void unlock() throws Exception; +} diff --git a/integrity-monitor/src/main/java/org/openecomp/policy/common/im/jmx/JmxAgentConnection.java b/integrity-monitor/src/main/java/org/openecomp/policy/common/im/jmx/JmxAgentConnection.java new file mode 100644 index 00000000..4940c4d2 --- /dev/null +++ b/integrity-monitor/src/main/java/org/openecomp/policy/common/im/jmx/JmxAgentConnection.java @@ -0,0 +1,133 @@ +/*- + * ============LICENSE_START======================================================= + * Integrity Monitor + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +/** + * + */ +package org.openecomp.policy.common.im.jmx; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; + +import javax.management.MBeanServerConnection; +import javax.management.Notification; +import javax.management.NotificationListener; +import javax.management.remote.JMXConnectionNotification; +import javax.management.remote.JMXConnector; +import javax.management.remote.JMXConnectorFactory; +import javax.management.remote.JMXServiceURL; + +/** + * Class to create a JMX RMI connection to the JmxAgent. + */ +public final class JmxAgentConnection { + + private static final String DEFAULT_HOST = "localhost"; + private static final String DEFAULT_PORT = "9996"; + + private String host; + private String port; + private JMXConnector connector; + private String jmxUrl = null; + + //private final static Logger Log = Logger.getLogger(JmxAgentConnection.class); + + /** + * Set up the host/port from the properties. Use defaults if missing from the properties. + * @param properties the properties used to look for host and port + */ + //JmxAgentConnection(Properties properties) { + //host = properties.getProperty("jmxAgent.host", DEFAULT_HOST); + //port = properties.getProperty("jmxAgent.port", DEFAULT_PORT); + //} + + public JmxAgentConnection() { + host = DEFAULT_HOST; + port = DEFAULT_PORT; + } + + public JmxAgentConnection(String url) { + jmxUrl = url; + } + + /** + * Generate jmxAgent url. + * service:jmx:rmi:///jndi/rmi://host.domain:9999/jmxAgent + * + * @param host + * host.domain + * @param port + * 9999 + * @return jmxAgent url. + */ + private static String jmxAgentUrl(String host, String port) { + + String url = "service:jmx:rmi:///jndi/rmi://" + host + ":" + port + + "/jmxrmi"; + + return url; + } + + /** + * Get a connection to the jmxAgent MBeanServer. + * @return the connection + * @throws Exception on error + */ + public MBeanServerConnection getMBeanConnection() throws Exception { + JMXServiceURL url; + if (jmxUrl == null) { + url = new JMXServiceURL(jmxAgentUrl(host, port)); + } + else { + url = new JMXServiceURL(jmxUrl); + } + Map env = new HashMap(); + + connector = JMXConnectorFactory.newJMXConnector(url, env); + connector.connect(); + connector.addConnectionNotificationListener( + new NotificationListener() { + + @Override + public void handleNotification( + Notification notification, Object handback) { + if (notification.getType().equals( + JMXConnectionNotification.FAILED)) { + //Log.debug("JMXAgent connection failure"); + // handle disconnect + disconnect(); + } + } + }, null, null); + + return connector.getMBeanServerConnection(); + } + + /** + * Disconnect. + */ + public void disconnect() { + if (connector != null) { + try { connector.close(); } catch (IOException e) { } + } + } +} diff --git a/integrity-monitor/src/main/java/org/openecomp/policy/common/im/jpa/ForwardProgressEntity.java b/integrity-monitor/src/main/java/org/openecomp/policy/common/im/jpa/ForwardProgressEntity.java new file mode 100644 index 00000000..4662f581 --- /dev/null +++ b/integrity-monitor/src/main/java/org/openecomp/policy/common/im/jpa/ForwardProgressEntity.java @@ -0,0 +1,131 @@ +/*- + * ============LICENSE_START======================================================= + * Integrity Monitor + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.policy.common.im.jpa; + +import java.io.Serializable; +import java.util.Date; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.NamedQueries; +import javax.persistence.NamedQuery; +import javax.persistence.PrePersist; +import javax.persistence.PreUpdate; +import javax.persistence.SequenceGenerator; +import javax.persistence.Table; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; +/* + * The Entity class to persist a policy object ForwardProgress + */ + +@Entity +@Table(name="ForwardProgressEntity") +@NamedQueries({ + @NamedQuery(name=" ForwardProgressEntity.findAll", query="SELECT e FROM ForwardProgressEntity e "), + @NamedQuery(name="ForwardProgressEntity.deleteAll", query="DELETE FROM ForwardProgressEntity WHERE 1=1") +}) +//@SequenceGenerator(name="seqForwardProgress", initialValue=1, allocationSize=1) + +public class ForwardProgressEntity implements Serializable { + private static final long serialVersionUID = 1L; + + @Id + //@GeneratedValue(strategy = GenerationType.SEQUENCE, generator="seqForwardProgress") + @GeneratedValue(strategy = GenerationType.AUTO) + @Column(name="forwardProgressId") + private long forwardProgressId; + + @Column(name="resourceName", nullable=false, length=100, unique=true) + private String resourceName; + + @Column(name="fpc_count", nullable=false) + private long fpcCount; + + @Temporal(TemporalType.TIMESTAMP) + @Column(name="created_date", updatable=false) + private Date created_date; + + @Temporal(TemporalType.TIMESTAMP) + @Column(name="last_updated") + private Date lastUpdated; + + public ForwardProgressEntity() { + } + + @PrePersist + public void prePersist() { + Date date = new Date(); + this.created_date = date; + this.lastUpdated = date; + this.fpcCount = 0; + } + + @PreUpdate + public void preUpdate() { + this.lastUpdated = new Date(); + } + + /** + * @return the Id + */ + public long getForwardProgressId() { + return forwardProgressId; + } + + public String getResourceName() { + return this.resourceName; + } + public void setResourceName(String resourceName) { + this.resourceName = resourceName; + } + + /** + * @return the fpcCount + */ + public long getFpcCount() { + return fpcCount; + } + + /** + * @param fpcCount the fpcCount to set + */ + public void setFpcCount(long fpcCount) { + this.fpcCount = fpcCount; + } + + /** + * @return the lastUpdated + */ + public Date getLastUpdated() { + return lastUpdated; + } + + /** + * @param lastUpdated the lastUpdated to set + */ + public void setLastUpdated(Date lastUpdated) { + this.lastUpdated = lastUpdated; + } +} diff --git a/integrity-monitor/src/main/java/org/openecomp/policy/common/im/jpa/ImTestEntity.java b/integrity-monitor/src/main/java/org/openecomp/policy/common/im/jpa/ImTestEntity.java new file mode 100644 index 00000000..0eee38b0 --- /dev/null +++ b/integrity-monitor/src/main/java/org/openecomp/policy/common/im/jpa/ImTestEntity.java @@ -0,0 +1,146 @@ +/*- + * ============LICENSE_START======================================================= + * Integrity Monitor + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.policy.common.im.jpa; + +import java.io.Serializable; +import java.util.Date; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Lob; +import javax.persistence.NamedQueries; +import javax.persistence.NamedQuery; +import javax.persistence.PrePersist; +import javax.persistence.PreUpdate; +import javax.persistence.SequenceGenerator; +import javax.persistence.Table; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; +import javax.persistence.Version; +/* + * The Entity class to persist a policy object Action Body + */ + +@Entity +@Table(name="ImTestEntity") +@NamedQueries({ + @NamedQuery(name=" ImTestEntity.findAll", query="SELECT e FROM ImTestEntity e "), + @NamedQuery(name="ImTestEntity.deleteAll", query="DELETE FROM ImTestEntity WHERE 1=1") +}) +//@SequenceGenerator(name="seqImTest", initialValue=1, allocationSize=1) + +public class ImTestEntity implements Serializable { + private static final long serialVersionUID = 1L; + + @Id + //@GeneratedValue(strategy = GenerationType.SEQUENCE, generator="seqImTest") + @GeneratedValue(strategy = GenerationType.AUTO) + @Column(name="ImTestId") + private long imTestId; + + @Column(name="created_by", nullable=false, length=255) + private String createdBy = "guest"; + + @Temporal(TemporalType.TIMESTAMP) + @Column(name="created_date", updatable=false) + private Date createdDate; + + @Column(name="modified_by", nullable=false, length=255) + private String modifiedBy = "guest"; + + @Temporal(TemporalType.TIMESTAMP) + @Column(name="modified_date", nullable=false) + private Date modifiedDate; + + public ImTestEntity() { + } + + @PrePersist + public void prePersist() { + Date date = new Date(); + this.createdDate = date; + this.modifiedDate = date; + } + + @PreUpdate + public void preUpdate() { + this.modifiedDate = new Date(); + } + + /** + * @return the Id + */ + public long getImTestId() { + return imTestId; + } + + /** + * @return the createdBy + */ + public String getCreatedBy() { + return createdBy; + } + + /** + * @param createdBy the createdBy to set + */ + public void setCreatedBy(String createdBy) { + this.createdBy = createdBy; + } + + /** + * @return the modifiedBy + */ + public String getModifiedBy() { + return modifiedBy; + } + + /** + * @param modifiedBy the modifiedBy to set + */ + public void setModifiedBy(String modifiedBy) { + this.modifiedBy = modifiedBy; + } + + /** + * @return the modifiedDate + */ + public Date getModifiedDate() { + return modifiedDate; + } + + /** + * @param modifiedDate the modifiedDate to set + */ + public void setModifiedDate(Date modifiedDate) { + this.modifiedDate = modifiedDate; + } + + /** + * @return the createdDate + */ + public Date getCreatedDate() { + return createdDate; + } +} diff --git a/integrity-monitor/src/main/java/org/openecomp/policy/common/im/jpa/ResourceRegistrationEntity.java b/integrity-monitor/src/main/java/org/openecomp/policy/common/im/jpa/ResourceRegistrationEntity.java new file mode 100644 index 00000000..c7eec085 --- /dev/null +++ b/integrity-monitor/src/main/java/org/openecomp/policy/common/im/jpa/ResourceRegistrationEntity.java @@ -0,0 +1,150 @@ +/*- + * ============LICENSE_START======================================================= + * Integrity Monitor + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.policy.common.im.jpa; + +import java.io.Serializable; +import java.util.Date; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.NamedQueries; +import javax.persistence.NamedQuery; +import javax.persistence.PrePersist; +import javax.persistence.PreUpdate; +import javax.persistence.SequenceGenerator; +import javax.persistence.Table; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; +/* + * The Entity class to persist a policy object ResourceRegistration + */ + +@Entity +@Table(name="ResourceRegistrationEntity") +@NamedQueries({ + @NamedQuery(name=" ResourceRegistrationEntity.findAll", query="SELECT e FROM ResourceRegistrationEntity e "), + @NamedQuery(name="ResourceRegistrationEntity.deleteAll", query="DELETE FROM ResourceRegistrationEntity WHERE 1=1") +}) +//@SequenceGenerator(name="seqResourceRegistration", initialValue=1, allocationSize=1) + +public class ResourceRegistrationEntity implements Serializable { + private static final long serialVersionUID = 1L; + + @Id + //@GeneratedValue(strategy = GenerationType.SEQUENCE, generator="seqResourceRegistration") + @GeneratedValue(strategy = GenerationType.AUTO) + @Column(name="ResourceRegistrationId") + private long resourceRegistrationId; + + @Column(name="resourceName", nullable=false, length=100, unique=true) + private String resourceName; + + @Column(name="resourceUrl", nullable=false, length=255, unique=true) + private String resourceUrl; + + @Column(name="site", nullable=true, length=50) + private String site; + + @Column(name="nodeType", nullable=true, length=50) + private String nodeType; + + @Temporal(TemporalType.TIMESTAMP) + @Column(name="created_date", updatable=false) + private Date createdDate; + + @Temporal(TemporalType.TIMESTAMP) + @Column(name="last_updated") + private Date lastUpdated; + + public ResourceRegistrationEntity() { + } + + @PrePersist + public void prePersist() { + Date date = new Date(); + this.createdDate = date; + this.lastUpdated = date; + } + + @PreUpdate + public void preUpdate() { + this.lastUpdated = new Date(); + } + + /** + * @return the Id + */ + public long getResourceRegistrationId() { + return resourceRegistrationId; + } + + public String getResourceName() { + return this.resourceName; + } + public void setResourceName(String resourceName) { + this.resourceName = resourceName; + } + + public String getResourceUrl() { + return this.resourceUrl; + } + public void setResourceUrl(String resourceUrl) { + this.resourceUrl = resourceUrl; + } + + public String getSite() { + return this.site; + } + public void setSite(String site) { + this.site = site; + } + + public String getNodeType() { + return this.nodeType; + } + public void setNodeType(String nodeType) { + this.nodeType = nodeType; + } + + /** + * @return the createdDate + */ + public Date getCreatedDate() { + return createdDate; + } + + /** + * @return the lastUpdated + */ + public Date getLastUpdated() { + return lastUpdated; + } + + /** + * @param lastUpdated the lastUpdated to set + */ + public void setLastUpdated(Date lastUpdated) { + this.lastUpdated = lastUpdated; + } +} diff --git a/integrity-monitor/src/main/java/org/openecomp/policy/common/im/jpa/StateManagementEntity.java b/integrity-monitor/src/main/java/org/openecomp/policy/common/im/jpa/StateManagementEntity.java new file mode 100644 index 00000000..b747c8f9 --- /dev/null +++ b/integrity-monitor/src/main/java/org/openecomp/policy/common/im/jpa/StateManagementEntity.java @@ -0,0 +1,143 @@ +/*- + * ============LICENSE_START======================================================= + * Integrity Monitor + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.policy.common.im.jpa; + +import java.io.Serializable; +import java.util.Date; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.NamedQuery; +import javax.persistence.PrePersist; +import javax.persistence.PreUpdate; +import javax.persistence.SequenceGenerator; +import javax.persistence.Table; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; + +@Entity +@Table(name="StateManagementEntity") +@NamedQuery(name="StateManagementEntity.findAll", query="SELECT e FROM StateManagementEntity e") +//@SequenceGenerator(name="seqSM", initialValue=1, allocationSize=1) + +public class StateManagementEntity implements Serializable { + private static final long serialVersionUID = 1L; + + @Id + //@GeneratedValue(strategy = GenerationType.SEQUENCE, generator="seqSM") + @GeneratedValue(strategy = GenerationType.AUTO) + @Column(name="id") + private long id; + + @Column(name="resourceName", nullable=false, length=100, unique=true) + private String resourceName; + + @Column(name="adminState", nullable=false, length=20) + private String adminState; + + @Column(name="opState", nullable=false, length=20) + private String opState; + + @Column(name="availStatus", nullable=false, length=20) + private String availStatus; + + @Column(name="standbyStatus", nullable=false, length=20) + private String standbyStatus; + + @Temporal(TemporalType.TIMESTAMP) + @Column(name="created_Date", updatable=false) + private Date created_Date; + + @Temporal(TemporalType.TIMESTAMP) + @Column(name="modifiedDate", nullable=false) + private Date modifiedDate; + + @PrePersist + public void prePersist() { + this.created_Date = new Date(); + this.modifiedDate = new Date(); + } + + @PreUpdate + public void preUpdate() { + this.modifiedDate = new Date(); + } + + public StateManagementEntity() { + } + + public String getResourceName() { + return this.resourceName; + } + public void setResourceName(String resourceName) { + this.resourceName = resourceName; + } + + public String getAdminState() { + return this.adminState; + } + + public void setAdminState(String adminState) { + this.adminState = adminState; + } + public String getOpState() { + return this.opState; + } + + public void setOpState(String opState) { + this.opState = opState; + + } + public String getAvailStatus() { + return this.availStatus; + } + + public void setAvailStatus(String availStatus) { + this.availStatus = availStatus; + } + public String getStandbyStatus() { + return this.standbyStatus; + } + + public void setStandbyStatus(String standbyStatus) { + this.standbyStatus = standbyStatus; + } + + public void setModifiedDate(Date modifiedDate) { + this.modifiedDate = modifiedDate; + } + + public static StateManagementEntity clone(StateManagementEntity sm) + { + StateManagementEntity newSM = new StateManagementEntity(); + newSM.setResourceName(sm.getResourceName()); + newSM.setAdminState(sm.getResourceName()); + newSM.setOpState(sm.getOpState()); + newSM.setAdminState(sm.getAdminState()); + newSM.setAvailStatus(sm.getAvailStatus()); + newSM.setStandbyStatus(sm.getStandbyStatus()); + + return newSM; + } +} -- cgit 1.2.3-korg