Batch submit

[ECOMPD2TD-1073 1707] Removal of extra flush statements and addition
of rollbacks in catch blocks instead of commits.

[ECOMPD2TD-1073 1707] Adding some needed synchronized statements to
IntegrityMonitor.

[ECOMPD2TD-1159] - Loggers should be Serializable

By making loggers Serializable, they can be included in Drools
persistent data. 'EelfLogger' and 'SystemOutLogger' can do this
trivially, but 'Logger4J' needed some additional work, because it has a
non-serializable field 'log'.

[ECOMPD2TD-000] Fix versioning of org.openecomp.policy.* dependencies

[US866186 1707] First cut of stateCheck mod and non-working JUnit

[US866186 1707] Completed the coding for the task TA1998344 which adds
a check of forward progress for dependencies.

[US866186 1707] Completed updates to IntegrityMonitor.stateCheck and
IntegrityMonitorTest which includes addition of a JUnit for stateCheck
and control of the order of JUnit execution.

[US865296] ECOMP Policy Logging Compliance, add TargetEntity and
TargetServiceName, remove unit from ElapsedTime

[US865296] ECOMP Policy Logging Compliance, set audit log statuscode to
'COMPLETE' instead of N/A

[US865296] ECOMP Policy Logging Compliance, remove time unit (seconds
and milliseconds) from ElapsedTime for logging compliance

[US866186 1707] Cleaned up IntegrityAudit JUnit tests.

[US866186 1707] IntegrityMonitor JUnit clean up

[US866186 1707] Re-added missing classes that were erroneously deleted.

[US865296] - add get/setters and inits for required log fields

Change-Id: I76ef4606ed6832ed48eaca68e72839a05c8bc3a8
Signed-off-by: Ralph Straubs <rs8887@att.com>
diff --git a/common-logging/src/main/java/org/openecomp/policy/common/logging/ECOMPLoggingContext.java b/common-logging/src/main/java/org/openecomp/policy/common/logging/ECOMPLoggingContext.java
index 71e75a1..e6e2b1c 100644
--- a/common-logging/src/main/java/org/openecomp/policy/common/logging/ECOMPLoggingContext.java
+++ b/common-logging/src/main/java/org/openecomp/policy/common/logging/ECOMPLoggingContext.java
@@ -75,6 +75,10 @@
 	private static final String THREAD_ID = "threadId";
 	private static final String SERVER_NAME = "serverName";
 	private static final String SERVICE_NAME = "serviceName";
+	private static final String PARTNER_NAME = "partnerName";
+	private static final String STATUS_CODE = "statusCode";
+	private static final String TARGET_ENTITY = "targetEntity";
+	private static final String TARGET_SERVICE_NAME = "targetServiceName";
 	private static final String INSTANCE_UUID = "instanceUuid";
 	private static final String SEVERITY = "severity";
 	private static final String SERVER_IP_ADDRESS = "serverIpAddress";
@@ -123,6 +127,11 @@
 		MDC.clear();
 		baseContext.context.transferTo(context);
 		transactionStartTime = baseContext.transactionStartTime;
+		setServiceName("POLICY");
+		setPartnerName("USER");
+		setStatusCode("COMPLETE");
+		setTargetEntity("POLICY");
+		setTargetServiceName("PE Process");
 	}
 	
 	/**
@@ -253,6 +262,70 @@
 	}
 	
 	/**
+	 * Set the value for the data item with key "partnerName"
+	 * 
+	 * @param id
+	 */
+	public void setPartnerName(String name) {
+		context.put(PARTNER_NAME, name);
+	}
+	/**
+	 * Get the value for the data item with key "partnerName"
+	 * @return current value, or empty string if not set
+	 */
+	public String getPartnerName() {
+		return context.get(PARTNER_NAME, "");
+	}
+	
+	/**
+	 * Set the value for the data item with key "statusCode"
+	 * 
+	 * @param id
+	 */
+	public void setStatusCode(String name) {
+		context.put(STATUS_CODE, name);
+	}
+	/**
+	 * Get the value for the data item with key "statusCode"
+	 * @return current value, or empty string if not set
+	 */
+	public String getStatusCode() {
+		return context.get(STATUS_CODE, "");
+	}
+	
+	/**
+	 * Set the value for the data item with key "targetEntity"
+	 * 
+	 * @param id
+	 */
+	public void setTargetEntity(String name) {
+		context.put(TARGET_ENTITY, name);
+	}
+	/**
+	 * Get the value for the data item with key "targetEntity"
+	 * @return current value, or empty string if not set
+	 */
+	public String getTargetEntity() {
+		return context.get(TARGET_ENTITY, "");
+	}
+	
+	/**
+	 * Set the value for the data item with key "targetServiceName"
+	 * 
+	 * @param id
+	 */
+	public void setTargetServiceName(String name) {
+		context.put(TARGET_SERVICE_NAME, name);
+	}
+	/**
+	 * Get the value for the data item with key "targetServiceName"
+	 * @return current value, or empty string if not set
+	 */
+	public String getTargetServiceName() {
+		return context.get(TARGET_SERVICE_NAME, "");
+	}
+	
+	/**
 	 * Set the value for the data item with key "instanceUuid"
 	 * 
 	 * @param id
@@ -433,17 +506,17 @@
 	 */
 	
 	public void setTransactionElapsedTime(Instant transactionEndTime) {
-		long ns = Duration.between(transactionStartTime, transactionEndTime).getSeconds();
-		String unit = " Seconds";
-		if(ns == 1){
-			unit = " Second";
-		}
+		long ns = Duration.between(transactionStartTime, transactionEndTime).toMillis();
+		//String unit = " Seconds";
+		//if(ns == 1){
+			//unit = " Second";
+		//}
 		
-		if(ns < 1){
-			ns = Duration.between(transactionStartTime, transactionEndTime).toMillis();
-			unit = " milliseconds";
-		}
-		context.put(TRANSACTION_ELAPSED_TIME, ns + unit);
+		//if(ns < 1){
+			//ns = Duration.between(transactionStartTime, transactionEndTime).toMillis();
+			//unit = " milliseconds";
+		//}
+		context.put(TRANSACTION_ELAPSED_TIME, ns); // + unit);
 	}
 
 	/**
@@ -506,17 +579,17 @@
 	 */
 	
 	public void setMetricElapsedTime(Instant metricEndTime) {
-		long ns = Duration.between(metricStartTime, metricEndTime).getSeconds();
-		String unit = " Seconds";
-		if(ns == 1){
-			unit = " Second";
-		}
+		long ns = Duration.between(metricStartTime, metricEndTime).toMillis();
+		//String unit = " Seconds";
+		//if(ns == 1){
+			//unit = " Second";
+		//}
 		
-		if(ns < 1){
-			ns = Duration.between(metricStartTime, metricEndTime).toMillis();
-			unit = " milliseconds";
-		}
-		context.put(METRIC_ELAPSED_TIME, ns + unit);
+		//if(ns < 1){
+			//ns = Duration.between(metricStartTime, metricEndTime).toMillis();
+			//unit = " milliseconds";
+		//}
+		context.put(METRIC_ELAPSED_TIME, ns); // + unit);
 	}
 
 	/**
diff --git a/common-logging/src/main/java/org/openecomp/policy/common/logging/eelf/Configuration.java b/common-logging/src/main/java/org/openecomp/policy/common/logging/eelf/Configuration.java
index a2a0b78..a839ea1 100644
--- a/common-logging/src/main/java/org/openecomp/policy/common/logging/eelf/Configuration.java
+++ b/common-logging/src/main/java/org/openecomp/policy/common/logging/eelf/Configuration.java
@@ -43,6 +43,16 @@
 	  */
 	public String PARTNER_NAME = "PartnerName";
 	
+	/**
+	 * Target Entity
+	 */
+    public String TARGET_ENTITY = "TargetEntity"; 
+	
+    /**
+     * Target service name
+     */
+	public String TARGET_SERVICE_NAME = "TargetServiceName"; 
+	
 	 /**
 	  * High level success or failure (COMPLETE or ERROR)
 	  */
diff --git a/common-logging/src/main/java/org/openecomp/policy/common/logging/eelf/PolicyLogger.java b/common-logging/src/main/java/org/openecomp/policy/common/logging/eelf/PolicyLogger.java
index 624ba58..ed03f9a 100644
--- a/common-logging/src/main/java/org/openecomp/policy/common/logging/eelf/PolicyLogger.java
+++ b/common-logging/src/main/java/org/openecomp/policy/common/logging/eelf/PolicyLogger.java
@@ -125,7 +125,13 @@
 		}
 		
 		if(component != null && component.equalsIgnoreCase("DROOLS")){
+			MDC.put(TARGET_ENTITY, "POLICY");
+			MDC.put(TARGET_SERVICE_NAME,  "drools evaluate rule");	
 			return postMDCInfoForEvent(transId, new DroolsPDPMDCInfo());
+		} else {
+			// For Xacml
+			MDC.put(TARGET_ENTITY, "POLICY");
+			MDC.put(TARGET_SERVICE_NAME,  "PE Process");
 		}
 		
 		MDC.put(MDC_REMOTE_HOST, "");
@@ -140,16 +146,16 @@
 		}
 		Instant startTime = Instant.now();
 		Instant endTime = Instant.now();
-		long ns = Duration.between(startTime, endTime).getSeconds();
-		String unit = " Seconds";
-		if(ns == 1){
-			unit = " Second";
-		}
+		long ns = Duration.between(startTime, endTime).toMillis(); // use millisecond as default and remove unit from log
+		//String unit = " Seconds";
+		//if(ns == 1){
+			//unit = " Second";
+		//}
 		
-		if(ns < 1){
-			ns = Duration.between(startTime, endTime).toMillis();
-			unit = " milliseconds";
-		}
+		//if(ns < 1){
+			//ns = Duration.between(startTime, endTime).toMillis();
+			//unit = " milliseconds";
+		//}
 		MDC.put(MDC_INSTANCE_UUID, "");
 		MDC.put(MDC_ALERT_SEVERITY, "");
 		
@@ -161,11 +167,11 @@
 		//set default values for these required fields below, they can be overridden
 		formatedTime = sdf.format(Date.from(endTime));
 		MDC.put(END_TIME_STAMP, formatedTime);
-		MDC.put(ELAPSED_TIME, ns + unit);
+		MDC.put(ELAPSED_TIME, Long.toString(ns)); // + unit);
 		
 		MDC.put(PARTNER_NAME, "N/A");
 		
-		MDC.put(STATUS_CODE, "N/A");
+		MDC.put(STATUS_CODE, "COMPLETE");
 		MDC.put(RESPONSE_CODE, "N/A");
 		MDC.put(RESPONSE_DESCRIPTION, "N/A");
 		
@@ -203,16 +209,16 @@
 		}
 		Instant startTime = Instant.now();
 		Instant endTime = Instant.now();
-		long ns = Duration.between(startTime, endTime).getSeconds();
-		String unit = " Seconds";
-		if(ns == 1){
-			unit = " Second";
-		}
+		long ns = Duration.between(startTime, endTime).toMillis(); // use millisecond as default and remove unit from log
+		//String unit = " Seconds";
+		//if(ns == 1){
+			//unit = " Second";
+		//}
 		
-		if(ns < 1){
-			ns = Duration.between(startTime, endTime).toMillis();
-			unit = " milliseconds";
-		}
+		//if(ns < 1){
+			//ns = Duration.between(startTime, endTime).toMillis();
+			//unit = " milliseconds";
+		//}
 
 		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS+00:00");
 	
@@ -222,7 +228,7 @@
 		//set default values for these required fields below, they can be overridden
 		formatedTime = sdf.format(Date.from(endTime));
 		MDC.put(END_TIME_STAMP, formatedTime);
-		MDC.put(ELAPSED_TIME, ns + unit);
+		MDC.put(ELAPSED_TIME, Long.toString(ns)); // + unit);
 
 		return transId;
 	}
@@ -234,16 +240,16 @@
 		
 		Instant startTime = Instant.now();
 		Instant endTime = Instant.now();
-		long ns = Duration.between(startTime, endTime).getSeconds();
-		String unit = " Seconds";
-		if(ns == 1){
-			unit = " Second";
-		}
+		long ns = Duration.between(startTime, endTime).toMillis();
+		//String unit = " Seconds";
+		//if(ns == 1){
+			//unit = " Second";
+		//}
 		
-		if(ns < 1){
-			ns = Duration.between(startTime, endTime).toMillis();
-			unit = " milliseconds";
-		}
+		//if(ns < 1){
+			//ns = Duration.between(startTime, endTime).toMillis();
+			//unit = " milliseconds";
+		//}
 		MDC.put(MDC_INSTANCE_UUID, "");
 		MDC.put(MDC_ALERT_SEVERITY, "");
 		
@@ -255,11 +261,11 @@
 		//set default values for these required fields below, they can be overridden
 		formatedTime = sdf.format(Date.from(endTime));
 		MDC.put(END_TIME_STAMP, formatedTime);
-		MDC.put(ELAPSED_TIME, ns + unit);
+		MDC.put(ELAPSED_TIME, Long.toString(ns)); // + unit);
 		
 		MDC.put(PARTNER_NAME, "N/A");
 		
-		MDC.put(STATUS_CODE, "N/A");
+		MDC.put(STATUS_CODE, "COMPLETE");
 		MDC.put(RESPONSE_CODE, "N/A");
 		MDC.put(RESPONSE_DESCRIPTION, "N/A");
 
@@ -315,7 +321,7 @@
 		}
 		MDC.put(MDC_INSTANCE_UUID, "");
 		MDC.put(MDC_ALERT_SEVERITY, "");
-		MDC.put(STATUS_CODE, "N/A");
+		MDC.put(STATUS_CODE, "COMPLETE");
 		
 		return transId;
 
@@ -634,7 +640,7 @@
 	 * @param arg0
 	 */
 	public static void audit(String className, Object arg0) {
-		MDC.put(STATUS_CODE, "N/A");
+		MDC.put(STATUS_CODE, "COMPLETE");
 		MDC.put(CLASS_NAME, className);
 		auditLogger.info("" + arg0);
 	}
@@ -644,7 +650,7 @@
 	 * @param arg0
 	 */
 	public static void audit(Object arg0) {
-		MDC.put(STATUS_CODE, "N/A");
+		MDC.put(STATUS_CODE, "COMPLETE");
 		MDC.put(CLASS_NAME, "");
 		auditLogger.info("" + arg0);
 	}
@@ -748,7 +754,7 @@
 	 */
 	public static void recordAuditEventStart(String eventId) {
 		
-		MDC.put(STATUS_CODE, "N/A");		
+		MDC.put(STATUS_CODE, "COMPLETE");		
 		postMDCInfoForEvent(eventId);
 		
 		if(eventTracker == null){
@@ -955,21 +961,21 @@
 		MDC.put(RESPONSE_CODE, "N/A");
 		MDC.put(RESPONSE_DESCRIPTION, "N/A");
 		
-		long ns = Duration.between(startTime, endTime).getSeconds();
-		String unit = " Seconds";
-		if(ns == 1){
-			unit = " Second";
-		}
+		long ns = Duration.between(startTime, endTime).toMillis();
+		//String unit = " Seconds";
+		//if(ns == 1){
+			//unit = " Second";
+		//}
 		
-		if(ns < 1){
-			ns = Duration.between(startTime, endTime).toMillis();
-			unit = " milliseconds";
-		}
+		//if(ns < 1){
+			//ns = Duration.between(startTime, endTime).toMillis();
+			//unit = " milliseconds";
+		//}
 		
-		MDC.put(ELAPSED_TIME, ns + unit);
+		MDC.put(ELAPSED_TIME, Long.toString(ns)); // + unit);
 		
 		auditLogger.info(MessageCodes.RULE_AUDIT_START_END_INFO,
-			serviceName, rule, startTime.toString(), endTime.toString(), ns+unit, policyVersion);
+			serviceName, rule, startTime.toString(), endTime.toString(), Long.toString(ns), policyVersion);
 		
 		//--- remove the record from the concurrentHashMap
 		if(eventTracker != null){
diff --git a/common-logging/src/main/java/org/openecomp/policy/common/logging/flexlogger/EelfLogger.java b/common-logging/src/main/java/org/openecomp/policy/common/logging/flexlogger/EelfLogger.java
index 6e74b94..31c1755 100644
--- a/common-logging/src/main/java/org/openecomp/policy/common/logging/flexlogger/EelfLogger.java
+++ b/common-logging/src/main/java/org/openecomp/policy/common/logging/flexlogger/EelfLogger.java
@@ -20,6 +20,7 @@
 
 package org.openecomp.policy.common.logging.flexlogger;
 
+import java.io.Serializable;
 import java.util.UUID;
 
 import org.openecomp.policy.common.logging.eelf.MessageCodes;
@@ -33,7 +34,7 @@
  *
  */
 
-public class EelfLogger implements Logger {
+public class EelfLogger implements Logger, Serializable {
 	
     private String className = "";
     private String transId = UUID.randomUUID().toString();
diff --git a/common-logging/src/main/java/org/openecomp/policy/common/logging/flexlogger/Logger4J.java b/common-logging/src/main/java/org/openecomp/policy/common/logging/flexlogger/Logger4J.java
index 02f95cf..23cafb4 100644
--- a/common-logging/src/main/java/org/openecomp/policy/common/logging/flexlogger/Logger4J.java
+++ b/common-logging/src/main/java/org/openecomp/policy/common/logging/flexlogger/Logger4J.java
@@ -20,6 +20,10 @@
 
 package org.openecomp.policy.common.logging.flexlogger;
 
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
 import java.util.UUID;
 
 import org.apache.log4j.Logger;
@@ -34,7 +38,7 @@
  * Logger4J implements all the methods of interface Logger by calling org.apache.log4j.Logger
  *
  */
-public class Logger4J implements org.openecomp.policy.common.logging.flexlogger.Logger {
+public class Logger4J implements org.openecomp.policy.common.logging.flexlogger.Logger, Serializable {
 	
 	private Logger log = null;
     private String methodName = "";
@@ -451,4 +455,30 @@
 	public void postMDCInfoForEvent(Object o){
     	log.info(o);
 	}
+
+	/* ============================================================ */
+
+	/*
+	 * Support for 'Serializable' --
+	 * the default rules don't work for the 'log' field
+	 */
+
+	private void writeObject(ObjectOutputStream out) throws IOException {
+		// write out 'methodName', 'className', 'transId' strings
+		out.writeObject(methodName);
+		out.writeObject(className);
+		out.writeObject(transId);
+	}
+
+	private void readObject(ObjectInputStream in)
+			throws IOException, ClassNotFoundException {
+
+		// read in 'methodName', 'className', 'transId' strings
+		methodName = (String)(in.readObject());
+		className = (String)(in.readObject());
+		transId = (String)(in.readObject());
+	
+		// look up associated logger
+		log = Logger.getLogger(className);
+	}
 }
diff --git a/common-logging/src/main/java/org/openecomp/policy/common/logging/flexlogger/SystemOutLogger.java b/common-logging/src/main/java/org/openecomp/policy/common/logging/flexlogger/SystemOutLogger.java
index 26f0664..91e16b9 100644
--- a/common-logging/src/main/java/org/openecomp/policy/common/logging/flexlogger/SystemOutLogger.java
+++ b/common-logging/src/main/java/org/openecomp/policy/common/logging/flexlogger/SystemOutLogger.java
@@ -20,6 +20,7 @@
 
 package org.openecomp.policy.common.logging.flexlogger;
 
+import java.io.Serializable;
 import java.util.UUID;
 
 import org.openecomp.policy.common.logging.eelf.MessageCodes;
@@ -31,7 +32,7 @@
  * SystemOutLogger implements all the methods of interface Logger by calling System.out.println
  *
  */
-public class SystemOutLogger implements Logger {
+public class SystemOutLogger implements Logger, Serializable {
 	
 	private String className = "";
 	private boolean isDebugEnabled = true;
diff --git a/integrity-audit/src/main/java/org/openecomp/policy/common/ia/DbAudit.java b/integrity-audit/src/main/java/org/openecomp/policy/common/ia/DbAudit.java
index 9af8999..b509d56 100644
--- a/integrity-audit/src/main/java/org/openecomp/policy/common/ia/DbAudit.java
+++ b/integrity-audit/src/main/java/org/openecomp/policy/common/ia/DbAudit.java
@@ -242,8 +242,6 @@
 		}
 		
 		// If misMatchedMap is not empty, retrieve the entries in each misMatched list and compare again
-		
-		//classNameSet = (HashSet<String>) misMatchedMap.keySet();
 		classNameSet = new HashSet<String>(misMatchedMap.keySet());
 		// We need to keep track of how long the audit is taking
 		startTime = System.currentTimeMillis();
diff --git a/integrity-audit/src/test/java/org/openecomp/policy/common/ia/test/AuditPeriodTest.java b/integrity-audit/src/test/java/org/openecomp/policy/common/ia/test/AuditPeriodTest.java
index 649b71f..d0c6406 100644
--- a/integrity-audit/src/test/java/org/openecomp/policy/common/ia/test/AuditPeriodTest.java
+++ b/integrity-audit/src/test/java/org/openecomp/policy/common/ia/test/AuditPeriodTest.java
@@ -49,6 +49,11 @@
 import org.openecomp.policy.common.logging.flexlogger.FlexLogger; 
 import org.openecomp.policy.common.logging.flexlogger.Logger;
 
+/*
+ * All JUnits are designed to run in the local development environment
+ * where they have write privileges and can execute time-sensitive
+ * tasks.
+ */
 public class AuditPeriodTest {
 	
 	private static Logger logger = FlexLogger.getLogger(AuditPeriodTest.class);
diff --git a/integrity-audit/src/test/java/org/openecomp/policy/common/ia/test/DbAuditCompareEntriesTest.java b/integrity-audit/src/test/java/org/openecomp/policy/common/ia/test/DbAuditCompareEntriesTest.java
index f109689..5b3c755 100644
--- a/integrity-audit/src/test/java/org/openecomp/policy/common/ia/test/DbAuditCompareEntriesTest.java
+++ b/integrity-audit/src/test/java/org/openecomp/policy/common/ia/test/DbAuditCompareEntriesTest.java
@@ -51,6 +51,11 @@
 import org.openecomp.policy.common.logging.flexlogger.FlexLogger; 
 import org.openecomp.policy.common.logging.flexlogger.Logger;
 
+/*
+ * All JUnits are designed to run in the local development environment
+ * where they have write privileges and can execute time-sensitive
+ * tasks.
+ */
 public class DbAuditCompareEntriesTest {
 
 	private static Logger logger = FlexLogger.getLogger(DbAuditCompareEntriesTest.class);
diff --git a/integrity-audit/src/test/java/org/openecomp/policy/common/ia/test/DbAuditTest.java b/integrity-audit/src/test/java/org/openecomp/policy/common/ia/test/DbAuditTest.java
index a84281d..21e3bfa 100644
--- a/integrity-audit/src/test/java/org/openecomp/policy/common/ia/test/DbAuditTest.java
+++ b/integrity-audit/src/test/java/org/openecomp/policy/common/ia/test/DbAuditTest.java
@@ -55,6 +55,11 @@
 import org.openecomp.policy.common.logging.flexlogger.FlexLogger; 
 import org.openecomp.policy.common.logging.flexlogger.Logger;
 
+/*
+ * All JUnits are designed to run in the local development environment
+ * where they have write privileges and can execute time-sensitive
+ * tasks.
+ */
 public class DbAuditTest {
 	
 	private static Logger logger = FlexLogger.getLogger(DbAuditTest.class);
diff --git a/integrity-audit/src/test/java/org/openecomp/policy/common/ia/test/DbDAOTest.java b/integrity-audit/src/test/java/org/openecomp/policy/common/ia/test/DbDAOTest.java
index 31fd0be..351fe5f 100644
--- a/integrity-audit/src/test/java/org/openecomp/policy/common/ia/test/DbDAOTest.java
+++ b/integrity-audit/src/test/java/org/openecomp/policy/common/ia/test/DbDAOTest.java
@@ -22,6 +22,11 @@
 
 import static org.junit.Assert.*;
 
+/*
+ * All JUnits are designed to run in the local development environment
+ * where they have write privileges and can execute time-sensitive
+ * tasks.
+ */
 import java.util.Date;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -49,6 +54,11 @@
 import org.openecomp.policy.common.ia.IntegrityAuditProperties;
 import org.openecomp.policy.common.ia.jpa.IntegrityAuditEntity;
 
+/*
+ * All JUnits are designed to run in the local development environment
+ * where they have write privileges and can execute time-sensitive
+ * tasks.
+ */
 public class DbDAOTest {
 	private static String persistenceUnit;
 	private static Properties properties;
diff --git a/integrity-audit/src/test/java/org/openecomp/policy/common/ia/test/IntegrityAuditDesignationTest.java b/integrity-audit/src/test/java/org/openecomp/policy/common/ia/test/IntegrityAuditDesignationTest.java
index 6eb5fa4..69936bf 100644
--- a/integrity-audit/src/test/java/org/openecomp/policy/common/ia/test/IntegrityAuditDesignationTest.java
+++ b/integrity-audit/src/test/java/org/openecomp/policy/common/ia/test/IntegrityAuditDesignationTest.java
@@ -51,6 +51,11 @@
 import org.openecomp.policy.common.logging.flexlogger.FlexLogger; 
 import org.openecomp.policy.common.logging.flexlogger.Logger;
 
+/*
+ * All JUnits are designed to run in the local development environment
+ * where they have write privileges and can execute time-sensitive
+ * tasks.
+ */
 public class IntegrityAuditDesignationTest {
 	
 	private static Logger logger = FlexLogger.getLogger(IntegrityAuditDesignationTest.class);
@@ -58,7 +63,7 @@
 	/*
 	 * Provides a little cushion for timing events.
 	 */
-	private static int FUDGE_FACTOR = 5000;
+	private static int FUDGE_FACTOR = 15000;
 	
 	private static String persistenceUnit;
 	private static Properties properties;
@@ -1028,29 +1033,31 @@
 		IntegrityAudit integrityAudit3 = new IntegrityAudit(resourceName3, persistenceUnit3, properties3);
 				
 		// Start audit on pdp1
+		logger.info("testDesignatedNodeDead: Start audit on pdp1");
 		integrityAudit.startAuditThread();			
 
-		// Sleep long enough for pdp1 figure out that it should be auditing and start the audit.
-		Thread.sleep(500); 
-		
 		// Start the auditing threads on other nodes.
+		logger.info("testDesignatedNodeDead: Start audit on pdp2");
 		integrityAudit2.startAuditThread();	
+		logger.info("testDesignatedNodeDead: Start audit on pdp3");
 		integrityAudit3.startAuditThread();		
 		
-		// Sleep long enough to ensure the other two audits have registered. 
-		Thread.sleep(500); 
-		
+
 		// Kill audit on pdp1
+		logger.info("testDesignatedNodeDead: Kill audit on pdp1");
 		integrityAudit.stopAuditThread();
 		
 		// Sleep long enough for pdp1 to get stale and pdp2 to take over
+		logger.info("testDesignatedNodeDead: Sleep long enough for pdp1 to get stale and pdp2 to take over");
 		Thread.sleep(AuditThread.AUDIT_COMPLETION_INTERVAL + FUDGE_FACTOR); 
 		
 		// Start audit thread on pdp1 again.
+		logger.info("testDesignatedNodeDead: Start audit thread on pdp1 again.");
 		integrityAudit.startAuditThread(); 
 		
 		// Sleep long enough for pdp2 to complete its audit and get stale, at
 		// which point pdp3 should take over
+		logger.info("testDesignatedNodeDead: Sleep long enough for pdp2 to complete its audit and get stale, at which point pdp3 should take over");
 		Thread.sleep((AuditThread.AUDIT_SIMULATION_SLEEP_INTERVAL * AuditThread.AUDIT_SIMULATION_ITERATIONS)
 				+ AuditThread.AUDIT_COMPLETION_INTERVAL + FUDGE_FACTOR);
 		
@@ -1059,6 +1066,7 @@
 		integrityAudit3.stopAuditThread();
 		
 		// Sleep long enough for pdp3 to get stale and pdp1 to take over
+		logger.info("testDesignatedNodeDead: Sleep long enough for pdp3 to get stale and pdp1 to take over");
 		Thread.sleep(AuditThread.AUDIT_COMPLETION_INTERVAL + FUDGE_FACTOR); 
 				
 		FileInputStream fstream = new FileInputStream(TEST_LOG);
diff --git a/integrity-monitor/config/policyLogger.properties b/integrity-monitor/config/policyLogger.properties
new file mode 100644
index 0000000..1e7187f
--- /dev/null
+++ b/integrity-monitor/config/policyLogger.properties
@@ -0,0 +1,44 @@
+###
+# ============LICENSE_START=======================================================
+# Integrity Audit
+# ================================================================================
+# 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=========================================================
+###
+
+################################### Set concurrentHashMap and timer info  #######################
+#Timer initial delay and the delay between in milliseconds before task is to be execute.
+timer.delay.time=1000
+#Timer scheduleAtFixedRate period - time in milliseconds between successive task executions.
+check.interval= 30000
+#Longest time an event info can be stored in the concurrentHashMap for logging - in seconds. 
+event.expired.time=86400
+#Size of the concurrentHashMap which stores the event starting time, etc - when its size reaches this limit, the Timer gets executed 
+#to remove all expired records from this concurrentHashMap.
+concurrentHashMap.limit=5000
+#Size of the concurrentHashMap - when its size drops to this point, stop the Timer
+stop.check.point=2500
+################################### Set logging format #############################################
+# set EELF for EELF logging format, set LOG4J for using log4j, set SYSTEMOUT for using system.out.println
+logger.type=EELF
+#################################### Set level for EELF or SYSTEMOUT logging ##################################
+# Set level for debug file. Set DEBUG to enable .info, .warn and .debug; set INFO for enable .info and .warn; set OFF to disable all 
+debugLogger.level=INFO
+# Set level for metrics file. Set OFF to disable; set ON to enable
+metricsLogger.level=ON
+# Set level for error file. Set OFF to disable; set ON to enable
+error.level=ON
+# Set level for audit file. Set OFF to disable; set ON to enable
+audit.level=ON
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
index 6c575ab..293bd11 100644
--- 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
@@ -37,14 +37,15 @@
 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.FlexLogger;
 import org.openecomp.policy.common.logging.flexlogger.Logger;
+//import org.apache.log4j.Logger;
+import org.openecomp.policy.common.im.jmx.ComponentAdmin;
+import org.openecomp.policy.common.im.jmx.ComponentAdminMBean;
+import org.openecomp.policy.common.im.jmx.JmxAgentConnection;
 
 /**
  * IntegrityMonitor
@@ -309,7 +310,6 @@
         	em.persist(rrx);
         	// flush to the DB
         	synchronized(IMFLUSHLOCK){
-        		em.flush();
         		et.commit();
         	}
         
@@ -442,59 +442,145 @@
 		}
 
 	}
-	
-	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");
+	/*
+	 * This method checks the forward progress counter and the state of
+	 * a dependency.  If the dependency is unavailable or failed, an
+	 * error message is created which is checked when evaluateSanity interface
+	 * is called.  If the error message is set then the  evaluateSanity
+	 * will return an error.  
+	 */
+	public String stateCheck(String dep) {
+		logger.debug("checking state of dependent resource: " + dep);
+
+		String error_msg = null;
+		ForwardProgressEntity forwardProgressEntity = null;
+		StateManagementEntity stateManagementEntity = null;
+		
+		// Start a transaction
+		EntityTransaction et = em.getTransaction();
+		et.begin();
+
+		try{
+			Query query = em.createQuery("Select p from ForwardProgressEntity 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);
+			List fpList = query.setLockMode(
+					LockModeType.NONE).setFlushMode(FlushModeType.COMMIT).getResultList();
+
+			if (!fpList.isEmpty()) {
+				// exists
+				forwardProgressEntity = (ForwardProgressEntity) fpList.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);
+				em.refresh(forwardProgressEntity);
+				logger.debug("Found entry in ForwardProgressEntity table for dependent Resource=" + dep);
 			} else {
-				error_msg = dep + ": resource not found in state management entity database table";
+				error_msg = dep + ": resource not found in ForwardProgressEntity database table";
+				logger.debug(error_msg);
 				logger.error(error_msg);
 			}
-
 			synchronized(IMFLUSHLOCK){
 				et.commit();
 			}
-		} catch (Exception e) {
+		}
+		catch(Exception ex){
 			// log an error
-			error_msg = dep + ": StateManagementEntity DB read failed with exception: " + e;
+			error_msg = dep + ": ForwardProgressEntity DB operation failed with exception: " + ex;
+			logger.debug(error_msg);
 			logger.error(error_msg);
+			synchronized(IMFLUSHLOCK){
+				if(et.isActive()){
+					et.rollback();
+				}
+			}
+		}
+
+		if(error_msg==null){
+			// Start a transaction
+			et = em.getTransaction();
+			et.begin();
+			try {
+				// 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.debug(error_msg);
+					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.debug(error_msg);
+				logger.error(error_msg);
+				synchronized(IMFLUSHLOCK){
+					if(et.isActive()){
+						et.rollback();
+					}
+				}
+			}
+		}
+
+		//verify that the ForwardProgress is current (check last_updated)
+		if(error_msg==null){
+			Date date = new Date();
+			long diffMs = date.getTime() - forwardProgressEntity.getLastUpdated().getTime();
+			logger.debug("IntegrityMonitor.stateCheck(): diffMs = " + diffMs);
+
+			//Threshold for a stale entry
+			long staleMs = failedCounterThreshold * monitorInterval * 1000;
+			logger.debug("IntegrityMonitor.stateCheck(): staleMs = " + staleMs);
+
+			if(diffMs > staleMs){
+				//ForwardProgress is stale.  Disable it
+				try {
+					if(!stateManagementEntity.getOpState().equals(StateManagement.DISABLED)){
+						logger.debug("IntegrityMonitor.stateCheck(): Changing OpStat = disabled for " + dep);
+						stateManager.disableFailed(dep);
+					}
+				} catch (Exception e) {
+					String msg = "IntegrityMonitor.stateCheck(): Failed to diableFail dependent resource = " + dep 
+							+ "; " + e.getMessage();
+					logger.debug(msg);
+					logger.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.debug(error_msg);
 				logger.error(error_msg);
 			} else if ((stateManager.getOpState() != null) && stateManagementEntity.getOpState().equals(StateManagement.DISABLED)) {
 				error_msg = dep + ": resource is operationally disabled";
+				logger.debug(error_msg);
 				logger.error(error_msg);
 			} else if ((stateManager.getStandbyStatus() != null) && stateManagementEntity.getStandbyStatus().equals(StateManagement.COLD_STANDBY)) {
 				error_msg = dep + ": resource is cold standby";
+				logger.debug(error_msg);
 				logger.error(error_msg);
 			}
 		}
 		
+		String returnMsg = "IntegrityMonitor.stateCheck(): returned error_msg: " + error_msg;
+		logger.debug(returnMsg);
 		return error_msg;
 	}
 	
@@ -551,6 +637,11 @@
 			// log an error and continue
 			error_msg = dep + ": ForwardProgressEntity DB read failed with exception: " + e;
 			logger.error(error_msg);
+			synchronized(IMFLUSHLOCK){
+				if(et.isActive()){
+					et.rollback();
+				}
+			}
 		}
 		
 		return error_msg;
@@ -563,11 +654,10 @@
 
 		// get the JMX URL from the database
 		String jmxUrl = null;
+		// Start a transaction
+		EntityTransaction et = em.getTransaction();
+		et.begin();
 		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);
@@ -595,6 +685,11 @@
 		} catch (Exception e) {
 			error_msg = dep + ": ResourceRegistrationEntity DB read failed with exception: " + e;
 			logger.error(error_msg);
+			synchronized(IMFLUSHLOCK){
+				if(et.isActive()){
+					et.rollback();
+				}
+			}
 		}
 
 
@@ -876,7 +971,6 @@
 				em.persist(fpx);
 				// flush to the DB and commit
 				synchronized(IMFLUSHLOCK){
-					em.flush();
 					et.commit();
 				}
 			}
@@ -887,8 +981,10 @@
 			}
         } catch (Exception e) {
         	try {
-        		if (et.isActive()) {
-        			et.rollback();
+        		synchronized(IMFLUSHLOCK){
+        			if (et.isActive()) {
+        				et.rollback();
+        			}
         		}
         	} catch (Exception e1) {
         		// ignore
@@ -965,18 +1061,6 @@
 			}
 		}
 		
-		/***********************
-		// 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
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
index 14d35e1..fd0f3d9 100644
--- 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
@@ -129,16 +129,11 @@
           logger.debug("Persist adminstrative state, resourceName = " + this.resourceName); 
           em.persist(sm);
           synchronized(FLUSHLOCK){
-        	  em.flush();
-        	  if(et.isActive()){
-        		  et.commit(); 
-        	  }
+       		  et.commit(); 
           }
         } else {
         	synchronized(FLUSHLOCK){
-        		if(et.isActive()){
-        			et.commit(); 
-        		}
+       			et.commit(); 
         	}
         }
         
@@ -147,13 +142,13 @@
 
         logger.debug("StateManagement: constructor end, resourceName: " + this.resourceName);
       } catch(Exception ex) {
+    	  logger.error("StateManagement: constructor caught unexpected exception: " + ex);
+    	  ex.printStackTrace();
     	  synchronized(FLUSHLOCK){
     		  if(et.isActive()){
-    			  et.commit();
+    			  et.rollback();
     		  }
     	  }
-    	  ex.printStackTrace();
-    	  logger.error("StateManagement: constructor caught unexpected exception: " + ex);
     	  throw new Exception("StateManagement: Exception: " + ex.toString());
       } 
   }
@@ -186,23 +181,20 @@
 
 			  em.persist(sm);
 			  synchronized(FLUSHLOCK){
-				  em.flush();
-				  if(et.isActive()){
-					  et.commit(); 
-				  }
+				  et.commit(); 
 			  }
 			  setChanged();
 			  notifyObservers(ADMIN_STATE);
 
 			  logger.debug("StateManagement: initializeState() operation completed, resourceName = " + this.resourceName);
 		  } catch(Exception ex) {
+			  logger.error("StateManagement.initializeState() caught unexpected exception: " + ex);
+			  ex.printStackTrace();
 			  synchronized(FLUSHLOCK){
 				  if(et.isActive()){
-					  et.commit();
+					  et.rollback();
 				  }
 			  }
-			  ex.printStackTrace();
-			  logger.error("StateManagement.initializeState() caught unexpected exception: " + ex);
 			  throw new Exception("StateManagement.initializeState() Exception: " + ex);
 		  }
 	  }
@@ -237,23 +229,20 @@
 
 			  em.persist(sm);
 			  synchronized(FLUSHLOCK){
-				  em.flush();
-				  if(et.isActive()){
-					  et.commit(); 
-				  }
+				  et.commit(); 
 			  }
 			  setChanged();
 			  notifyObservers(ADMIN_STATE);
 
 			  logger.debug("StateManagement: lock() operation completed, resourceName = " + this.resourceName);
 		  } catch(Exception ex) {
+			  logger.error("StateManagement.lock() caught unexpected exception: " + ex);
+			  ex.printStackTrace();
 			  synchronized(FLUSHLOCK){
 				  if(et.isActive()){
-					  et.commit();
+					  et.rollback();
 				  }
 			  }
-			  ex.printStackTrace();
-			  logger.error("StateManagement.lock() caught unexpected exception: " + ex);
 			  throw new Exception("StateManagement.lock() Exception: " + ex.toString());
 		  } 
 	  }
@@ -287,23 +276,20 @@
 
 			  em.persist(sm);
 			  synchronized(FLUSHLOCK){
-				  em.flush();
-				  if(et.isActive()){
-					  et.commit(); 
-				  }
+				  et.commit(); 
 			  }
 			  setChanged();
 			  notifyObservers(ADMIN_STATE);
 
 			  logger.debug("StateManagement: unlock() operation completed, resourceName = " + this.resourceName);
 		  } catch(Exception ex) {
+			  logger.error("StateManagement.unlock() caught unexpected exception: " + ex);
+			  ex.printStackTrace();
 			  synchronized(FLUSHLOCK){
 				  if(et.isActive()){
-					  et.commit();
+					  et.rollback();
 				  }
 			  }
-			  ex.printStackTrace();
-			  logger.error("StateManagement.unlock() caught unexpected exception: " + ex);
 			  throw new Exception("StateManagement.unlock() Exception: " + ex);
 		  }
 	  }
@@ -338,23 +324,20 @@
 
 			  em.persist(sm);
 			  synchronized(FLUSHLOCK){
-				  em.flush();
-				  if(et.isActive()){
-					  et.commit(); 
-				  }
+				  et.commit(); 
 			  }
 			  setChanged();
 			  notifyObservers(OPERATION_STATE);
 
 			  logger.debug("StateManagement enableNotFailed() operation completed, resourceName = " + this.resourceName);
 		  } catch(Exception ex) {
+			  logger.error("StateManagement.enableNotFailed() caught unexpected exception: " + ex);
+			  ex.printStackTrace();
 			  synchronized(FLUSHLOCK){
 				  if(et.isActive()){
-					  et.commit();
+					  et.rollback();
 				  }
 			  }
-			  ex.printStackTrace();
-			  logger.error("StateManagement.enableNotFailed() caught unexpected exception: " + ex);
 			  throw new Exception("StateManagement.enableNotFailed() Exception: " + ex);
 		  }
 	  }
@@ -387,23 +370,20 @@
 
 			  em.persist(sm);
 			  synchronized(FLUSHLOCK){
-				  em.flush();
-				  if(et.isActive()){
-					  et.commit(); 
-				  }
+				  et.commit(); 
 			  }
 			  setChanged();
 			  notifyObservers(OPERATION_STATE);
 
 			  logger.debug("StateManagement: disableFailed() operation completed, resourceName = " + this.resourceName);
 		  } catch(Exception ex) {
+			  logger.error("StateManagement.disableFailed() caught unexpected exception: " + ex);
+			  ex.printStackTrace();
 			  synchronized(FLUSHLOCK){
 				  if(et.isActive()){
-					  et.commit();
+					  et.rollback();
 				  }
 			  }
-			  ex.printStackTrace();
-			  logger.error("StateManagement.disableFailed() caught unexpected exception: " + ex);
 			  throw new Exception("StateManagement.disableFailed() Exception: " + ex);
 		  }
 	  }
@@ -442,10 +422,7 @@
 
 			  em.persist(sm);
 			  synchronized(FLUSHLOCK){
-				  em.flush();
-				  if(et.isActive()){
-					  et.commit(); 
-				  }
+				  et.commit(); 
 			  }
 			  setChanged();
 			  notifyObservers(OPERATION_STATE);
@@ -453,13 +430,13 @@
 			  logger.debug("StateManagement: disableFailed(otherResourceName) operation completed, resourceName = " 
 					  + otherResourceName);
 		  } catch(Exception ex) {
+			  logger.error("StateManagement.disableFailed(otherResourceName) caught unexpected exception: " + ex);
+			  ex.printStackTrace();
 			  synchronized(FLUSHLOCK){
 				  if(et.isActive()){
-					  et.commit();
+					  et.rollback();
 				  }
 			  }
-			  ex.printStackTrace();
-			  logger.error("StateManagement.disableFailed(otherResourceName) caught unexpected exception: " + ex);
 			  throw new Exception("StateManagement.disableFailed(otherResourceName) Exception: " + ex);
 		  }
 	  }
@@ -493,23 +470,20 @@
 
 			  em.persist(sm);
 			  synchronized(FLUSHLOCK){
-				  em.flush();
-				  if(et.isActive()){
-					  et.commit(); 
-				  }
+				  et.commit(); 
 			  }
 			  setChanged();
 			  notifyObservers(OPERATION_STATE);
 
 			  logger.debug("StateManagement: disableDependency() operation completed, resourceName = " + this.resourceName);
 		  } catch(Exception ex) {
+			  logger.error("StateManagement.disableDependency() caught unexpected exception: " + ex);
+			  ex.printStackTrace();
 			  synchronized(FLUSHLOCK){
 				  if(et.isActive()){
-					  et.commit();
+					  et.rollback();
 				  }
 			  }
-			  ex.printStackTrace();
-			  logger.error("StateManagement.disableDependency() caught unexpected exception: " + ex);
 			  throw new Exception("StateManagement.disableDependency() Exception: " + ex);
 		  }
 	  }
@@ -544,23 +518,20 @@
 
 			  em.persist(sm);
 			  synchronized(FLUSHLOCK){
-				  em.flush(); 
-				  if(et.isActive()){
-					  et.commit(); 
-				  }
+				  et.commit(); 
 			  }
 			  setChanged();
 			  notifyObservers(OPERATION_STATE);
 
 			  logger.debug("StateManagement: enableNoDependency() operation completed, resourceName = " + this.resourceName);
 		  } catch(Exception ex) {
+			  logger.error("StateManagement.enableNoDependency() caught unexpected exception: " + ex);
+			  ex.printStackTrace();
 			  synchronized(FLUSHLOCK){
 				  if(et.isActive()){
-					  et.commit();
+					  et.rollback();
 				  }
 			  }
-			  ex.printStackTrace();
-			  logger.error("StateManagement.enableNoDependency() caught unexpected exception: " + ex);
 			  throw new Exception("StateManagement.enableNoDependency() Exception: " + ex);
 		  }
 	  }
@@ -597,7 +568,6 @@
 
 			  em.persist(sm);
 			  synchronized(FLUSHLOCK){
-				  em.flush();
 				  if(et.isActive()){
 					  et.commit(); 
 				  }
@@ -605,13 +575,13 @@
 			  setChanged();
 			  notifyObservers(STANDBY_STATUS);
 		  }catch(Exception ex){
+			  logger.error("StateManagement.promote() caught unexpected exception: " + ex);
+			  ex.printStackTrace();
 			  synchronized(FLUSHLOCK){
 				  if(et.isActive()){
-					  et.commit();
+					  et.rollback();
 				  }
 			  }
-			  ex.printStackTrace();
-			  logger.error("StateManagement.promote() caught unexpected exception: " + ex);
 			  throw new Exception("StateManagement.promote() Exception: " + ex);
 		  }
 
@@ -651,23 +621,20 @@
 
 			  em.persist(sm);
 			  synchronized(FLUSHLOCK){
-				  em.flush();
-				  if(et.isActive()){
-					  et.commit(); 
-				  }
+				  et.commit(); 
 			  }
 			  setChanged();
 			  notifyObservers(STANDBY_STATUS); 
 
 			  logger.debug("StateManagement: demote() operation completed, resourceName = " + this.resourceName);
 		  } catch(Exception ex) {
+			  logger.error("StateManagement.demote() caught unexpected exception: " + ex);
+			  ex.printStackTrace();
 			  synchronized(FLUSHLOCK){
 				  if(et.isActive()){
-					  et.commit();
+					  et.rollback();
 				  }
 			  }
-			  ex.printStackTrace();
-			  logger.error("StateManagement.demote() caught unexpected exception: " + ex);
 			  throw new Exception("StateManagement.demote() Exception: " + ex);
 		  }
 	  }
@@ -710,22 +677,19 @@
 
 			  em.persist(sm);
 			  synchronized(FLUSHLOCK){
-				  em.flush();
-				  if(et.isActive()){
-					  et.commit(); 
-				  }
+				  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) {
+			  logger.error("StateManagement.demote(otherResourceName) caught unexpected exception: " + ex);
+			  ex.printStackTrace();
 			  synchronized(FLUSHLOCK){
 				  if(et.isActive()){
-					  et.commit();
+					  et.rollback();
 				  }
 			  }
-			  ex.printStackTrace();
-			  logger.error("StateManagement.demote(otherResourceName) caught unexpected exception: " + ex);
 			  throw new Exception("StateManagement.demote(otherResourceName) Exception: " + ex);
 		  }
 	  }
@@ -914,6 +878,7 @@
 
 		String standbyStatus = null;
 		
+		// The transaction is required for the LockModeType
 		EntityTransaction et = em.getTransaction();
 		if(!et.isActive()){
 			et.begin();
@@ -940,17 +905,19 @@
 				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()){
+			synchronized(FLUSHLOCK){
 				et.commit();
 			}
+		} catch (Exception e) {
+			logger.error("getStandbyStatus: Caught Exception attempting to get statemanagemententity record, message='"
+					+ e.getMessage() + "'");
+			e.printStackTrace();
+			synchronized(FLUSHLOCK){
+				if(et.isActive()){
+					et.rollback();
+				}
+			}
 		}
-
 		if (logger.isDebugEnabled()) {
 			logger.debug("getStandbyStatus: Returning standbyStatus="
 					+ standbyStatus);
@@ -989,27 +956,21 @@
 					  + 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();
 		  }
+	  }catch(Exception ex){
+		  logger.error("StateManagement.deleteAllStateManagementEntities() caught Exception: " + ex);
+		  ex.printStackTrace();
+		  synchronized(FLUSHLOCK){
+			  if(et.isActive()){
+				  et.rollback();
+			  }
+		  }
 	  }
-
-	  logger.info("deleteAllStateManagementEntities: Exiting");
-
+	  if(logger.isDebugEnabled()){
+		  logger.info("deleteAllStateManagementEntities: Exiting");
+	  }
   }
 
 }
diff --git a/integrity-monitor/src/test/java/org/openecomp/policy/common/im/test/IntegrityMonitorTest.java b/integrity-monitor/src/test/java/org/openecomp/policy/common/im/test/IntegrityMonitorTest.java
index 68a6cf2..7375988 100644
--- a/integrity-monitor/src/test/java/org/openecomp/policy/common/im/test/IntegrityMonitorTest.java
+++ b/integrity-monitor/src/test/java/org/openecomp/policy/common/im/test/IntegrityMonitorTest.java
@@ -53,6 +53,11 @@
 import org.openecomp.policy.common.logging.flexlogger.FlexLogger; 
 import org.openecomp.policy.common.logging.flexlogger.Logger;
 
+/*
+ * All JUnits are designed to run in the local development environment
+ * where they have write privileges and can execute time-sensitive
+ * tasks.
+ */
 public class IntegrityMonitorTest {
 	private static Logger logger = FlexLogger.getLogger(IntegrityMonitorTest.class);
 	private static Properties myProp;
@@ -103,6 +108,21 @@
 		// clear jmx remote port setting
 		systemProps.remove("com.sun.management.jmxremote.port");
 	}
+	
+	/*
+	 * The following runs all tests and controls the order of execution. If you allow
+	 * the tests to execute individually, you cannot predict the order and some
+	 * conflicts occur.
+	 */
+	@Ignore
+	@Test
+	public void runAllTests() throws Exception{
+		testSanityJmx();
+		testIM();
+		testSanityState();
+		testRefreshStateAudit();
+		testStateCheck();
+	}
 
 	/*
 	 * The following test verifies the following test cases:
@@ -114,8 +134,6 @@
 	 * Unlock
 	 * Unlock restart
 	 */
-	@Ignore // Test passed 10/18/16 
-	@Test
 	public void testSanityJmx() throws Exception {
 		System.out.println("\nIntegrityMonitorTest: Entering testSanityJmx\n\n");
 		
@@ -267,8 +285,6 @@
 	}
 	
 
-	@Ignore  // Test passed 10/18/16 
-	@Test
 	public void testIM() throws Exception {
 		System.out.println("\nIntegrityMonitorTest: Entering testIM\n\n");
 		
@@ -554,8 +570,6 @@
 	}
 	
 
-	@Ignore  // Test passed 10/18/16 
-	@Test
 	public void testSanityState() throws Exception {
 		System.out.println("\nIntegrityMonitorTest: Entering testSanityState\n\n");
 		
@@ -618,8 +632,6 @@
 		System.out.println("\n\ntestSanityState: Exit\n\n");
 	}
 	
-	@Ignore  // Test passed 10/18/16 
-	@Test
 	public void testRefreshStateAudit() throws Exception {
 		logger.debug("\nIntegrityMonitorTest: testRefreshStateAudit Enter\n\n");
 
@@ -731,4 +743,94 @@
 
 		logger.debug("\nIntegrityMonitorTest: testRefreshStateAudit Exit\n\n");
 	}
+	
+	public void testStateCheck() throws Exception {
+		System.out.println("\nIntegrityMonitorTest: Entering testStateCheck\n\n");
+		
+		// parameters are passed via a properties file
+		myProp.put(IntegrityMonitorProperties.DEPENDENCY_GROUPS, "group1_dep1");
+		myProp.put(IntegrityMonitorProperties.TEST_VIA_JMX, "false");
+		myProp.put(IntegrityMonitorProperties.FAILED_COUNTER_THRESHOLD, "1");
+		myProp.put(IntegrityMonitorProperties.FP_MONITOR_INTERVAL, "10");
+		IntegrityMonitor.updateProperties(myProp);
+		/*
+		 *  The default monitorInterval is 30 and the default failedCounterThreshold is 3
+		 *  Since stateCheck() uses the faileCounterThreshold * monitorInterval to determine
+		 *  if an entry is stale, it will be stale after 30 seconds.
+		 */
+		
+		et = em.getTransaction();
+		et.begin();
+
+		// Make sure we start with the DB clean
+		em.createQuery("DELETE FROM StateManagementEntity").executeUpdate();
+		em.createQuery("DELETE FROM ResourceRegistrationEntity").executeUpdate();
+		em.createQuery("DELETE FROM ForwardProgressEntity").executeUpdate();
+
+		em.flush();
+		et.commit();
+
+		IntegrityMonitor.deleteInstance();
+		
+		IntegrityMonitor im = IntegrityMonitor.getInstance(resourceName, myProp);
+		
+		// Add a group1 dependent resources to put an entry in the forward progress table
+		// This sets lastUpdated to the current time
+		ForwardProgressEntity fpe = new ForwardProgressEntity();
+		fpe.setFpcCount(0);
+		fpe.setResourceName("group1_dep1");
+		et = em.getTransaction();
+		et.begin();
+		em.persist(fpe);
+		em.flush();
+		et.commit();
+
+		//Now add new group1 stateManager instances
+		StateManagement sm2 = new StateManagement(emf, "group1_dep1");
+		
+		boolean sanityPass = true;
+		//Thread.sleep(15000);
+		Thread.sleep(5000);
+		try {
+			im.evaluateSanity();
+		} catch (Exception e) {
+			System.out.println("testStateCheck: After 15 sec sleep - evaluateSanity exception: " + e);
+			sanityPass = false;
+		}
+		assertTrue(sanityPass);  // expect sanity test to pass
+		
+		//now wait 30 seconds.  The dependency entry should now be stale and the sanitry check should fail
+		
+		sanityPass = true;
+		//Thread.sleep(30000);
+		Thread.sleep(10000);
+		try {
+			im.evaluateSanity();
+		} catch (Exception e) {
+			System.out.println("testStateCheck: After 10 sec sleep - evaluateSanity exception: " + e);
+			sanityPass = false;
+		}
+		assertFalse(sanityPass);  // expect sanity test to fail
+		
+		// undo dependency groups, jmx test properties settings and failed counter threshold
+		myProp.put(IntegrityMonitorProperties.DEPENDENCY_GROUPS, "");
+		myProp.put(IntegrityMonitorProperties.TEST_VIA_JMX, "false");
+		myProp.put(IntegrityMonitorProperties.FAILED_COUNTER_THRESHOLD, Integer.toString(IntegrityMonitorProperties.DEFAULT_FAILED_COUNTER_THRESHOLD));
+		myProp.put(IntegrityMonitorProperties.FP_MONITOR_INTERVAL, Integer.toString(IntegrityMonitorProperties.DEFAULT_MONITOR_INTERVAL));
+		IntegrityMonitor.updateProperties(myProp);
+
+		et = em.getTransaction();
+		
+		et.begin();
+		// Make sure we leave the DB clean
+		em.createQuery("DELETE FROM StateManagementEntity").executeUpdate();
+		em.createQuery("DELETE FROM ResourceRegistrationEntity").executeUpdate();
+		em.createQuery("DELETE FROM ForwardProgressEntity").executeUpdate();
+
+		em.flush();
+		et.commit();
+		
+		System.out.println("\n\ntestStateCheck: Exit\n\n");
+	}
+	
 }
diff --git a/integrity-monitor/src/test/java/org/openecomp/policy/common/im/test/StateManagementTest.java b/integrity-monitor/src/test/java/org/openecomp/policy/common/im/test/StateManagementTest.java
index 3247d78..f51f5ac 100644
--- a/integrity-monitor/src/test/java/org/openecomp/policy/common/im/test/StateManagementTest.java
+++ b/integrity-monitor/src/test/java/org/openecomp/policy/common/im/test/StateManagementTest.java
@@ -41,6 +41,7 @@
 
 
 
+
 import org.junit.After;
 import org.junit.AfterClass;
 import org.junit.Before;
@@ -49,7 +50,6 @@
 import org.junit.Test;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
-
 import org.openecomp.policy.common.im.StateManagement;
 import org.openecomp.policy.common.im.StateTransition;
 import org.openecomp.policy.common.im.StandbyStatusException; 
@@ -57,6 +57,11 @@
 import org.openecomp.policy.common.logging.flexlogger.FlexLogger; 
 import org.openecomp.policy.common.logging.flexlogger.Logger;
 
+/*
+ * All JUnits are designed to run in the local development environment
+ * where they have write privileges and can execute time-sensitive
+ * tasks.
+ */
 public class StateManagementTest {
 	private static Logger logger = FlexLogger.getLogger(StateManagementTest.class);
 	
diff --git a/integrity-monitor/src/test/java/org/openecomp/policy/common/im/test/StateTransitionTest.java b/integrity-monitor/src/test/java/org/openecomp/policy/common/im/test/StateTransitionTest.java
index b0e6e18..d76cad0 100644
--- a/integrity-monitor/src/test/java/org/openecomp/policy/common/im/test/StateTransitionTest.java
+++ b/integrity-monitor/src/test/java/org/openecomp/policy/common/im/test/StateTransitionTest.java
@@ -50,7 +50,11 @@
 import org.openecomp.policy.common.im.StateChangeNotifier; 
 import org.openecomp.policy.common.logging.flexlogger.FlexLogger; 
 import org.openecomp.policy.common.logging.flexlogger.Logger;
-
+/*
+ * All JUnits are designed to run in the local development environment
+ * where they have write privileges and can execute time-sensitive
+ * tasks.
+ */
 public class StateTransitionTest {
 	private static Logger logger = FlexLogger.getLogger(StateTransitionTest.class);