Initial OpenECOMP policy/common commit 55/355/1
authorPamela Dragosh <pdragosh@research.att.com>
Wed, 15 Feb 2017 00:31:53 +0000 (19:31 -0500)
committerPamela Dragosh <pdragosh@research.att.com>
Wed, 15 Feb 2017 00:32:27 +0000 (19:32 -0500)
Change-Id: I61cd29d6d8bf8702c1a66915895b519bf3484afa
Signed-off-by: Pamela Dragosh <pdragosh@research.att.com>
96 files changed:
.gitattributes [new file with mode: 0644]
.gitignore [new file with mode: 0644]
.gitreview [new file with mode: 0644]
LICENSE.txt [new file with mode: 0644]
README.md [new file with mode: 0644]
common-logging/config/policyLogger.properties [new file with mode: 0644]
common-logging/policyLogger.properties [new file with mode: 0644]
common-logging/pom.xml [new file with mode: 0644]
common-logging/src/main/java/org/openecomp/policy/common/logging/ECOMPLoggingContext.java [new file with mode: 0644]
common-logging/src/main/java/org/openecomp/policy/common/logging/ECOMPLoggingUtils.java [new file with mode: 0644]
common-logging/src/main/java/org/openecomp/policy/common/logging/eelf/Configuration.java [new file with mode: 0644]
common-logging/src/main/java/org/openecomp/policy/common/logging/eelf/DroolsPDPMDCInfo.java [new file with mode: 0644]
common-logging/src/main/java/org/openecomp/policy/common/logging/eelf/ErrorCodeMap.java [new file with mode: 0644]
common-logging/src/main/java/org/openecomp/policy/common/logging/eelf/EventData.java [new file with mode: 0644]
common-logging/src/main/java/org/openecomp/policy/common/logging/eelf/EventTrackInfo.java [new file with mode: 0644]
common-logging/src/main/java/org/openecomp/policy/common/logging/eelf/EventTrackInfoHandler.java [new file with mode: 0644]
common-logging/src/main/java/org/openecomp/policy/common/logging/eelf/MDCInfo.java [new file with mode: 0644]
common-logging/src/main/java/org/openecomp/policy/common/logging/eelf/MessageCodes.java [new file with mode: 0644]
common-logging/src/main/java/org/openecomp/policy/common/logging/eelf/PolicyLogger.java [new file with mode: 0644]
common-logging/src/main/java/org/openecomp/policy/common/logging/flexlogger/EelfLogger.java [new file with mode: 0644]
common-logging/src/main/java/org/openecomp/policy/common/logging/flexlogger/FlexLogger.java [new file with mode: 0644]
common-logging/src/main/java/org/openecomp/policy/common/logging/flexlogger/FlexLoggerTester.java [new file with mode: 0644]
common-logging/src/main/java/org/openecomp/policy/common/logging/flexlogger/Logger.java [new file with mode: 0644]
common-logging/src/main/java/org/openecomp/policy/common/logging/flexlogger/Logger4J.java [new file with mode: 0644]
common-logging/src/main/java/org/openecomp/policy/common/logging/flexlogger/LoggerType.java [new file with mode: 0644]
common-logging/src/main/java/org/openecomp/policy/common/logging/flexlogger/PropertyUtil.java [new file with mode: 0644]
common-logging/src/main/java/org/openecomp/policy/common/logging/flexlogger/SystemOutLogger.java [new file with mode: 0644]
common-logging/src/main/java/org/openecomp/policy/common/logging/nsa/LoggingContext.java [new file with mode: 0644]
common-logging/src/main/java/org/openecomp/policy/common/logging/nsa/LoggingContextFactory.java [new file with mode: 0644]
common-logging/src/main/java/org/openecomp/policy/common/logging/nsa/SharedLoggingContext.java [new file with mode: 0644]
common-logging/src/main/java/org/openecomp/policy/common/logging/nsa/impl/SharedContext.java [new file with mode: 0644]
common-logging/src/main/java/org/openecomp/policy/common/logging/nsa/impl/Slf4jLoggingContext.java [new file with mode: 0644]
common-logging/src/main/java/org/openecomp/policy/common/logging/nsa/package-info.java [new file with mode: 0644]
common-logging/src/main/resources/org/openecomp/policy/common/logging/eelf/Resources.properties [new file with mode: 0644]
integrity-audit/config/policyLogger.properties [new file with mode: 0644]
integrity-audit/policyLogger.properties [new file with mode: 0644]
integrity-audit/pom.xml [new file with mode: 0644]
integrity-audit/src/main/java/org/openecomp/policy/common/ia/AuditThread.java [new file with mode: 0644]
integrity-audit/src/main/java/org/openecomp/policy/common/ia/DbAudit.java [new file with mode: 0644]
integrity-audit/src/main/java/org/openecomp/policy/common/ia/DbAuditException.java [new file with mode: 0644]
integrity-audit/src/main/java/org/openecomp/policy/common/ia/DbDAO.java [new file with mode: 0644]
integrity-audit/src/main/java/org/openecomp/policy/common/ia/DbDaoTransactionException.java [new file with mode: 0644]
integrity-audit/src/main/java/org/openecomp/policy/common/ia/IntegrityAudit.java [new file with mode: 0644]
integrity-audit/src/main/java/org/openecomp/policy/common/ia/IntegrityAuditProperties.java [new file with mode: 0644]
integrity-audit/src/main/java/org/openecomp/policy/common/ia/IntegrityAuditPropertiesException.java [new file with mode: 0644]
integrity-audit/src/main/java/org/openecomp/policy/common/ia/jpa/IntegrityAuditEntity.java [new file with mode: 0644]
integrity-audit/src/main/resources/META-INF/persistence.xml [new file with mode: 0644]
integrity-audit/src/main/resources/log4j.properties [new file with mode: 0644]
integrity-audit/src/main/resources/logback.xml [new file with mode: 0644]
integrity-audit/src/test/java/org/openecomp/policy/common/ia/test/AuditPeriodTest.java [new file with mode: 0644]
integrity-audit/src/test/java/org/openecomp/policy/common/ia/test/DbAuditCompareEntriesTest.java [new file with mode: 0644]
integrity-audit/src/test/java/org/openecomp/policy/common/ia/test/DbAuditTest.java [new file with mode: 0644]
integrity-audit/src/test/java/org/openecomp/policy/common/ia/test/DbDAOTest.java [new file with mode: 0644]
integrity-audit/src/test/java/org/openecomp/policy/common/ia/test/IntegrityAuditDesignationTest.java [new file with mode: 0644]
integrity-audit/src/test/java/org/openecomp/policy/common/ia/test/jpa/IaTestEntity.java [new file with mode: 0644]
integrity-audit/src/test/java/org/openecomp/policy/common/ia/test/jpa/PersonTest.java [new file with mode: 0644]
integrity-audit/src/test/resources/log4j.properties [new file with mode: 0644]
integrity-audit/src/test/resources/logback.xml [new file with mode: 0644]
integrity-audit/src/test/resources/policyLogger.properties [new file with mode: 0644]
integrity-monitor/policyLogger.properties [new file with mode: 0644]
integrity-monitor/pom.xml [new file with mode: 0644]
integrity-monitor/src/main/java/org/openecomp/policy/common/im/AdministrativeStateException.java [new file with mode: 0644]
integrity-monitor/src/main/java/org/openecomp/policy/common/im/ForwardProgressException.java [new file with mode: 0644]
integrity-monitor/src/main/java/org/openecomp/policy/common/im/IntegrityMonitor.java [new file with mode: 0644]
integrity-monitor/src/main/java/org/openecomp/policy/common/im/IntegrityMonitorProperties.java [new file with mode: 0644]
integrity-monitor/src/main/java/org/openecomp/policy/common/im/IntegrityMonitorPropertiesException.java [new file with mode: 0644]
integrity-monitor/src/main/java/org/openecomp/policy/common/im/StandbyStatusException.java [new file with mode: 0644]
integrity-monitor/src/main/java/org/openecomp/policy/common/im/StateChangeNotifier.java [new file with mode: 0644]
integrity-monitor/src/main/java/org/openecomp/policy/common/im/StateElement.java [new file with mode: 0644]
integrity-monitor/src/main/java/org/openecomp/policy/common/im/StateManagement.java [new file with mode: 0644]
integrity-monitor/src/main/java/org/openecomp/policy/common/im/StateTransition.java [new file with mode: 0644]
integrity-monitor/src/main/java/org/openecomp/policy/common/im/jmx/ComponentAdmin.java [new file with mode: 0644]
integrity-monitor/src/main/java/org/openecomp/policy/common/im/jmx/ComponentAdminMBean.java [new file with mode: 0644]
integrity-monitor/src/main/java/org/openecomp/policy/common/im/jmx/JmxAgentConnection.java [new file with mode: 0644]
integrity-monitor/src/main/java/org/openecomp/policy/common/im/jpa/ForwardProgressEntity.java [new file with mode: 0644]
integrity-monitor/src/main/java/org/openecomp/policy/common/im/jpa/ImTestEntity.java [new file with mode: 0644]
integrity-monitor/src/main/java/org/openecomp/policy/common/im/jpa/ResourceRegistrationEntity.java [new file with mode: 0644]
integrity-monitor/src/main/java/org/openecomp/policy/common/im/jpa/StateManagementEntity.java [new file with mode: 0644]
integrity-monitor/src/main/resources/META-INF/persistence.xml [new file with mode: 0644]
integrity-monitor/src/main/resources/log4j.properties [new file with mode: 0644]
integrity-monitor/src/main/resources/logback.xml [new file with mode: 0644]
integrity-monitor/src/test/java/org/openecomp/policy/common/im/test/IntegrityMonitorTest.java [new file with mode: 0644]
integrity-monitor/src/test/java/org/openecomp/policy/common/im/test/StateManagementEntityTest.java [new file with mode: 0644]
integrity-monitor/src/test/java/org/openecomp/policy/common/im/test/StateManagementTest.java [new file with mode: 0644]
integrity-monitor/src/test/java/org/openecomp/policy/common/im/test/StateTransitionTest.java [new file with mode: 0644]
integrity-monitor/src/test/resources/log4j.properties [new file with mode: 0644]
integrity-monitor/src/test/resources/logback.xml [new file with mode: 0644]
pom.xml [new file with mode: 0644]
project-configs/maven/conf/settings.xml [new file with mode: 0644]
site-manager/pom.xml [new file with mode: 0644]
site-manager/src/assembly/assemble_zip.xml [new file with mode: 0644]
site-manager/src/main/files/README [new file with mode: 0644]
site-manager/src/main/files/siteManager [new file with mode: 0644]
site-manager/src/main/files/siteManager.properties [new file with mode: 0644]
site-manager/src/main/java/org/openecomp/policy/common/sitemanager/Main.java [new file with mode: 0644]
version.properties [new file with mode: 0644]

diff --git a/.gitattributes b/.gitattributes
new file mode 100644 (file)
index 0000000..a6c1a2a
--- /dev/null
@@ -0,0 +1,37 @@
+# Handle line endings automatically for files detected as text
+# and leave all files detected as binary untouched.
+* text=auto
+
+#
+# The above will handle all files NOT found below
+#
+# These files are text and should be normalized (Convert crlf => lf)
+*.css           text
+*.df            text
+*.htm           text
+*.html          text
+*.java          text
+*.js            text
+*.json          text
+*.jsp           text
+*.jspf          text
+*.properties    text
+*.sh            text
+*.svg           text
+*.tld           text
+*.txt           text
+*.xml           text
+
+# These files are binary and should be left untouched
+# (binary is a macro for -text -diff)
+*.class         binary
+*.dll           binary
+*.ear           binary
+*.gif           binary
+*.ico           binary
+*.jar           binary
+*.jpg           binary
+*.jpeg          binary
+*.png           binary
+*.so            binary
+*.war           binary
diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..5480485
--- /dev/null
@@ -0,0 +1,31 @@
+.project
+.settings
+.classpath
+.jupiter
+.pydevproject
+target
+.metadata/
+integrity-audit/sql/generatedCreateIA.ddl
+integrity-audit/sql/generatedDropIA.ddl
+integrity-audit/sql/iaTest.mv.db
+integrity-audit/sql/iaTest.trace.db
+integrity-audit/sql/iaTest2.mv.db
+integrity-audit/sql/iaTest2.trace.db
+integrity-audit/testingLogs/common-modules/integrity-audit/audit.log
+integrity-audit/testingLogs/common-modules/integrity-audit/debug.log
+integrity-audit/testingLogs/common-modules/integrity-audit/error.log
+integrity-audit/testingLogs/common-modules/integrity-audit/metrics.log
+integrity-monitor/IntegrityMonitor.log.2016-09-02
+integrity-monitor/IntegrityMonitor.log.2016-09-06
+integrity-monitor/IntegrityMonitor.log.2016-09-15
+integrity-monitor/IntegrityMonitor.log.2016-09-19
+integrity-monitor/IntegrityMonitor.log.2016-09-20
+integrity-monitor/IntegrityMonitor.log.2016-09-26
+integrity-monitor/IntegrityMonitor.log.2016-09-30
+integrity-monitor/IntegrityMonitor.log.2016-10-01
+integrity-monitor/IntegrityMonitor.log.2016-10-03
+integrity-monitor/IntegrityMonitor.log.2016-10-07
+integrity-monitor/IntegrityMonitor.log.2016-10-11
+integrity-monitor/IntegrityMonitor.log.2016-10-12
+integrity-monitor/IntegrityMonitor.log.2016-10-18
+*.log
diff --git a/.gitreview b/.gitreview
new file mode 100644 (file)
index 0000000..9b55188
--- /dev/null
@@ -0,0 +1,4 @@
+[gerrit]
+host=gerrit.openecomp.org
+port=29418
+project=policy/common.git
diff --git a/LICENSE.txt b/LICENSE.txt
new file mode 100644 (file)
index 0000000..e8c89ea
--- /dev/null
@@ -0,0 +1,16 @@
+Copyright ï¿½ 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.
+
+ECOMP and OpenECOMP are trademarks and service marks of AT&T Intellectual Property.
diff --git a/README.md b/README.md
new file mode 100644 (file)
index 0000000..d356e24
--- /dev/null
+++ b/README.md
@@ -0,0 +1,3 @@
+This source repository contains OpenECOMP common code, which is shared by 'policy-drools-pdp' and 'policy-engine'. The settings file only needs to support the standard Maven repositories (e.g. central = http://repo1.maven.org/maven2/), and any proxy settings needed in your environment.
+
+To build it using Maven 3, run: mvn clean install
diff --git a/common-logging/config/policyLogger.properties b/common-logging/config/policyLogger.properties
new file mode 100644 (file)
index 0000000..6aaa6a9
--- /dev/null
@@ -0,0 +1,44 @@
+###
+# ============LICENSE_START=======================================================
+# ECOMP-Logging
+# ================================================================================
+# 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/common-logging/policyLogger.properties b/common-logging/policyLogger.properties
new file mode 100644 (file)
index 0000000..7f160b6
--- /dev/null
@@ -0,0 +1,50 @@
+###
+# ============LICENSE_START=======================================================
+# ECOMP-Logging
+# ================================================================================
+# 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 override flag. Set TRUE for override the level setups in logback.xml. Set FALSE for using the level setups of logback.xml
+override.logback.level.setup=FALSE
+#Only use these setups below if override.logback.level.setup=TRUE
+# 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
+#################################### Set Policy Component ##################################
+# Set DROOLS for drools PDP. Set XACML to xacml PDP
+policy.component=DROOLS
diff --git a/common-logging/pom.xml b/common-logging/pom.xml
new file mode 100644 (file)
index 0000000..c674ffa
--- /dev/null
@@ -0,0 +1,120 @@
+<!--
+  ============LICENSE_START=======================================================
+  ECOMP Policy Engine - Common Modules
+  ================================================================================
+  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=========================================================
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+       <parent>
+               <groupId>org.openecomp.policy.common</groupId>
+               <artifactId>common-modules</artifactId>
+               <version>1.0.0-SNAPSHOT</version>
+       </parent>
+  <groupId>org.openecomp.policy.common</groupId>
+  <artifactId>ECOMP-Logging</artifactId>
+  <description>ECOMP Logging Framework</description>
+  <packaging>jar</packaging>
+
+  <dependencies>
+    <dependency>
+      <groupId>javax.servlet</groupId>
+      <artifactId>javax.servlet-api</artifactId>
+      <version>3.0.1</version>
+      <scope>compile</scope>
+    </dependency>
+       <dependency>
+               <groupId>org.slf4j</groupId>
+               <artifactId>slf4j-api</artifactId>
+               <version>1.7.12</version>
+       </dependency>
+       <dependency>
+           <groupId>com.att.eelf</groupId>
+               <artifactId>eelf-core</artifactId>
+               <version>0.0.1</version>
+       </dependency>
+       <dependency>
+               <groupId>log4j</groupId>
+               <artifactId>log4j</artifactId>
+               <version>1.2.17</version>
+               <scope>provided</scope>
+       </dependency>
+  </dependencies>
+  
+  <repositories>
+          <repository>   
+            <id>eelf-framework</id>
+                       <url>http://search.maven.org/#search|ga|1|EELF</url> 
+                       <name>EELF repository</name>
+          </repository>
+  </repositories>
+  
+  <pluginRepositories>
+                       <pluginRepository>
+                               <releases />
+                               <snapshots />
+                               <id>eelf-framework</id>
+                               <url>http://search.maven.org/#search|ga|1|EELF</url> 
+                       </pluginRepository>
+  </pluginRepositories>
+
+
+       <build>
+               <plugins>
+                       <plugin>
+                               <groupId>com.att.eelf</groupId>
+                               <artifactId>eelf-maven-plugin</artifactId>
+                               <version>0.0.1</version>
+                               <executions>
+                                       <execution>
+                                               <phase>install</phase>
+                                               <goals>
+                                                       <goal>WikiMsgGenerator</goal>
+                                               </goals>
+                                       </execution>
+                               </executions>
+                               <dependencies>
+                                       <!-- We need to include the dependency of the project so that its include 
+                                               in classpath when running plugin -->
+                                       <dependency>
+                                               <groupId>org.openecomp.policy.common</groupId>
+                                               <artifactId>ECOMP-Logging</artifactId>
+                                               <version>1.0.0-SNAPSHOT</version>
+                                       </dependency>
+                               </dependencies>
+                               <configuration>
+                                       <outputDirectory>target/messages</outputDirectory>
+                                       <outputFile>messages.html</outputFile>
+                                       <resources>
+                                               <resource>
+                                                       <messageClass>org.openecomp.policy.common.logging.eelf.MessageCodes</messageClass>
+                                                       This needs to be replaced with your Enum class name .which
+                                                       implements EELFResolvableErrorEnum and have your defined error
+                                                       codes.
+                                                       <header><![CDATA[<p>   <ac:macro ac:name="toc" /> </p>
+                <p>
+        <ac:macro ac:name="anchor"> <ac:default-parameter>Application Messages</ac:default-parameter>  </ac:macro> </p> <h2>Application Messages</h2>]]></header>
+                                               </resource>
+
+                                       </resources>
+                               </configuration>
+                       </plugin>
+               </plugins>
+       </build>
+</project>
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
new file mode 100644 (file)
index 0000000..71e75a1
--- /dev/null
@@ -0,0 +1,530 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP-Logging
+ * ================================================================================
+ * 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.logging;
+
+//import static org.openecomp.policy.common.logging.eelf.Configuration.TRANSACTION_BEGIN_TIME_STAMP;
+//import static org.openecomp.policy.common.logging.eelf.Configuration.TRANSACTION_ELAPSED_TIME;
+//import static org.openecomp.policy.common.logging.eelf.Configuration.TRANSACTION_END_TIME_STAMP;
+
+import static com.att.eelf.configuration.Configuration.MDC_ALERT_SEVERITY;
+import static com.att.eelf.configuration.Configuration.MDC_INSTANCE_UUID;
+
+import java.text.SimpleDateFormat;
+import java.time.Duration;
+import java.time.Instant;
+import java.time.ZoneOffset;
+import java.util.Date;
+import java.util.Properties;
+import java.util.Timer;
+import java.util.TimerTask;
+
+import org.slf4j.MDC;
+
+import org.openecomp.policy.common.logging.nsa.LoggingContextFactory;
+import org.openecomp.policy.common.logging.nsa.SharedLoggingContext;
+
+/**
+ * A facade over the org.openecomp.policy.common.logging.nsa.SharedLoggingContext interface/implementation that makes it
+ * more convenient to use. SharedLoggingContext builds on the SLF4J/log4j Mapped Diagnostic Context (MDC)
+ * feature, which provides a hashmap-based context for data items that need to be logged, where the
+ * hashmap is kept in ThreadLocal storage. The data items can be referenced in the log4j configuration
+ * using the EnhancedPatternLayout appender layout class, and the notation "%X{key}" in the ConversionPattern
+ * string, where "key" is one of the keys in the MDC hashmap (which is determined by what hashmap entries the
+ * application code creates). Example:
+ *   log4j.appender.auditAppender.layout=org.apache.log4j.EnhancedPatternLayout
+ *   log4j.appender.auditAppender.layout.ConversionPattern=%d|%X{requestId}|%X{serviceInstanceId}|...|%m%n
+ * where "requestId" and "serviceInstanceId" are entries in the MDC hashmap.
+ * 
+ * The notable functionality the SharedLoggingContext adds over MDC is that it maintains its own copy
+ * of the MDC data items in a hashmap (not in ThreadLocal storage), which allows more control of the data.
+ * The ECOMPLoggingContext constructor that takes another ECOMPLoggingContext object as a parameter makes
+ * use of this feature. For example if there is a thread pulling requests from a queue for processing, it
+ * can keep a base logging context with data that is common to all requests, and for each request, create a
+ * new logging context with that base context as a parameter; this will create a new logging context with
+ * those initial values and none of the request-specific values from the previous request such as a request ID.
+ * The setter methods in this class set corresponding items in the SharedLoggingContext/MDC hashmaps.
+ * These items correspond to the fields defined in the "ECOMP platform application logging guidelines"
+ * document.  In addition, there is a pair of convenience functions, transactionStarted() and
+ * transactionEnded(), that can be called at the beginning and end of transaction processing to calculate
+ * the duration of the transaction and record that value in the "timer" item.
+ * 
+ */
+public class ECOMPLoggingContext {
+
+       private static final String REQUEST_ID = "requestId";
+       private static final String SERVICE_INSTANCE_ID = "serviceInstanceId";
+       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 INSTANCE_UUID = "instanceUuid";
+       private static final String SEVERITY = "severity";
+       private static final String SERVER_IP_ADDRESS = "serverIpAddress";
+       private static final String SERVER = "server";
+       private static final String CLIENT_IP_ADDRESS = "clientIpAddress";
+       private static final String CLASSNAME = "classname";
+       private static final String TRANSACTION_BEGIN_TIME_STAMP = "TransactionBeginTimestamp";
+       private static final String TRANSACTION_END_TIME_STAMP = "TransactionEndTimestamp";
+       private static final String TRANSACTION_ELAPSED_TIME = "TransactionElapsedTime";
+       private static final String METRIC_BEGIN_TIME_STAMP = "MetricBeginTimestamp";
+       private static final String METRIC_END_TIME_STAMP = "MetricEndTimestamp";
+       private static final String METRIC_ELAPSED_TIME = "MetricElapsedTime";
+       
+
+    private static LoggingContextFactory.Builder loggingContextBuilder = new LoggingContextFactory.Builder();
+
+    protected SharedLoggingContext context = null;
+//    private long transactionStartTime = 0;
+    private Instant transactionStartTime;
+    private Instant metricStartTime;
+    
+    /**
+     * Create a new ECOMPLoggingContext with no base context.
+     */
+       public ECOMPLoggingContext() {
+               context = (SharedLoggingContext) loggingContextBuilder.forSharing().build();
+       }
+
+       /**
+        * Create a new ECOMPLoggingContext initially populated with the values
+        * in the given base context.  This can be used for example in a servlet
+        * where each incoming request may be processed by a separate thread, but
+        * there may be some logging data items that will be unchanging and common
+        * to all the threads.  That constant data can be populated in a base
+        * context, and then each request handler creates new context passing that
+        * base context to populate the common data in the new one.
+        * @param baseContext
+        */
+       public ECOMPLoggingContext(ECOMPLoggingContext baseContext) {
+               context = (SharedLoggingContext) loggingContextBuilder.forSharing().build();
+               // a logging context could be passed into a thread (e.g. one that is servicing a queue)
+               // that already had a logging context established, so the MDC hashmap could contain
+               // entries that are no longer appropriate; so clear out the MDC hashmap before
+               // transferring the new logging context values.
+               // x
+               MDC.clear();
+               baseContext.context.transferTo(context);
+               transactionStartTime = baseContext.transactionStartTime;
+       }
+       
+       /**
+        * Indicate the start of transaction processing.  The current system time
+        * will be recorded for use by <code>transactionEnded()</code> to calculate
+        * the duration of the transaction.
+        */
+       public void transactionStarted() {
+//             transactionStartTime = System.currentTimeMillis();
+               transactionStartTime = Instant.now();
+               setTransactionBeginTimestamp(transactionStartTime);
+       }
+       
+       /**
+        * Indicate the end of transaction processing.  The difference between the
+        * current system time and the time recorded by <code>transactionStarted()</code>
+        * will be recorded in the data item with key "TransactionElapsedTime".
+        */
+       public void transactionEnded() {
+               Instant transactionEndTime = Instant.now();
+               setTransactionEndTimestamp(transactionEndTime);
+               setTransactionElapsedTime(transactionEndTime);
+       }
+       
+       /**
+        * Indicate the start of metric processing.  The current system time
+        * will be recorded for use by <code>metricEnded()</code> to calculate
+        * the duration of the metric.
+        */
+       public void metricStarted() {
+//             transactionStartTime = System.currentTimeMillis();
+               metricStartTime = Instant.now();
+               setMetricBeginTimestamp(metricStartTime);
+       }
+       
+       /**
+        * Indicate the end of metric processing.  The difference between the
+        * current system time and the time recorded by <code>metricStarted()</code>
+        * will be recorded in the data item with key "MetricElapsedTime".
+        */
+       public void metricEnded() {
+               Instant metricEndTime = Instant.now();
+               setMetricEndTimestamp(metricEndTime);
+               setMetricElapsedTime(metricEndTime);
+       }
+
+       
+       /**
+        * Set the value for the data item with key "requestId"
+        * 
+        * @param id
+        */
+       public void setRequestID(String id) {
+               context.put(REQUEST_ID, id);
+       }
+       /**
+        * Get the value for the data item with key "requestId"
+        * @return current value, or empty string if not set
+        */
+       public String getRequestID() {
+               return context.get(REQUEST_ID, "");
+       }
+       
+       /**
+        * Set the value for the data item with key "serviceInstanceId"
+        * 
+        * @param id
+        */
+       public void setServiceInstanceID(String id) {
+               context.put(SERVICE_INSTANCE_ID, id);
+       }
+       /**
+        * Get the value for the data item with key "serviceInstanceId"
+        * @return current value, or empty string if not set
+        */
+       public String getServiceInstanceID() {
+               return context.get(SERVICE_INSTANCE_ID, "");
+       }
+
+       /**
+        * Set the value for the data item with key "threadId".
+        * An alternative to using this item is to use the
+        * %t conversion character in the appender's conversion string.
+        * 
+        * @param id
+        */
+       public void setThreadID(String id) {
+               context.put(THREAD_ID, id);
+       }
+       /**
+        * Get the value for the data item with key "threadId"
+        * @return current value, or empty string if not set
+        */
+       public String getThreadID() {
+               return context.get(THREAD_ID, "");
+       }
+       
+       /**
+        * Set the value for the data item with key "serverName"
+        * 
+        * @param id
+        */
+       public void setServerName(String name) {
+               context.put(SERVER_NAME, name);
+       }
+       /**
+        * Get the value for the data item with key "serverName"
+        * @return current value, or empty string if not set
+        */
+       public String getServerName() {
+               return context.get(SERVER_NAME, "");
+       }
+       
+       /**
+        * Set the value for the data item with key "serviceName"
+        * 
+        * @param id
+        */
+       public void setServiceName(String name) {
+               context.put(SERVICE_NAME, name);
+       }
+       /**
+        * Get the value for the data item with key "serviceName"
+        * @return current value, or empty string if not set
+        */
+       public String getServiceName() {
+               return context.get(SERVICE_NAME, "");
+       }
+       
+       /**
+        * Set the value for the data item with key "instanceUuid"
+        * 
+        * @param id
+        */
+       public void setInstanceUUID(String uuid) {
+               context.put(INSTANCE_UUID, uuid);
+       }
+       /**
+        * Get the value for the data item with key "instanceUuid"
+        * @return current value, or empty string if not set
+        */
+       public String getInstanceUUID() {
+               return context.get(INSTANCE_UUID, "");
+       }
+       
+       /**
+        * Set the value for the data item with key "severity"
+        * 
+        * @param id
+        */
+       public void setSeverity(Long severity) {
+               context.put(SEVERITY, severity);
+       }
+       /**
+        * Get the value for the data item with key "severity"
+        * @return current value, or empty string if not set
+        */
+       public String getSeverity() {
+               return context.get(SEVERITY, "");
+       }
+       
+       /**
+        * Set the value for the data item with key "serverIp"
+        * 
+        * @param id
+        */
+       public void setServerIPAddress(String serverIP) {
+               context.put(SERVER_IP_ADDRESS, serverIP);
+       }
+       /**
+        * Get the value for the data item with key "serverIp"
+        * @return current value, or empty string if not set
+        */
+       public String getServerIPAddress() {
+               return context.get(SERVER_IP_ADDRESS, "");
+       }
+       
+       /**
+        * Set the value for the data item with key "server"
+        * 
+        * @param id
+        */
+       public void setServer(String server) {
+               context.put(SERVER, server);
+       }
+       /**
+        * Get the value for the data item with key "server"
+        * @return current value, or empty string if not set
+        */
+       public String getServer() {
+               return context.get(SERVER, "");
+       }
+       
+       /**
+        * Set the value for the data item with key "clientIp"
+        * 
+        * @param id
+        */
+       public void setClientIPAddress(String clientIP) {
+               context.put(CLIENT_IP_ADDRESS, clientIP);
+       }
+       /**
+        * Get the value for the data item with key "clientIp"
+        * @return current value, or empty string if not set
+        */
+       public String getClientIPAddress() {
+               return context.get(CLIENT_IP_ADDRESS, "");
+       }
+       
+       /**
+        * Set the value for the data item with key "classname".
+        * Use of this item is not recommended (unless it is used to
+        * indicate something other than the Java classname) since
+        * it would be unwieldy to maintain a correct value across
+        * calls to/returns from methods in other classes.
+        * Use of the PatternLayout %c conversion character in the
+        * conversion string will give a more reliable value.
+        * 
+        * @param id
+        */
+       public void setClassname(String classname) {
+               context.put(CLASSNAME, classname);
+       }
+       /**
+        * Get the value for the data item with key "classname"
+        * @return current value, or empty string if not set
+        */
+       public String getClassname() {
+               return context.get(CLASSNAME, "");
+       }
+
+       /**
+        * Set the value for the data item with key "timer".
+        * An alternative to calling this method directly is to call
+        * <code>transactionStarted()</code> at the start of transaction
+        * processing and <code>transactionEnded()</code> at the end,
+        * which will compute the time difference in milliseconds
+        * and store the result as the "timer" value.
+        * 
+        * @param id
+        */
+//     public void setTimer(Long timer) {
+//             context.put(TIMER, timer);
+//     }
+       
+//     public void setTimer(Long elapsedtime) {
+//             String unit = " milliseconds";
+//             context.put(TRANSACTION_ELAPSED_TIME, elapsedtime + unit);
+//     }
+
+       /**
+        * Get the value for the data item with key "timer"
+        * @return current value, or 0 if not set
+        */
+//     public long getTimer() {
+//             return context.get(TRANSACTION_ELAPSED_TIME, 0);
+//     }
+       
+       /**
+        * Set the value for the data item with key "TransactionBeginTimestamp"
+        * 
+        * @param id
+        */
+       public void setTransactionBeginTimestamp(Instant transactionStartTime) {
+               SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS+00:00");
+               
+               String formatedTime = sdf.format(Date.from(transactionStartTime));
+               context.put(TRANSACTION_BEGIN_TIME_STAMP, formatedTime );
+       }
+       
+       /**
+        * Get the value for the data item with key "TransactionBeginTimestamp"
+        * @return current value, or 0 if not set
+        */
+       public long getTransactionBeginTimestamp() {
+               return context.get(TRANSACTION_BEGIN_TIME_STAMP, 0);
+       }
+       
+       /**
+        * Set the value for the data item with key "TransactionEndTimestamp"
+        * 
+        * @param id
+        */
+       public void setTransactionEndTimestamp(Instant transactionEndTime) {
+               SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS+00:00");
+               
+               String formatedTime = sdf.format(Date.from(transactionEndTime));
+               context.put(TRANSACTION_END_TIME_STAMP, formatedTime );
+       }
+       
+       /**
+        * Get the value for the data item with key "TransactionEndTimestamp"
+        * @return current value, or 0 if not set
+        */
+       public long getTransactionEndTimestamp() {
+               return context.get(TRANSACTION_END_TIME_STAMP, 0);
+       }
+       
+       /**
+        * Set the value for the data item with key "TransactionElapsedTime".
+        * An alternative to calling this method directly is to call
+        * <code>transactionStarted()</code> at the start of transaction
+        * processing and <code>transactionEnded()</code> at the end,
+        * which will compute the time difference in milliseconds
+        * and store the result as the "ns" value.
+        * 
+        * @param id
+        */
+       
+       public void setTransactionElapsedTime(Instant transactionEndTime) {
+               long ns = Duration.between(transactionStartTime, transactionEndTime).getSeconds();
+               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);
+       }
+
+       /**
+        * Get the value for the data item with key "TransactionElapsedTime"
+        * @return current value, or 0 if not set
+        */
+       public long getTransactionElapsedTime() {
+               return context.get(TRANSACTION_ELAPSED_TIME, 0);
+       }
+       
+       /**
+        * Set the value for the data item with key "MetricBeginTimestamp"
+        * 
+        * @param id
+        */
+       public void setMetricBeginTimestamp(Instant metricStartTime) {
+               SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS+00:00");
+               
+               String formatedTime = sdf.format(Date.from(metricStartTime));
+               context.put(METRIC_BEGIN_TIME_STAMP, formatedTime );
+       }
+       
+       /**
+        * Get the value for the data item with key "MetricBeginTimestamp"
+        * @return current value, or 0 if not set
+        */
+       public long getMetricBeginTimestamp() {
+               return context.get(METRIC_BEGIN_TIME_STAMP, 0);
+       }
+       
+       /**
+        * Set the value for the data item with key "MetricEndTimestamp"
+        * 
+        * @param id
+        */
+       public void setMetricEndTimestamp(Instant metricEndTime) {
+               SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS+00:00");
+               
+               String formatedTime = sdf.format(Date.from(metricEndTime));
+               context.put(METRIC_END_TIME_STAMP, formatedTime );
+       }
+       
+       /**
+        * Get the value for the data item with key "MetricEndTimestamp"
+        * @return current value, or 0 if not set
+        */
+       public long getMetricEndTimestamp() {
+               return context.get(METRIC_END_TIME_STAMP, 0);
+       }
+       
+       /**
+        * Set the value for the data item with key "MetricElapsedTime".
+        * An alternative to calling this method directly is to call
+        * <code>metricStarted()</code> at the start of metric
+        * processing and <code>metricEnded()</code> at the end,
+        * which will compute the time difference in milliseconds
+        * and store the result as the "ns" value.
+        * 
+        * @param id
+        */
+       
+       public void setMetricElapsedTime(Instant metricEndTime) {
+               long ns = Duration.between(metricStartTime, metricEndTime).getSeconds();
+               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);
+       }
+
+       /**
+        * Get the value for the data item with key "MetricElapsedTime"
+        * @return current value, or 0 if not set
+        */
+       public long getMetricElapsedTime() {
+               return context.get(METRIC_ELAPSED_TIME, 0);
+       }
+
+}
diff --git a/common-logging/src/main/java/org/openecomp/policy/common/logging/ECOMPLoggingUtils.java b/common-logging/src/main/java/org/openecomp/policy/common/logging/ECOMPLoggingUtils.java
new file mode 100644 (file)
index 0000000..5e6aa90
--- /dev/null
@@ -0,0 +1,52 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP-Logging
+ * ================================================================================
+ * 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.logging;
+
+import javax.servlet.http.HttpServletRequest;
+
+public class ECOMPLoggingUtils {
+
+       public static ECOMPLoggingContext getLoggingContextForRequest(HttpServletRequest request,
+                       ECOMPLoggingContext baseContext)
+       {
+               ECOMPLoggingContext requestContext = new ECOMPLoggingContext(baseContext);
+               if (request.getLocalAddr() != null) { // may be null in junit tests
+                       requestContext.setServerIPAddress(request.getLocalAddr());
+               }
+               // get client IP address as leftmost address in X-Forwarded-For header if present,
+               // otherwise from remote address in the request
+               String forwarded = request.getHeader("X-Forwarded-For");
+               if (forwarded != null && forwarded.trim().length() > 0) {
+                       forwarded = forwarded.trim().split(",")[0];
+                       requestContext.setClientIPAddress(forwarded);
+               } else if (request.getRemoteAddr() != null) { // may be null in junit tests
+                       requestContext.setClientIPAddress(request.getRemoteAddr());
+               }
+               // RequestID 
+               String requestId = request.getHeader("X-ECOMP-RequestID");
+               if (requestId != null && requestId.trim().length() > 0) {
+                       requestContext.setRequestID(requestId);
+               }
+               return requestContext;
+       }
+
+
+}
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
new file mode 100644 (file)
index 0000000..a2a0b78
--- /dev/null
@@ -0,0 +1,91 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP-Logging
+ * ================================================================================
+ * 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.logging.eelf;
+
+
+public interface Configuration  extends com.att.eelf.configuration.Configuration{
+       
+        /**
+         * The Date-time of the start of a transaction
+         */
+        public String BEGIN_TIME_STAMP = "BeginTimestamp";
+        
+        /**
+         * The Date-time of the end of transaction
+         */
+        public String END_TIME_STAMP = "EndTimestamp";
+
+        /**
+         * Externally advertised API invoked by clients of this component
+         */
+       public String SERVICE_NAME = "ServiceName";
+       
+        /**
+         * Client or user invoking the API
+         */
+       public String PARTNER_NAME = "PartnerName";
+       
+        /**
+         * High level success or failure (COMPLETE or ERROR)
+         */
+       public String STATUS_CODE = "StatusCode";
+       
+        /**
+         * Application specific response code
+         */
+       public String RESPONSE_CODE = "ResponseCode";
+       
+        /**
+         * Human readable description of the application specific response code
+         */
+       public String RESPONSE_DESCRIPTION = "ResponseDescription";
+       
+        /**
+         * Externally advertised API invoked by clients of this component
+         */
+       public String ELAPSED_TIME = "ElapsedTime";
+       
+        /**
+         * High level failure (ERROR)
+         */
+       public String ERROR_CATEGORY = "ErrorCategory";
+       
+        /**
+         * Error Code
+         */
+       public String ERROR_CODE = "ErrorCode"; 
+       
+        /**
+         * Error Description
+         */
+       public String ERROR_DESCRIPTION = "ErrorDesciption";    
+       
+        /**
+         * Class name
+         */
+       public String CLASS_NAME = "ClassName";         
+       
+        /**
+         * Server name
+         */
+       public String SERVER_NAME = "ServerName";
+       
+}
diff --git a/common-logging/src/main/java/org/openecomp/policy/common/logging/eelf/DroolsPDPMDCInfo.java b/common-logging/src/main/java/org/openecomp/policy/common/logging/eelf/DroolsPDPMDCInfo.java
new file mode 100644 (file)
index 0000000..ad50247
--- /dev/null
@@ -0,0 +1,53 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP-Logging
+ * ================================================================================
+ * 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.logging.eelf;
+
+import java.util.concurrent.ConcurrentHashMap;
+
+public class DroolsPDPMDCInfo implements MDCInfo{
+
+    private static ConcurrentHashMap<String, String> mdcMap = new ConcurrentHashMap<String, String>();
+
+    static {
+       
+       mdcMap.put(org.openecomp.policy.common.logging.eelf.Configuration.MDC_REMOTE_HOST, "");
+       mdcMap.put(org.openecomp.policy.common.logging.eelf.Configuration.MDC_SERVICE_NAME, "Policy.droolsPdp");
+       mdcMap.put(org.openecomp.policy.common.logging.eelf.Configuration.MDC_SERVICE_INSTANCE_ID, "Policy.droolsPdp.event");
+       mdcMap.put(org.openecomp.policy.common.logging.eelf.Configuration.MDC_INSTANCE_UUID, "");
+       mdcMap.put(org.openecomp.policy.common.logging.eelf.Configuration.MDC_ALERT_SEVERITY, "");
+       mdcMap.put(org.openecomp.policy.common.logging.eelf.Configuration.PARTNER_NAME, "N/A");         
+       mdcMap.put(org.openecomp.policy.common.logging.eelf.Configuration.STATUS_CODE, "N/A");
+       mdcMap.put(org.openecomp.policy.common.logging.eelf.Configuration.RESPONSE_CODE, "N/A");
+       mdcMap.put(org.openecomp.policy.common.logging.eelf.Configuration.RESPONSE_DESCRIPTION, "N/A");
+       
+    }
+
+       @Override
+       /**
+        * @return the instance of ConcurrentHashMap
+        */
+       public ConcurrentHashMap<String, String> getMDCInfo() {
+
+               return mdcMap;
+       }
+       
+       
+}
diff --git a/common-logging/src/main/java/org/openecomp/policy/common/logging/eelf/ErrorCodeMap.java b/common-logging/src/main/java/org/openecomp/policy/common/logging/eelf/ErrorCodeMap.java
new file mode 100644 (file)
index 0000000..4e4457d
--- /dev/null
@@ -0,0 +1,112 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP-Logging
+ * ================================================================================
+ * 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.logging.eelf;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 
+ * ErrorCodeMap contains a HashMap of ErrorCodeInfo (error code and error description) 
+ *
+ */
+public class ErrorCodeMap {
+       
+
+    public static HashMap<MessageCodes, ErrorCodeInfo> hm = new HashMap();
+    
+    private static String ERROR_PERMISSIONS = "POLICY-100E";
+       private static String ERROR_PERMISSIONS_DESCRIPTION = "This is a Permissions Error. Please check the error message for detail information";
+    
+       private static String ERROR_SCHEMA_INVALID = "POLICY-400E";
+       private static String ERROR_SCHEMA_INVALID_DESCRIPTION = "This is an Invalid Schema Error. Please check the error message for detail information";
+       
+    private static String UPDATE_ERROR = "POLICY-502E";
+       private static String UPDATE_ERROR_DESCRIPTION = "This is an updating error. Please check the error message for  detail information";
+       
+       private static String EXCEPTION_ERROR_CODE = "POLICY-503E";
+       private static String EXCEPTION_ERROR_DESCRIPTION = "This is an exception error message during the process. Please check the error message for detail information";
+       
+       private static String MISS_PROPERTY_ERROR = "POLICY-504E";
+       private static String MISS_PROPERTY_ERROR_DESCRIPTION = "This is an error of missing properties. Please check the error message for  detail information";
+       
+    private static String GENERAL_ERROR_CODE = "POLICY-515E";
+    private static String GENERAL_ERROR_DESCRIPTION = "This is a general error message during the process. Please check the error message for detail information";
+    
+    private static String ERROR_SYSTEM_ERROR = "POLICY-516E";
+       private static String ERROR_SYSTEM_ERROR_DESCRIPTION = "This is a System Error. Please check the error message for detail information";
+       
+       private static String ERROR_DATA_ISSUE = "POLICY-517E";
+       private static String ERROR_DATA_ISSUE_DESCRIPTION = "This is a Data Issue Error. Please check the error message for detail information";
+       
+       private static String ERROR_PROCESS_FLOW = "POLICY-518E";
+       private static String ERROR_PROCESS_FLOW_DESCRIPTION = "This is a Process Flow Error. Please check the error message for detail information";
+       
+       private static String ERROR_UNKNOWN = "POLICY-519E";
+       private static String ERROR_UNKNOWN_DESCRIPTION = "This is an Unknown Error. Please check the error message for detail information";
+
+       private static String ERROR_AUDIT = "POLICY-520E";
+       private static String ERROR_AUDIT_DESCRIPTION = "This is an audit Error. Please check the error message for detail information";
+    
+    static {
+       hm.put(MessageCodes.EXCEPTION_ERROR, new ErrorCodeInfo(EXCEPTION_ERROR_CODE, EXCEPTION_ERROR_DESCRIPTION));
+       hm.put(MessageCodes.GENERAL_ERROR, new ErrorCodeInfo(GENERAL_ERROR_CODE, GENERAL_ERROR_DESCRIPTION));
+       hm.put(MessageCodes.MISS_PROPERTY_ERROR, new ErrorCodeInfo(MISS_PROPERTY_ERROR, MISS_PROPERTY_ERROR_DESCRIPTION));
+       hm.put(MessageCodes.UPDATE_ERROR, new ErrorCodeInfo(UPDATE_ERROR, UPDATE_ERROR_DESCRIPTION));
+       hm.put(MessageCodes.ERROR_SYSTEM_ERROR, new ErrorCodeInfo(ERROR_SYSTEM_ERROR, ERROR_SYSTEM_ERROR_DESCRIPTION));
+       hm.put(MessageCodes.ERROR_DATA_ISSUE, new ErrorCodeInfo(ERROR_DATA_ISSUE, ERROR_DATA_ISSUE_DESCRIPTION));
+       hm.put(MessageCodes.ERROR_PERMISSIONS, new ErrorCodeInfo(ERROR_PERMISSIONS, ERROR_PERMISSIONS_DESCRIPTION));
+       hm.put(MessageCodes.ERROR_DATA_ISSUE, new ErrorCodeInfo(ERROR_DATA_ISSUE, ERROR_DATA_ISSUE_DESCRIPTION));
+       hm.put(MessageCodes.ERROR_PROCESS_FLOW, new ErrorCodeInfo(ERROR_PROCESS_FLOW, ERROR_PROCESS_FLOW_DESCRIPTION));
+       hm.put(MessageCodes.ERROR_SCHEMA_INVALID, new ErrorCodeInfo(ERROR_SCHEMA_INVALID, ERROR_SCHEMA_INVALID_DESCRIPTION));
+       hm.put(MessageCodes.ERROR_UNKNOWN, new ErrorCodeInfo(ERROR_UNKNOWN, ERROR_UNKNOWN_DESCRIPTION));
+       hm.put(MessageCodes.ERROR_AUDIT, new ErrorCodeInfo(ERROR_AUDIT, ERROR_AUDIT_DESCRIPTION));
+    }
+    
+    static class ErrorCodeInfo {
+       
+       private String errorCode;
+       private String errorDesc;
+       
+       public ErrorCodeInfo(String errorCode, String errorDesc){
+               this.errorCode = errorCode;
+               this.errorDesc = errorDesc;
+       }
+
+               public String getErrorCode() {
+                       return errorCode;
+               }
+
+               public void setErrorCode(String errorCode) {
+                       this.errorCode = errorCode;
+               }
+
+               public String getErrorDesc() {
+                       return errorDesc;
+               }
+
+               public void setErrorDesc(String errorDesc) {
+                       this.errorDesc = errorDesc;
+               }
+       
+    }  
+}
diff --git a/common-logging/src/main/java/org/openecomp/policy/common/logging/eelf/EventData.java b/common-logging/src/main/java/org/openecomp/policy/common/logging/eelf/EventData.java
new file mode 100644 (file)
index 0000000..549651f
--- /dev/null
@@ -0,0 +1,93 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP-Logging
+ * ================================================================================
+ * 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.logging.eelf;
+
+import java.time.Instant;
+
+import javax.swing.text.html.parser.Entity;
+
+/**
+ * 
+ * EventData can be used for logging a rule event.
+ *
+ */
+public class EventData {
+       
+       private String requestID = null;
+       private Instant startTime = null;
+       private Instant endTime = null;
+
+       public EventData() {
+               
+       }
+       
+       public EventData(String requestID, Instant startTime, Instant endTime) {
+               
+               this.requestID = requestID;
+               this.startTime = startTime;
+               this.endTime = endTime;         
+       }
+
+       public String getRequestID() {
+               return requestID;
+       }
+
+       public void setRequestID(String requestID) {
+               this.requestID = requestID;
+       }
+
+       public Instant getStartTime() {
+               return startTime;
+       }
+
+       public void setStartTime(Instant startTime) {
+               this.startTime = startTime;
+       }
+
+       public Instant getEndTime() {
+               return endTime;
+       }
+
+       public void setEndTime(Instant endTime) {
+               this.endTime = endTime;
+       }
+       
+       public String toString(){
+               return requestID + " Starting Time : " + this.startTime + " Ending Time : " + this.endTime;
+       }
+       @Override
+       public int hashCode(){
+               final int prime =31;
+               int result =1;
+               result = prime * result +((requestID == null) ? 0: requestID.hashCode());
+               return result;
+       }
+       @Override
+       public boolean equals(Object obj){
+               
+               String requestId = (String) obj;
+               if(requestID != null && requestID.equals(requestId)){
+                       return true;
+               }
+               return false;
+       }
+
+}
diff --git a/common-logging/src/main/java/org/openecomp/policy/common/logging/eelf/EventTrackInfo.java b/common-logging/src/main/java/org/openecomp/policy/common/logging/eelf/EventTrackInfo.java
new file mode 100644 (file)
index 0000000..c6ed63d
--- /dev/null
@@ -0,0 +1,90 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP-Logging
+ * ================================================================================
+ * 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.logging.eelf;
+
+import java.io.IOException;
+import java.time.Instant;
+import java.util.Properties;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.openecomp.policy.common.logging.flexlogger.PropertyUtil;
+
+/**
+ * 
+ * EventTrackInfo contains a ConcurrentHashMap of EventData
+ *
+ */
+public class EventTrackInfo {
+
+    private ConcurrentHashMap<String, EventData> eventInfo = null;    
+       
+       public EventTrackInfo() {
+               /*
+                * An initial capacity of 16 ensures the number of elements before resizing happens
+                * Load factor of 0,9 ensures a dense packaging inside ConcurrentHashMap which will optimize memory use
+                * ConcurencyLevel set to 1 will ensure that only one shard is created and maintained 
+                */
+               eventInfo = new ConcurrentHashMap<String, EventData>(16, 0.9f, 1);      
+       }
+   
+       /**
+        * Returns an instance of EventData associated to this requestID
+        * @param requestID
+        * @return EventData
+        */
+       public EventData getEventDataByRequestID(String requestID){
+               return eventInfo.get(requestID);
+       }
+       
+       /**
+        * Stores an EventData object in a ConcurrentHashMap using its requestID as key.
+        * @param event
+        */
+       public void storeEventData(EventData event){
+               
+               if(event == null || event.getRequestID() == null || event.getRequestID().isEmpty()){
+                       return;
+               }
+               //in case override the start time, check the original event was already stored or not 
+               if(!eventInfo.containsKey(event.getRequestID())){
+                       eventInfo.put(event.getRequestID(), event);             
+               }
+       }
+       
+       /**
+        * Removes an EventData object from a ConcurrentHashMap using the eventId as key. 
+        * @param eventId
+        */
+       public void remove(String eventId){
+               if(eventInfo != null){
+                       eventInfo.remove(eventId);
+               }
+       }
+       
+       /**
+        * Returns a ConcurrentHashMap of EventData
+        */
+       public ConcurrentHashMap<String, EventData> getEventInfo() {
+               return eventInfo;
+       }
+
+}
diff --git a/common-logging/src/main/java/org/openecomp/policy/common/logging/eelf/EventTrackInfoHandler.java b/common-logging/src/main/java/org/openecomp/policy/common/logging/eelf/EventTrackInfoHandler.java
new file mode 100644 (file)
index 0000000..a947ed0
--- /dev/null
@@ -0,0 +1,109 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP-Logging
+ * ================================================================================
+ * 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.logging.eelf;
+
+import java.time.Duration;
+import java.time.Instant;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.Timer;
+import java.util.TimerTask;
+
+/**
+ * 
+ * EventTrackInfoHandler is the handler of clean up all expired event objcts
+ *
+ */
+public class EventTrackInfoHandler extends TimerTask {
+
+       String className = this.getClass().getSimpleName();
+
+       @Override
+       public void run() {
+
+               PolicyLogger.info(className
+                               + " Release expired event records start...");
+
+               CleanUp();
+
+               PolicyLogger.info(className + " Release expired event records done");
+       }
+    
+       /**
+        * Removes all expired event objects from the ConcurrentHashMap of EventData
+        */
+       private void CleanUp() {
+
+               if (PolicyLogger.getEventTracker() == null
+                               || PolicyLogger.getEventTracker().getEventInfo() == null
+                               || PolicyLogger.getEventTracker().getEventInfo().isEmpty()) {
+                       return;
+               }
+
+               Instant startTime = null;
+               long ns = 0;
+
+               ArrayList<String> expiredEvents = null;
+
+               for (String key: PolicyLogger.getEventTracker().getEventInfo().keySet()) {
+                       EventData event  = PolicyLogger.getEventTracker().getEventInfo().get(key);
+                       startTime = event.getStartTime();
+                       ns = Duration.between(startTime, Instant.now()).getSeconds();
+
+                       PolicyLogger.info(className
+                                       + " duration time : " + ns);
+
+                       PolicyLogger.info(className
+                                       + " PolicyLogger.EXPIRED_TIME : " + PolicyLogger.EXPIRED_TIME); 
+
+                       // if longer than EXPIRED_TIME, remove the object
+
+                       if (ns > PolicyLogger.EXPIRED_TIME){    
+                               if (expiredEvents == null) {
+                                       expiredEvents = new ArrayList<String>();
+                               }
+                               expiredEvents.add(key);
+
+                               PolicyLogger.info(className
+                                               + " add expired event request ID: "
+                                               + event.getRequestID());
+                       }
+               }
+               
+               synchronized (PolicyLogger.getEventTracker().getEventInfo()) {  
+                       if (expiredEvents != null) {
+                               for (String expiredKey : expiredEvents) {
+                                       PolicyLogger.getEventTracker().getEventInfo()
+                                                       .remove(expiredKey);
+                                       System.out.println(className
+                                                       + " removed expired event request ID: "
+                                                       + expiredKey);
+                                       PolicyLogger.info(className
+                                                       + " removed expired event request ID: "
+                                                       + expiredKey);
+                               }
+                       }
+
+               }
+
+       }
+
+}
diff --git a/common-logging/src/main/java/org/openecomp/policy/common/logging/eelf/MDCInfo.java b/common-logging/src/main/java/org/openecomp/policy/common/logging/eelf/MDCInfo.java
new file mode 100644 (file)
index 0000000..6b5e395
--- /dev/null
@@ -0,0 +1,35 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP-Logging
+ * ================================================================================
+ * 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.logging.eelf;
+
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * 
+ * Interface needs to be implemented by DroolsPDPMDCInfo
+ *
+ */
+
+public interface MDCInfo {
+       
+       public ConcurrentHashMap<String, String> getMDCInfo();
+     
+}
diff --git a/common-logging/src/main/java/org/openecomp/policy/common/logging/eelf/MessageCodes.java b/common-logging/src/main/java/org/openecomp/policy/common/logging/eelf/MessageCodes.java
new file mode 100644 (file)
index 0000000..6f1437e
--- /dev/null
@@ -0,0 +1,163 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP-Logging
+ * ================================================================================
+ * 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.logging.eelf;
+
+import com.att.eelf.i18n.EELFResolvableErrorEnum;
+import com.att.eelf.i18n.EELFResourceManager;
+
+/**
+ * 
+ * MessageCodes contains all the messagge codes for EELF logging messages
+ *
+ */
+public enum MessageCodes implements EELFResolvableErrorEnum {
+       // Below is a list of Error Messages taken from com.att.research.xacml.api XACMLErrorConstants
+       //       found under:  policy-engine\XACML\src\main\java\com\att\research\xacml\api\XACMLErrorConstants.java
+
+       ERROR_PERMISSIONS,
+
+       ERROR_SYSTEM_ERROR,
+
+       ERROR_DATA_ISSUE,
+
+       ERROR_SCHEMA_INVALID,
+
+       ERROR_PROCESS_FLOW,
+
+       ERROR_UNKNOWN,
+       
+       ERROR_AUDIT,
+       
+       // Above is a list of Error Messages taken from com.att.research.xacml.api XACMLErrorConstants
+       //       found under:  policy-engine\XACML\src\main\java\com\att\research\xacml\api\XACMLErrorConstants.java
+               
+       //----------------------5000-5099 Business/Flow Processing Related --------------------/        
+       
+       BAD_TYPE_WARNING,
+       
+       GENERAL_INFO,
+       
+       GENERAL_WARNING,
+       
+       MISS_PROPERTY_ERROR,
+       
+       EXCEPTION_ERROR,
+       
+       MISS_PROPERTY_INFO,
+       
+       RULE_AUDIT_EXEC_INFO,
+       
+       RULE_AUDIT_BEGIN_INFO,
+       
+       RULE_AUDIT_END_INFO,    
+       
+       RULE_AUDIT_START_END_INFO,
+       
+       RULE_METRICS_INFO,      
+
+       UEB_AUDIT_EXEC_INFO,
+       
+       UEB_AUDIT_BEGIN_INFO,
+       
+       UEB_AUDIT_END_INFO,
+       
+       UPDATE_ERROR,
+
+       GENERAL_ERROR,
+       
+       //----------------------New enums should be added above this line ------------------------------------------------------------------/
+       
+       //--------------------- The enums below are old code. They should not be used since 1607 release and eventually will be removed -----/
+        /**
+     * Application message which requires no arguments
+     */
+       MESSAGE_SAMPLE_NOARGS,
+       
+        /**
+     * Application message which requires one argument {0}
+     */
+       MESSAGE_SAMPLE_ONEARGUMENT,
+       
+       /**
+     * Audit message which requires one argument {0}
+     */        
+       AUDIT_MESSAGE_ONEARGUMENT,
+       
+       /**
+     * Error message which requires one argument {0}
+     */
+       ERROR_MESSAGE_ONEARGUMENT,
+       
+       /**
+     * Metrics message which requires one argument {0}
+     */
+       METRICS_MESSAGE_ONEARGUMENT,
+       
+       /**
+     * Debug message which requires one argument {0}
+     */
+       DEBUG_MESSAGE_ONEARGUMENT,
+       
+    /**
+     * Application message which requires two argument {0} and another argument {1}
+     */
+       MESSAGE_SAMPLE_TWOARGUMENTS,
+       
+       /**
+     * Sample error exception
+     */
+    MESSAGE_SAMPLE_EXCEPTION,
+       
+       /**
+     * Sample warning message
+     */
+       MESSAGE_WARNING_SAMPLE,
+       
+       /**
+     * Sample exception in method {0}
+     */
+       MESSAGE_SAMPLE_EXCEPTION_ONEARGUMENT,
+       
+       /**
+     * Sample trace message
+     */
+       MESSAGE_TRACE_SAMPLE,
+       
+       /**
+     * Sample error message
+     */
+       MESSAGE_ERROR_SAMPLE;
+       
+       
+    /**
+     * Static initializer to ensure the resource bundles for this class are loaded...
+     * Here this application loads messages from three bundles
+     */
+    static {
+        EELFResourceManager.loadMessageBundle("org/openecomp/policy/common/logging/eelf/Resources");
+        String id = EELFResourceManager.getIdentifier(RULE_AUDIT_EXEC_INFO);
+        String value = EELFResourceManager.getMessage(RULE_AUDIT_EXEC_INFO);
+                
+        System.out.println("*********************** " + id);
+        System.out.println("*********************** " + value);
+       
+    }
+}
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
new file mode 100644 (file)
index 0000000..624ba58
--- /dev/null
@@ -0,0 +1,1438 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP-Logging
+ * ================================================================================
+ * 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.logging.eelf;
+
+import org.slf4j.MDC;
+
+import static org.openecomp.policy.common.logging.eelf.Configuration.*;
+
+import org.openecomp.policy.common.logging.flexlogger.LoggerType;
+import org.openecomp.policy.common.logging.eelf.PolicyLogger;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFLogger.Level;
+import com.att.eelf.configuration.EELFManager;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.text.SimpleDateFormat;
+import java.time.Duration;
+import java.time.Instant;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.Properties;
+import java.util.Timer;
+import java.util.TimerTask;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * 
+ * PolicyLogger contains all the static methods for EELF logging
+ *
+ */
+public class PolicyLogger {
+
+       private static EELFLogger applicationLogger = EELFManager.getInstance()
+                       .getApplicationLogger();
+
+       private static EELFLogger errorLogger = EELFManager.getInstance()
+                       .getErrorLogger();
+
+       private static EELFLogger metricsLogger = EELFManager.getInstance()
+                       .getMetricsLogger();
+
+       private static EELFLogger auditLogger = EELFManager.getInstance()
+                       .getAuditLogger();
+
+       private static EELFLogger debugLogger = EELFManager.getInstance()
+                       .getDebugLogger();
+       
+       private static EventTrackInfo eventTracker = new EventTrackInfo();
+       
+       private static String hostName = null;
+       private static String hostAddress = null;
+       private static String component = null;
+       
+       private static TimerTask ttrcker = null;
+       private static boolean isEventTrackerRunning = false;
+       private static Timer timer = null;
+       
+       //Default:Timer initial delay and the delay between in milliseconds before task is to be execute
+       private static int TIMER_DELAY_TIME = 1000;
+       
+       //Default:Timer scheduleAtFixedRate period - time in milliseconds between successive task executions
+       private static int CHECK_INTERVAL = 30 * 1000;
+       
+       //Default:longest time an event info can be stored in the concurrentHashMap for logging - in seconds 
+       static int EXPIRED_TIME = 60*60*1000*24; //one day
+       
+       //Default:the size of the concurrentHashMap which stores the event starting time - when its size reaches this limit, the Timer get executed
+       private static int CONCURRENTHASHMAP_LIMIT = 5000;
+       
+       //Default:the size of the concurrentHashMap which stores the event starting time - when its size drops to this point, stop the Timer
+       private static int STOP_CHECK_POINT = 2500;
+       
+       private static boolean isOverrideLogbackLevel = false;
+       
+       public static Level DEBUG_LEVEL = Level.INFO;
+       public static Level AUDIT_LEVEL = Level.INFO;
+       public static Level METRICS_LEVEL = Level.INFO;
+       public static Level ERROR_LEVEL = Level.ERROR;
+       public static String CLASS_NAME = "ClassName";
+       
+
+       static{
+               if (hostName == null || hostAddress == null) {
+                       try {
+                               hostName = InetAddress.getLocalHost().getHostName();
+                               hostAddress = InetAddress.getLocalHost().getHostAddress();
+                       } catch (UnknownHostException e) {
+                               PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyLogger", "UnknownHostException");
+                       }
+               }
+       }
+       
+       /**
+        * Populates MDC info 
+        * @param transId
+        * @return String
+        */
+       public static String postMDCInfoForEvent(String transId) {
+               MDC.clear();
+               
+               if(transId == null || transId.isEmpty()){
+                       transId = UUID.randomUUID().toString();
+               }
+               
+               if(component != null && component.equalsIgnoreCase("DROOLS")){
+                       return postMDCInfoForEvent(transId, new DroolsPDPMDCInfo());
+               }
+               
+               MDC.put(MDC_REMOTE_HOST, "");
+               MDC.put(MDC_KEY_REQUEST_ID, transId);
+               MDC.put(MDC_SERVICE_NAME, "Policy.xacmlPdp");
+               MDC.put(MDC_SERVICE_INSTANCE_ID, "Policy.xacmlPdp.event");
+               try {
+                       MDC.put(MDC_SERVER_FQDN, hostName);
+                       MDC.put(MDC_SERVER_IP_ADDRESS, hostAddress);
+               } catch (Exception e) {
+                       errorLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyLogger");
+               }
+               Instant startTime = Instant.now();
+               Instant endTime = Instant.now();
+               long ns = Duration.between(startTime, endTime).getSeconds();
+               String unit = " Seconds";
+               if(ns == 1){
+                       unit = " Second";
+               }
+               
+               if(ns < 1){
+                       ns = Duration.between(startTime, endTime).toMillis();
+                       unit = " milliseconds";
+               }
+               MDC.put(MDC_INSTANCE_UUID, "");
+               MDC.put(MDC_ALERT_SEVERITY, "");
+               
+               SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS+00:00");
+       
+               String formatedTime = sdf.format(Date.from(startTime));
+               MDC.put(BEGIN_TIME_STAMP, formatedTime );
+               
+               //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(PARTNER_NAME, "N/A");
+               
+               MDC.put(STATUS_CODE, "N/A");
+               MDC.put(RESPONSE_CODE, "N/A");
+               MDC.put(RESPONSE_DESCRIPTION, "N/A");
+               
+               
+               return transId;
+
+       }
+       
+       /**
+        * Populate MDC Info using the passed in mdcInfo
+        * @param transId
+        * @param mdcInfo
+        * @return String
+        */
+       private static String postMDCInfoForEvent(String transId, MDCInfo mdcInfo ) {
+               
+               MDC.put(MDC_KEY_REQUEST_ID, transId);
+               if(mdcInfo != null && mdcInfo.getMDCInfo() != null && !mdcInfo.getMDCInfo().isEmpty()){
+                       
+                       ConcurrentHashMap<String, String> mdcMap = mdcInfo.getMDCInfo();
+                   Iterator<String> keyIterator = mdcMap.keySet().iterator();
+                   String key = "";
+                   
+                   while(keyIterator.hasNext()){
+                       key = keyIterator.next();
+                       MDC.put(key, mdcMap.get(key));
+                   }               
+               }
+
+               try {
+                       MDC.put(MDC_SERVER_FQDN, hostName);
+                       MDC.put(MDC_SERVER_IP_ADDRESS, hostAddress);
+               } catch (Exception e) {
+                       errorLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyLogger");
+               }
+               Instant startTime = Instant.now();
+               Instant endTime = Instant.now();
+               long ns = Duration.between(startTime, endTime).getSeconds();
+               String unit = " Seconds";
+               if(ns == 1){
+                       unit = " Second";
+               }
+               
+               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");
+       
+               String formatedTime = sdf.format(Date.from(startTime));
+               MDC.put(BEGIN_TIME_STAMP, formatedTime );
+               
+               //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);
+
+               return transId;
+       }
+
+       /**
+        * Set Timestamps for start, end and duration of logging a transaction 
+        */
+       private static void seTimeStamps(){
+               
+               Instant startTime = Instant.now();
+               Instant endTime = Instant.now();
+               long ns = Duration.between(startTime, endTime).getSeconds();
+               String unit = " Seconds";
+               if(ns == 1){
+                       unit = " Second";
+               }
+               
+               if(ns < 1){
+                       ns = Duration.between(startTime, endTime).toMillis();
+                       unit = " milliseconds";
+               }
+               MDC.put(MDC_INSTANCE_UUID, "");
+               MDC.put(MDC_ALERT_SEVERITY, "");
+               
+               SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS+00:00");
+       
+               String formatedTime = sdf.format(Date.from(startTime));
+               MDC.put(BEGIN_TIME_STAMP, formatedTime );
+               
+               //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(PARTNER_NAME, "N/A");
+               
+               MDC.put(STATUS_CODE, "N/A");
+               MDC.put(RESPONSE_CODE, "N/A");
+               MDC.put(RESPONSE_DESCRIPTION, "N/A");
+
+       }
+       
+       /**
+        * Sets transaction Id to MDC
+        * @param transId
+        */
+       public static void setTransId(String transId){
+               
+               MDC.put(MDC_KEY_REQUEST_ID, transId);
+       }
+       
+       /**
+        * Returns current transaction Id used in MDC
+        * @return transId
+        */
+       public static String getTransId(){
+               
+               return MDC.get(MDC_KEY_REQUEST_ID);             
+       }
+       
+       /**
+        * Sets transaction Id to MDC
+        * @param o 
+        */
+       public static void postMDCInfoForEvent(Object o){
+               postMDCInfoForEvent(""+o);
+       }
+
+       /**
+        * Resets transaction Id in MDC for the rule triggered by this event
+        * @param transId
+        * @return String
+        */
+       public static String postMDCInfoForTriggeredRule(String transId) {
+               
+               MDC.clear();
+               
+               if(transId == null || transId.isEmpty()){
+                       transId = UUID.randomUUID().toString();
+               }
+               MDC.put(MDC_REMOTE_HOST, "");
+               MDC.put(MDC_KEY_REQUEST_ID, transId);
+               MDC.put(MDC_SERVICE_NAME, "Policy.droolsPdp");
+               MDC.put(MDC_SERVICE_INSTANCE_ID, "");
+               try {
+                       MDC.put(MDC_SERVER_FQDN, hostName);
+                       MDC.put(MDC_SERVER_IP_ADDRESS, hostAddress);
+               } catch (Exception e) {
+                       errorLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyLogger");
+               }
+               MDC.put(MDC_INSTANCE_UUID, "");
+               MDC.put(MDC_ALERT_SEVERITY, "");
+               MDC.put(STATUS_CODE, "N/A");
+               
+               return transId;
+
+       }
+       
+       /**
+        * Resets transaction Id in MDC for the rule triggered by this event
+        * @param o
+        */     
+       public static void postMDCUUIDForTriggeredRule(Object o) {
+               
+               postMDCInfoForTriggeredRule("" + o);
+
+       }
+
+       // ************************************************************************************************
+       /**
+        * Records the Info event with String [] arguments
+        * @param msg
+        * @param arguments
+        */
+       public static void info(MessageCodes msg, String... arguments) {
+               MDC.put(CLASS_NAME, "");
+               debugLogger.info(msg, arguments);
+       }
+       
+       /**
+        * Records the Info event with String [] arguments
+        * @param msg
+        * @param className
+        * @param arguments
+        */
+       public static void info(MessageCodes msg, String className, String... arguments) {
+               MDC.put(CLASS_NAME, className);
+               debugLogger.info(msg, arguments);
+       }
+       
+       /**
+        * Records only one String message with its class name
+        * @param className
+        * @param arg0
+        */
+       public static void info( String className, String arg0) {
+               MDC.put(CLASS_NAME, className);
+               debugLogger.info(MessageCodes.GENERAL_INFO, arg0);
+       }
+
+       /**
+        * Records only one String message without its class name passed in
+        * @param arg0
+        */
+       public static void info(String arg0) {
+               MDC.put(CLASS_NAME, "");
+               debugLogger.info(MessageCodes.GENERAL_INFO, arg0);
+       }
+       
+       /**
+        * Records only one String message
+        * @param arg0
+        */
+       public static void info(Object arg0) {
+               MDC.put(CLASS_NAME, "");
+               info(arg0);
+       }
+
+       /**
+        * Records a message with passed in message code, Throwable object, a list of string values
+        * @param msg
+        * @param arg0
+        * @param arguments
+        */
+       public static void info(MessageCodes msg, Throwable arg0,
+                       String... arguments) {
+               MDC.put(CLASS_NAME, "");
+           String arguments2 = getNormalizedStackTrace(arg0, arguments);
+           debugLogger.info(msg, arguments2);
+       }
+       
+       /**
+        * Records a message with passed in message code, class name, Throwable object, a list of string values
+        * @param msg
+        * @param className
+        * @param arg0
+        * @param arguments
+        */
+       public static void info(MessageCodes msg, String className, Throwable arg0,
+                       String... arguments) {
+               MDC.put(CLASS_NAME, className);
+           String arguments2 = getNormalizedStackTrace(arg0, arguments);
+           debugLogger.info(msg, arguments2);
+       }
+       
+       /**
+        * Records only one String message with its class name
+        * @param arg0 log message
+        * @param className class name
+        */
+       public static void warn( String className, String arg0) {
+               MDC.put(CLASS_NAME, className);
+               debugLogger.warn(MessageCodes.GENERAL_INFO, arg0);
+       }
+
+       /**
+        * Records only one String message
+        * @param arg0
+        */
+       public static void warn(Object arg0) {
+               MDC.put(CLASS_NAME, "");
+               debugLogger.warn(MessageCodes.GENERAL_WARNING, "" + arg0);
+       }
+       
+       /**
+        * Records only one String message without its class name passed in
+        * @param arg0
+        */
+       public static void warn(String arg0) {
+               MDC.put(CLASS_NAME, "");
+               debugLogger.warn(MessageCodes.GENERAL_WARNING, arg0);
+       }
+
+       /**
+        * Records a message with passed in message code and a list of string values
+        * @param msg
+        * @param arguments
+        */
+       public static void warn(MessageCodes msg, String... arguments) {
+               MDC.put(CLASS_NAME, "");
+               debugLogger.warn(msg, arguments);
+       }
+       
+       /**
+        * Records a message with passed in message code, class name and a list of string values
+        * @param msg
+        * @param className
+        * @param arguments
+        */     
+       public static void warn(MessageCodes msg, String className, String... arguments) {
+               MDC.put(CLASS_NAME, className);
+               debugLogger.warn(msg, arguments);
+       }
+
+       /**
+        * Records a message with passed in message code, Throwable object, a list of string values
+        * @param msg
+        * @param arg0
+        * @param arguments
+        */
+       public static void warn(MessageCodes msg, Throwable arg0,
+                       String... arguments) {
+               MDC.put(CLASS_NAME, "");
+           String arguments2 = getNormalizedStackTrace(arg0, arguments);
+           debugLogger.warn(msg, arguments2);
+       }
+       
+       /**
+        * Records a message with passed in message code, Throwable object, a list of string values
+        * @param msg
+        * @param className
+        * @param arg0
+        * @param arguments
+        */
+       public static void warn(MessageCodes msg, String className, Throwable arg0,
+                       String... arguments) {
+               MDC.put(CLASS_NAME, className);
+           String arguments2 = getNormalizedStackTrace(arg0, arguments);
+           debugLogger.warn(msg, arguments2);
+       }
+
+       /**
+        * Records only one String message with its class name
+        * @param className class name
+        * @param arg0 log message
+        */
+       public static void error( String className, String arg0) {
+               MDC.put(CLASS_NAME, className);
+               if(ErrorCodeMap.hm.get(MessageCodes.GENERAL_ERROR) != null){
+                   MDC.put(ERROR_CODE, ErrorCodeMap.hm.get(MessageCodes.GENERAL_ERROR).getErrorCode());
+                       MDC.put(ERROR_DESCRIPTION, ErrorCodeMap.hm.get(MessageCodes.GENERAL_ERROR).getErrorDesc());
+
+               }
+               errorLogger.error(MessageCodes.GENERAL_ERROR, arg0);
+       }
+       
+       /**
+        * Records only one String message
+        * @param arg0
+        */
+       public static void error(String arg0) {
+               MDC.put(CLASS_NAME, "");
+               MDC.put(ERROR_CATEGORY, "ERROR");
+               
+               if(ErrorCodeMap.hm.get(MessageCodes.GENERAL_ERROR) != null){
+                   MDC.put(ERROR_CODE, ErrorCodeMap.hm.get(MessageCodes.GENERAL_ERROR).getErrorCode());
+                       MDC.put(ERROR_DESCRIPTION, ErrorCodeMap.hm.get(MessageCodes.GENERAL_ERROR).getErrorDesc());
+
+               }
+               errorLogger.error(MessageCodes.GENERAL_ERROR, arg0);
+       }
+       
+       /**
+        * Records only one String message
+        * @param arg0
+        */
+       public static void error(Object arg0) {
+               MDC.put(CLASS_NAME, "");
+               MDC.put(ERROR_CATEGORY, "ERROR");
+               
+               if(ErrorCodeMap.hm.get(MessageCodes.GENERAL_ERROR) != null){
+                   MDC.put(ERROR_CODE, ErrorCodeMap.hm.get(MessageCodes.GENERAL_ERROR).getErrorCode());
+                       MDC.put(ERROR_DESCRIPTION, ErrorCodeMap.hm.get(MessageCodes.GENERAL_ERROR).getErrorDesc());
+
+               }
+               errorLogger.error(MessageCodes.GENERAL_ERROR, "" + arg0);
+       }
+       
+       /**
+        * Records a message with passed in message code, Throwable object, a list of string values
+        * @param msg
+        * @param arg0
+        * @param arguments
+        */
+       public static void error(MessageCodes msg, Throwable arg0,
+                       String... arguments) {
+               MDC.put(CLASS_NAME, "");
+               MDC.put(ERROR_CATEGORY, "ERROR");
+               
+               if(ErrorCodeMap.hm.get(msg) != null){
+                   MDC.put(ERROR_CODE, ErrorCodeMap.hm.get(msg).getErrorCode());
+                       MDC.put(ERROR_DESCRIPTION, ErrorCodeMap.hm.get(msg).getErrorDesc());
+
+               }
+           String arguments2 = getNormalizedStackTrace(arg0, arguments);
+               errorLogger.error(msg, arguments2);
+       }
+       
+       /**
+        * Records a message with passed in message code, class name, Throwable object, a list of string values
+        * @param msg
+        * @param className
+        * @param arg0
+        * @param arguments
+        */
+       public static void error(MessageCodes msg, String className, Throwable arg0,
+                       String... arguments) {
+               MDC.put(CLASS_NAME, className);
+               MDC.put(ERROR_CATEGORY, "ERROR");
+               
+               if(ErrorCodeMap.hm.get(msg) != null){
+                   MDC.put(ERROR_CODE, ErrorCodeMap.hm.get(msg).getErrorCode());
+                       MDC.put(ERROR_DESCRIPTION, ErrorCodeMap.hm.get(msg).getErrorDesc());
+
+               }
+           String arguments2 = getNormalizedStackTrace(arg0, arguments);
+               errorLogger.error(msg, arguments2);
+       }
+
+       /**
+        * Records a message with passed in message code and a list of string values
+        * @param msg
+        * @param arguments
+        */
+       public static void error(MessageCodes msg, String... arguments) {
+               MDC.put(CLASS_NAME, "");
+               MDC.put(ERROR_CATEGORY, "ERROR");
+               
+               if(ErrorCodeMap.hm.get(msg) != null){
+                   MDC.put(ERROR_CODE, ErrorCodeMap.hm.get(msg).getErrorCode());
+                       MDC.put(ERROR_DESCRIPTION, ErrorCodeMap.hm.get(msg).getErrorDesc());
+
+               }
+               errorLogger.error(msg, arguments);
+       }
+
+       /**
+        * Records a message with passed in message code and a list of string values
+        * @param msg
+        * @param arguments
+        */
+       public static void debug(MessageCodes msg, String... arguments) {
+               MDC.put(CLASS_NAME, "");
+               debugLogger.debug(msg, arguments);
+       }
+       
+       /**
+        * Records only one String message with its class name
+        * @param className
+        * @param arg0
+        */
+       public static void debug( String className, String arg0) {
+               MDC.put(CLASS_NAME, className);
+               debugLogger.debug(MessageCodes.GENERAL_INFO, arg0);
+       }
+
+       /**
+        * Records only one String message
+        * @param arg0
+        */
+       public static void debug(String arg0) {
+               MDC.put(CLASS_NAME, "");
+               debugLogger.debug(arg0);
+       }
+       
+       /**
+        * Records only one String message
+        * @param arg0
+        */
+       public static void debug(Object arg0) {
+
+               MDC.put(CLASS_NAME, "");
+               debugLogger.debug("" + arg0);
+       }
+       
+       /**
+        * Records only one String message with its class name
+        * @param className
+        * @param arg0
+        */
+       public static void audit(String className, Object arg0) {
+               MDC.put(STATUS_CODE, "N/A");
+               MDC.put(CLASS_NAME, className);
+               auditLogger.info("" + arg0);
+       }
+
+       /**
+        * Records only one String message
+        * @param arg0
+        */
+       public static void audit(Object arg0) {
+               MDC.put(STATUS_CODE, "N/A");
+               MDC.put(CLASS_NAME, "");
+               auditLogger.info("" + arg0);
+       }
+       
+       /**
+        * Records a message with passed in message code, hrowable object, a list of string values
+        * @param msg
+        * @param arg0
+        * @param arguments
+        */
+       public static void debug(MessageCodes msg, Throwable arg0,
+                       String... arguments) {
+               MDC.put(CLASS_NAME, "");
+           String arguments2 = getNormalizedStackTrace(arg0, arguments);
+               errorLogger.error(msg, arguments2);
+       }
+       
+       /**
+        * Records a message with passed in message code, class name, Throwable object, a list of string values
+        * @param msg
+        * @param className
+        * @param arg0
+        * @param arguments
+        */
+       public static void debug(MessageCodes msg, String className, Throwable arg0,
+                       String... arguments) {
+               MDC.put(CLASS_NAME, className);
+           String arguments2 = getNormalizedStackTrace(arg0, arguments);
+               errorLogger.error(msg, arguments2);
+       }
+       /**
+        * returns true for enabled, false for not enabled
+        */
+       public static boolean isDebugEnabled(){
+               
+               return debugLogger.isDebugEnabled();
+       }
+
+       /**
+        * returns true for enabled, false for not enabled
+        */
+       public static boolean isErrorEnabled(){
+               
+               return errorLogger.isErrorEnabled();
+       }
+       
+       /**
+        * returns true for enabled, false for not enabled
+        */
+       public static boolean isWarnEnabled(){
+               
+               return debugLogger.isWarnEnabled();
+       }
+       
+       /**
+        * returns true for enabled, false for not enabled
+        */
+       public static boolean isInfoEnabled1(){
+               
+               return debugLogger.isInfoEnabled();
+       }       
+       
+       /**
+        * returns true for enabled, false for not enabled
+        */
+       public static boolean isAuditEnabled(){
+               
+               return debugLogger.isInfoEnabled();
+       }
+       
+       /**
+        * returns true for enabled, false for not enabled
+        */
+       public static boolean isInfoEnabled(){
+               
+               return debugLogger.isInfoEnabled();
+       }
+       
+       /**
+        * Records only one String message with its class name
+        * @param className
+        * @param arg0
+        */
+       public static void trace( String className, String arg0) {
+               MDC.put(CLASS_NAME, className);
+               errorLogger.info(MessageCodes.GENERAL_INFO, arg0);
+       }
+               
+       /**
+        * Records only one String message
+        * @param arg0
+        */
+       public static void trace(Object arg0){
+               
+               MDC.put(CLASS_NAME, "");
+                debugLogger.trace(""+arg0);
+       }       
+       /**
+        * Records the starting time of the event with its request Id as the key
+        * @param eventId
+        */
+       public static void recordAuditEventStart(String eventId) {
+               
+               MDC.put(STATUS_CODE, "N/A");            
+               postMDCInfoForEvent(eventId);
+               
+               if(eventTracker == null){
+                       eventTracker = new EventTrackInfo();
+               }
+               EventData  event = new EventData();
+               event.setRequestID(eventId);
+               event.setStartTime(Instant.now());
+               eventTracker.storeEventData(event);
+               MDC.put(MDC_KEY_REQUEST_ID, eventId);
+               debugLogger.info("CONCURRENTHASHMAP_LIMIT : " + CONCURRENTHASHMAP_LIMIT);       
+               //--- Tracking the size of the concurrentHashMap, if it is above limit, keep EventTrack Timer running
+               int size = eventTracker.getEventInfo().size();
+               
+               debugLogger.info("EventInfo concurrentHashMap Size : " + size + " on " + new Date());   
+               debugLogger.info("isEventTrackerRunning : " + isEventTrackerRunning);   
+               
+               if( size >= CONCURRENTHASHMAP_LIMIT){ 
+                       
+                       
+                       if(!isEventTrackerRunning){
+                               
+                           startCleanUp();     
+                           isEventTrackerRunning = true;
+                       }
+                       
+               }else if( size <= STOP_CHECK_POINT){
+                   
+                       if(isEventTrackerRunning){
+                               stopCleanUp();
+                       }                       
+               }
+       }
+       
+       /**
+        * Records the starting time of the event with its request Id as the key
+        * @param eventId
+        */
+       public static void recordAuditEventStart(UUID eventId) {
+               
+               if(eventId == null){
+                       return;
+               }
+               
+               if(eventTracker == null){
+                       eventTracker = new EventTrackInfo();
+               }
+               
+               recordAuditEventStart(eventId.toString());
+
+       }
+       
+       /**
+        * Records the ending time of the event with its request Id as the key
+        * @param eventId
+        * @param rule
+        */
+       public static void recordAuditEventEnd(String eventId, String rule) {
+               
+               if(eventTracker == null){
+                       return;
+               }
+               if(eventId == null){
+                       return;
+               }
+
+               creatAuditEventTrackingRecord(eventId, rule, "");
+               
+       }
+       
+       /**
+        * Records the ending time of the event with its request Id as the key
+        * @param eventId 
+        * @param rule
+        * @param policyVersion 
+        */
+       public static void recordAuditEventEnd(String eventId, String rule , String policyVersion) {
+               
+               if(eventTracker == null){
+                       return;
+               }
+               if(eventId == null){
+                       return;
+               }
+
+               creatAuditEventTrackingRecord(eventId, rule, policyVersion);
+               
+       }
+       
+       /**
+        * Records the ending time of the event with its request Id as the key
+        * @param eventId 
+        * @param rule
+        * @param policyVersion 
+        */
+       public static void recordAuditEventEnd(UUID eventId, String rule, String policyVersion) {
+               
+               if(eventId == null){
+                       return;
+               }
+               
+               recordAuditEventEnd(eventId.toString(), rule, policyVersion);
+               
+       }       
+       
+       
+       /**
+        * Records the ending time of the event with its request Id as the key
+        * @param eventId
+        * @param rule
+        */
+       public static void recordAuditEventEnd(UUID eventId, String rule) {
+               
+               if(eventId == null){
+                       return;
+               }
+               
+               recordAuditEventEnd(eventId.toString(), rule);
+               
+       }               
+       
+       /**
+        * Records the ending time of the event with its request Id as the key
+        * @param eventId
+        * @param rule
+        * @param policyVersion 
+        */
+       public static void creatAuditEventTrackingRecord(String eventId, String rule, String policyVersion) {
+               
+               if(eventTracker == null){
+                       return;
+               }       
+               
+               EventData event = eventTracker.getEventDataByRequestID(eventId);
+               
+               if(event != null){
+                       Instant endTime = event.getEndTime();
+                       if(endTime == null){
+                               endTime = Instant.now();
+                       }
+                       MDC.put(STATUS_CODE, "COMPLETE");
+                       recordAuditEventStartToEnd(eventId, rule, event.getStartTime(), endTime, policyVersion);
+               }
+       }
+       
+       /**
+        * Records the ending time of the event with its request Id as the key
+        * @param eventId 
+        * @param rule 
+        */
+       public static void creatAuditEventTrackingRecord(UUID eventId, String rule) {
+               
+               if(eventId == null){
+                       return;
+               }
+               
+               if(eventTracker == null){
+                       return;
+               }       
+               
+               EventData event = eventTracker.getEventDataByRequestID(eventId.toString());
+               
+               if(event != null){
+                       Instant endTime = event.getEndTime();
+                       if(endTime == null){
+                               endTime = Instant.now();
+                       }
+                       
+                       recordAuditEventStartToEnd(eventId.toString(), rule, event.getStartTime(), endTime, "N/A");
+               }
+       }
+
+       public static EventTrackInfo getEventTracker() {
+               return eventTracker;
+       }
+
+       /**
+        * Records the audit with an event starting and ending times 
+        * @param eventId
+        * @param rule
+        * @param startTime
+        * @param endTime
+        * @param policyVersion
+        */
+       public static void recordAuditEventStartToEnd(String eventId, String rule, Instant startTime, Instant endTime, String policyVersion) {
+               
+               if(startTime == null || endTime == null){
+                       return;
+               }
+               String serviceName = MDC.get(MDC_SERVICE_NAME);
+               if(eventId != null && !eventId.isEmpty()){
+                  MDC.put(MDC_KEY_REQUEST_ID, eventId);
+               }
+               
+               SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS+00:00");
+               
+               String formatedTime = sdf.format(Date.from(startTime));
+               MDC.put(BEGIN_TIME_STAMP, formatedTime );
+               
+               //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(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";
+               }
+               
+               if(ns < 1){
+                       ns = Duration.between(startTime, endTime).toMillis();
+                       unit = " milliseconds";
+               }
+               
+               MDC.put(ELAPSED_TIME, ns + unit);
+               
+               auditLogger.info(MessageCodes.RULE_AUDIT_START_END_INFO,
+                       serviceName, rule, startTime.toString(), endTime.toString(), ns+unit, policyVersion);
+               
+               //--- remove the record from the concurrentHashMap
+               if(eventTracker != null){
+                       if(eventTracker.getEventDataByRequestID(eventId) != null){
+                               eventTracker.remove(eventId);
+                               debugLogger.info("eventTracker.remove(" + eventId + ")");
+                       }
+               }       
+       }
+
+       /**
+        * Records the metrics with an event Id and log message 
+        * @param eventId
+        * @param arg1
+        */
+       public static void recordMetricEvent(String eventId, String arg1) {
+               
+               seTimeStamps();  
+               
+               String serviceName = MDC.get(MDC_SERVICE_NAME);
+               MDC.put(MDC_KEY_REQUEST_ID, eventId);
+               metricsLogger.info(MessageCodes.RULE_AUDIT_END_INFO,
+                               serviceName, arg1);
+
+       }
+       
+       /**
+        * Records the metrics with an event Id, class name and log message 
+        * @param eventId
+        * @param className
+        * @param arg1
+        */
+       public static void recordMetricEvent(String eventId, String className,String arg1) {
+               
+               seTimeStamps();
+               
+               MDC.put(CLASS_NAME, className);
+               String serviceName = MDC.get(MDC_SERVICE_NAME);
+               MDC.put(MDC_KEY_REQUEST_ID, eventId);
+               metricsLogger.info(MessageCodes.RULE_AUDIT_END_INFO,
+                               serviceName, arg1);
+       }
+       
+       /**
+        * Records the metrics with an event Id and log message 
+        * @param eventId
+        * @param arg1
+        */
+       public static void recordMetricEvent(UUID eventId, String arg1) {
+               
+               if(eventId == null){
+                       return;
+               }               
+               String serviceName = MDC.get(MDC_SERVICE_NAME);
+               MDC.put(MDC_KEY_REQUEST_ID, eventId.toString());
+               metricsLogger.info(MessageCodes.RULE_AUDIT_END_INFO,
+                               serviceName, arg1);
+       }
+       
+       /**
+        * Records a String message for metrics logs
+        * @param arg0
+        */
+       public static void recordMetricEvent(String arg0) {
+               seTimeStamps();
+               String serviceName = MDC.get(MDC_SERVICE_NAME);
+               metricsLogger.info(MessageCodes.RULE_METRICS_INFO,
+                               serviceName, arg0);
+       }
+       
+
+       /**
+        * Records the metrics event with a String message
+        * @param arg0
+        */
+       public static void metrics(String arg0) {
+               String serviceName = MDC.get(MDC_SERVICE_NAME);
+               metricsLogger.info(MessageCodes.RULE_METRICS_INFO,
+                               serviceName, arg0);
+       }
+       
+       /**
+        * Records the metrics event with a class name and a String message 
+        * @param arg0
+        */
+       public static void metrics(String className, Object arg0) {
+               seTimeStamps();
+               MDC.put(CLASS_NAME, className);
+               String serviceName = MDC.get(MDC_SERVICE_NAME);
+               metricsLogger.info(MessageCodes.RULE_METRICS_INFO,
+                               serviceName, ""+arg0);
+       }
+       
+       /**
+        * Records the metrics event with a String message
+        * @param arg0
+        */
+       public static void metrics(Object arg0) {
+               seTimeStamps();
+               MDC.put(CLASS_NAME, "");
+               String serviceName = MDC.get(MDC_SERVICE_NAME);
+               metricsLogger.info(MessageCodes.RULE_METRICS_INFO,
+                               serviceName, ""+arg0);
+       }
+       
+       /**
+        * Records the metrics event with a String message
+        * @param arg0
+        */
+       public static void metricsPrintln(String arg0) {
+               MDC.clear();
+               metricsLogger.info(arg0);
+       }
+       
+       /**
+        * Removes all the return lines from the printStackTrace
+        * @param t
+        * @param arguments
+        */
+       private static String getNormalizedStackTrace (Throwable t, String...arguments) {
+        StringWriter sw = new StringWriter();
+        PrintWriter pw = new PrintWriter(sw);
+        t.printStackTrace(pw);
+        String newStValue = sw.toString().replace ('|', '!').replace ("\n", " - ");
+        int curSize = (arguments == null ? 0 : arguments.length);
+        StringBuffer newArgument = new StringBuffer();
+        for(int i=0; i<curSize; i++) {
+               newArgument.append(arguments[i]);
+               newArgument.append(":");
+        }
+        newArgument.append(newStValue);       
+               return newArgument.toString();
+    }
+       
+       /**
+        * Starts the process of cleaning up the ConcurrentHashMap of EventData
+        */
+       private static void startCleanUp(){
+               
+               if(!isEventTrackerRunning) {
+                       ttrcker = new EventTrackInfoHandler(); 
+                       timer = new Timer(true);
+                       timer.scheduleAtFixedRate(ttrcker, TIMER_DELAY_TIME, CHECK_INTERVAL);
+                       debugLogger.info("EventTrackInfoHandler begins! : " + new Date());
+               }else{
+                       debugLogger.info("Timer is still running : " + new Date());
+
+               }               
+       }
+
+       
+       /**
+        * Stops the process of cleaning up the ConcurrentHashMap of EventData
+        */
+       private static void stopCleanUp(){
+               
+               if(isEventTrackerRunning && timer != null){                     
+             timer.cancel();
+             timer.purge();
+                       debugLogger.info("Timer stopped: " + new Date());             
+               }else{
+                       debugLogger.info("Timer was already stopped : " + new Date());
+
+               }               
+               isEventTrackerRunning = false;
+               
+       }
+       
+       /**
+        * Loads all the attributes from policyLogger.properties file
+        */
+       public  static  LoggerType init(Properties properties) throws Exception  {
+               // read in properties
+               Properties logger_properties = properties;
+               LoggerType logger_type = LoggerType.EELF;
+
+               // fetch and verify definitions of some properties
+               try{
+                       
+                       int timerDelayTime = Integer.parseInt(logger_properties.getProperty("timer.delay.time"));
+                       int checkInterval = Integer.parseInt(logger_properties.getProperty("check.interval"));
+                       int expiredDate = Integer.parseInt(logger_properties.getProperty("event.expired.time"));
+                       int concurrentHashMapLimit = Integer.parseInt(logger_properties.getProperty("concurrentHashMap.limit"));
+                       int stopCheckPoint = Integer.parseInt(logger_properties.getProperty("stop.check.point"));                       
+                   String loggerType = logger_properties.getProperty("logger.type");
+                   
+                   String debugLevel = logger_properties.getProperty("debugLogger.level");
+                   String metricsLevel = logger_properties.getProperty("metricsLogger.level");
+                   String auditLevel = logger_properties.getProperty("error.level");
+                   String errorLevel = logger_properties.getProperty("audit.level");
+                   component = logger_properties.getProperty("policy.component");      
+                   String overrideLogbackLevel = logger_properties.getProperty("override.logback.level.setup");
+
+                   if(overrideLogbackLevel != null && !overrideLogbackLevel.isEmpty()) {
+                       if(overrideLogbackLevel.equalsIgnoreCase("TRUE")){
+                               isOverrideLogbackLevel = true;
+                       }else{
+                               isOverrideLogbackLevel = false;
+                       }
+                   }
+                   
+               
+                       if (debugLevel != null && !debugLevel.isEmpty()){
+                               
+                               DEBUG_LEVEL = Level.valueOf(debugLevel);
+                               
+                       }
+                       //Only check if it is to turn off or not
+                       if (errorLevel != null && errorLevel.equalsIgnoreCase(Level.OFF.toString())){
+                               
+                               ERROR_LEVEL = Level.valueOf(errorLevel);
+                               
+                       }
+                       //Only check if it is to turn off or not
+                       if (metricsLevel != null && metricsLevel.equalsIgnoreCase(Level.OFF.toString())){
+                               
+                               METRICS_LEVEL = Level.valueOf(metricsLevel);
+                               
+                       }
+                       //Only check if it is to turn off or not
+                       if (auditLevel != null && auditLevel.equalsIgnoreCase(Level.OFF.toString())){
+                               
+                               AUDIT_LEVEL = Level.valueOf(auditLevel);
+                               
+                       }                       
+
+            if(isOverrideLogbackLevel){
+               
+                               debugLogger.setLevel(DEBUG_LEVEL);      
+                               metricsLogger.setLevel(METRICS_LEVEL);                          
+                               auditLogger.setLevel(AUDIT_LEVEL);                              
+                               errorLogger.setLevel(ERROR_LEVEL);
+                               
+            }
+                       isEventTrackerRunning = false;
+                       
+                       debugLogger.info("timerDelayTiime value: " + timerDelayTime);
+
+                       debugLogger.info("checkInterval value: " + checkInterval);
+
+                       debugLogger.info("expiredDate value: " + expiredDate);
+
+                       debugLogger.info("concurrentHashMapLimit value: " + concurrentHashMapLimit);
+
+                       debugLogger.info("loggerType value: " + loggerType);            
+
+                       debugLogger.info("debugLogger level: " + debugLevel);   
+
+                       debugLogger.info("component: " + component);                            
+
+                       if (timerDelayTime > 0){
+                               
+                               TIMER_DELAY_TIME = timerDelayTime;
+                               
+                       }else {
+                               MDC.put(ERROR_CATEGORY, "ERROR");
+                               if(ErrorCodeMap.hm.get(MessageCodes.GENERAL_ERROR) != null){
+                                   MDC.put(ERROR_CODE, ErrorCodeMap.hm.get(MessageCodes.GENERAL_ERROR).getErrorCode());
+                                       MDC.put(ERROR_DESCRIPTION, ErrorCodeMap.hm.get(MessageCodes.GENERAL_ERROR).getErrorDesc());
+
+                               }
+                               errorLogger.error("failed to get the timer.delay.time, so use its default value: " + TIMER_DELAY_TIME);
+                       }
+                       
+                       if (checkInterval > 0){
+                               
+                               CHECK_INTERVAL = checkInterval;
+                               
+                       }else {
+                               MDC.put(ERROR_CATEGORY, "ERROR");
+                               if(ErrorCodeMap.hm.get(MessageCodes.GENERAL_ERROR) != null){
+                                   MDC.put(ERROR_CODE, ErrorCodeMap.hm.get(MessageCodes.GENERAL_ERROR).getErrorCode());
+                                       MDC.put(ERROR_DESCRIPTION, ErrorCodeMap.hm.get(MessageCodes.GENERAL_ERROR).getErrorDesc());
+
+                               }
+                               errorLogger.error("failed to get the check.interval, so use its default value: " + CHECK_INTERVAL);
+                       }
+                       
+                       if (expiredDate > 0){
+                               
+                               EXPIRED_TIME = expiredDate;
+                               
+                       }else {
+                               MDC.put(ERROR_CATEGORY, "ERROR");
+                               
+                               if(ErrorCodeMap.hm.get(MessageCodes.GENERAL_ERROR) != null){
+                                   MDC.put(ERROR_CODE, ErrorCodeMap.hm.get(MessageCodes.GENERAL_ERROR).getErrorCode());
+                                       MDC.put(ERROR_DESCRIPTION, ErrorCodeMap.hm.get(MessageCodes.GENERAL_ERROR).getErrorDesc());
+
+                               }
+                               errorLogger.error("failed to get the event.expired.time, so use its default value: " + EXPIRED_TIME);
+                       }
+                       
+                       if (concurrentHashMapLimit > 0){
+                               
+                               CONCURRENTHASHMAP_LIMIT = concurrentHashMapLimit;
+                               
+                       }else {
+                               MDC.put(ERROR_CATEGORY, "ERROR");
+                               if(ErrorCodeMap.hm.get(MessageCodes.GENERAL_ERROR) != null){
+                                   MDC.put(ERROR_CODE, ErrorCodeMap.hm.get(MessageCodes.GENERAL_ERROR).getErrorCode());
+                                       MDC.put(ERROR_DESCRIPTION, ErrorCodeMap.hm.get(MessageCodes.GENERAL_ERROR).getErrorDesc());
+
+                               }
+                               errorLogger.error("failed to get the concurrentHashMap.limit, so use its default value: " + CONCURRENTHASHMAP_LIMIT);
+                       }       
+                       
+                       if (stopCheckPoint > 0){
+                               
+                               STOP_CHECK_POINT = stopCheckPoint;
+                               
+                       }else {
+                               MDC.put(ERROR_CATEGORY, "ERROR");
+                               if(ErrorCodeMap.hm.get(MessageCodes.GENERAL_ERROR) != null){
+                                   MDC.put(ERROR_CODE, ErrorCodeMap.hm.get(MessageCodes.GENERAL_ERROR).getErrorCode());
+                                       MDC.put(ERROR_DESCRIPTION, ErrorCodeMap.hm.get(MessageCodes.GENERAL_ERROR).getErrorDesc());
+
+                               }
+                               errorLogger.error("failed to get the stop.check.point, so use its default value: " + STOP_CHECK_POINT);
+                       }       
+                       
+                       if (loggerType != null){
+                               
+                               if (loggerType.equalsIgnoreCase("EELF")){
+                                       
+                                       logger_type = LoggerType.EELF;
+                                       
+                               }else if (loggerType.equalsIgnoreCase("LOG4J")){
+                                       
+                                       logger_type = LoggerType.LOG4J;
+                                       
+                               }else if (loggerType.equalsIgnoreCase("SYSTEMOUT")){
+                                       
+                                       logger_type = LoggerType.SYSTEMOUT;
+                                       
+                               }
+                               
+                       }
+                       
+                       if (debugLevel != null && !debugLevel.isEmpty()){
+                               
+                               DEBUG_LEVEL = Level.valueOf(debugLevel);
+                               
+                       }
+                       //Only check if it is to turn off or not
+                       if (errorLevel != null && errorLevel.equalsIgnoreCase(Level.OFF.toString())){
+                               
+                               ERROR_LEVEL = Level.valueOf(errorLevel);
+                               
+                       }
+                       //Only check if it is to turn off or not
+                       if (metricsLevel != null && metricsLevel.equalsIgnoreCase(Level.OFF.toString())){
+                               
+                               METRICS_LEVEL = Level.valueOf(metricsLevel);
+                               
+                       }
+                       //Only check if it is to turn off or not
+                       if (auditLevel != null && auditLevel.equalsIgnoreCase(Level.OFF.toString())){
+                               
+                               AUDIT_LEVEL = Level.valueOf(auditLevel);
+                               
+                       }
+                       
+               }catch(Exception e){
+                       MDC.put(ERROR_CATEGORY, "ERROR");
+                       
+                       if(ErrorCodeMap.hm.get(MessageCodes.GENERAL_ERROR) != null){
+                           MDC.put(ERROR_CODE, ErrorCodeMap.hm.get(MessageCodes.GENERAL_ERROR).getErrorCode());
+                               MDC.put(ERROR_DESCRIPTION, ErrorCodeMap.hm.get(MessageCodes.GENERAL_ERROR).getErrorDesc());
+
+                       }
+                       errorLogger.error("failed to get the policyLogger.properties, so use their default values",e);
+               }
+               
+               return logger_type;
+
+       }
+       
+       /**
+        * Sets Debug Level
+        */
+       public static void setDebugLevel(String debugLevel){
+               
+               if(isOverrideLogbackLevel){
+                       PolicyLogger.DEBUG_LEVEL = Level.valueOf(debugLevel); 
+                       debugLogger.setLevel(DEBUG_LEVEL);
+               }
+               
+       }
+       
+    /**
+     * Sets Error OFF or ON
+     */
+       public static void setErrorLevel(String errorLevel){    
+               
+               if(isOverrideLogbackLevel){
+                       if(errorLevel != null && errorLevel.equalsIgnoreCase("OFF")){
+                               PolicyLogger.ERROR_LEVEL = Level.OFF; 
+                               errorLogger.setLevel(ERROR_LEVEL);
+                       }else{
+                               //--- set default value
+                           errorLogger.setLevel(Level.ERROR);
+                           PolicyLogger.ERROR_LEVEL = Level.ERROR;
+                       }
+               }
+       }
+       
+       /**
+        * Sets Metrics OFF or ON
+        */
+       public static void setMetricsLevel(String metricsLevel){
+               
+               if(isOverrideLogbackLevel){
+                       if(metricsLevel != null && metricsLevel.equalsIgnoreCase("OFF")){
+                               PolicyLogger.METRICS_LEVEL = Level.OFF;
+                               metricsLogger.setLevel(METRICS_LEVEL);
+                       }else {
+                               //--- set default value
+                               metricsLogger.setLevel(Level.INFO);
+                               PolicyLogger.METRICS_LEVEL = Level.INFO; 
+                       }
+               }
+               
+       }
+       
+       /**
+        * Sets Audit OFF or ON
+        */
+       public static void setAuditLevel(String auditLevel){
+               
+               if(isOverrideLogbackLevel){
+                       if(auditLevel != null && auditLevel.equalsIgnoreCase("OFF")){
+                               PolicyLogger.AUDIT_LEVEL = Level.OFF; 
+                               auditLogger.setLevel(AUDIT_LEVEL);
+                       }else {
+                               //--- set default value
+                               auditLogger.setLevel(Level.INFO);
+                               PolicyLogger.AUDIT_LEVEL = Level.INFO; 
+                       }
+               }
+       }
+       
+       /**
+        * Returns true for overriding logback levels; returns false for not
+        */
+       public static boolean isOverrideLogbackLevel(){
+               
+               return isOverrideLogbackLevel;
+       }
+       
+       /**
+        * Sets true for overriding logback levels; sets false for not
+        */     
+       public static void setOverrideLogbackLevel(boolean odl){
+               
+               isOverrideLogbackLevel = odl;
+               
+       }
+       /**
+        * Sets server information to MDC
+        */
+       public static void setServerInfo(String serverHost, String serverPort){
+               MDC.put(SERVER_NAME, serverHost+":"+serverPort);                
+       }
+
+}
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
new file mode 100644 (file)
index 0000000..6e74b94
--- /dev/null
@@ -0,0 +1,481 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP-Logging
+ * ================================================================================
+ * 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.logging.flexlogger;
+
+import java.util.UUID;
+
+import org.openecomp.policy.common.logging.eelf.MessageCodes;
+import org.openecomp.policy.common.logging.eelf.PolicyLogger;
+import org.openecomp.policy.common.logging.flexlogger.Logger;
+import com.att.eelf.configuration.EELFLogger.Level;
+
+/**
+ * 
+ * EelfLogger implements all the methods of interface Logger by calling PolicyLogger methods
+ *
+ */
+
+public class EelfLogger implements Logger {
+       
+    private String className = "";
+    private String transId = UUID.randomUUID().toString();
+    
+    /**
+     * Constructor
+     * @param clazz
+     */
+       public EelfLogger(Class clazz) {
+               if(clazz != null){
+                  className = clazz.getName();
+               }
+               PolicyLogger.postMDCInfoForEvent(null); 
+       }
+       
+    /**
+     * Constructor
+        * @param s
+     */
+       public EelfLogger(String s) {
+               if(s != null){
+                  className = s;
+               }
+               PolicyLogger.postMDCInfoForEvent(null); 
+       }
+       
+       /**
+        * Constructor
+        * @param clazz
+        * @param isNewTransaction
+        */
+       public EelfLogger(Class clazz, boolean isNewTransaction) {
+               if(clazz != null){
+                  className = clazz.getName();
+               }
+        if(isNewTransaction){          
+                   transId = PolicyLogger.postMDCInfoForEvent(null);               
+        }else{         
+               transId = PolicyLogger.getTransId();
+        }              
+       }
+       
+       /**
+        * Constructor
+        * @param s
+        * @param isNewTransaction
+        */
+       public EelfLogger(String s, boolean isNewTransaction) {
+               if(s != null){
+                  className = s;
+               }
+        if(isNewTransaction){          
+                   transId = PolicyLogger.postMDCInfoForEvent(null);               
+        }else{         
+               transId = PolicyLogger.getTransId();
+        }              
+       }
+       
+       /**
+        * Constructor
+        * @param clazz
+        * @param transId
+        */
+       public EelfLogger(Class clazz, String transId) {
+               if(clazz != null){
+                  className = clazz.getName();
+               }
+               PolicyLogger.postMDCInfoForEvent(transId);
+       }
+       
+       /**
+        * Constructor
+        * @param s
+        * @param transId
+        */
+       public EelfLogger(String s, String transId) {
+               if(s != null){
+                  className = s;
+               }
+               PolicyLogger.postMDCInfoForEvent(transId);
+       }
+       
+       /**
+        * Sets transaction Id for logging
+        * @param transId
+        */
+       @Override
+       public void setTransId(String transId){
+               
+               PolicyLogger.setTransId(transId);
+               this.transId = transId;
+       }
+       
+       /**
+        * Returns transaction Id for logging
+        */
+       @Override
+       public String getTransId(){             
+               return transId;
+       }
+       
+       /**
+        * Records a message
+        * @param message
+        */
+       @Override
+       public void debug(Object message) {  
+               PolicyLogger.debug(className, ""+message);
+       }
+
+       /**
+        * Records an error message
+        * @param message
+        */
+       @Override
+       public void error(Object message) {             
+               PolicyLogger.error(className, ""+message);
+       }
+
+       /**
+        * Records a message
+        * @param message
+        */
+       @Override
+       public void info(Object message) {              
+        PolicyLogger.info(className, ""+message);
+       }       
+
+       /**
+        * Records a message
+        * @param message
+        */
+       @Override
+       public void warn(Object message) {              
+               PolicyLogger.warn(className, ""+message);
+       }
+
+       /**
+        * Records a message
+        * @param message
+        */
+       @Override
+       public void trace(Object message) {             
+               PolicyLogger.trace(className, ""+message);
+       }
+       
+       /**
+        * Returns true for debug enabled, or false for not
+        * @return boolean
+        */
+       @Override
+       public boolean isDebugEnabled(){                
+               return PolicyLogger.isDebugEnabled();
+       }
+       
+       /**
+        * Returns true for info enabled, or false for not
+        * @return boolean
+        */
+       @Override
+       public boolean isInfoEnabled(){         
+               return PolicyLogger.isInfoEnabled();
+       }
+       
+       /**
+        * Returns true for warn enabled, or false for not
+        * @return boolean
+        */
+       @Override
+       public boolean isWarnEnabled(){         
+               return PolicyLogger.isWarnEnabled();
+       }
+       
+       /**
+        * Returns true for error enabled, or false for not
+        * @return boolean
+        */
+       @Override
+       public boolean isErrorEnabled(){                
+               return PolicyLogger.isErrorEnabled();
+       }
+       
+       /**
+        * Returns true for audit enabled, or false for not
+        * @return boolean
+        */
+       @Override
+       public boolean isAuditEnabled(){                
+               if(PolicyLogger.AUDIT_LEVEL != null && PolicyLogger.AUDIT_LEVEL.toString().equals(Level.OFF.toString())){
+                       return false;
+               }else {
+                       return true;
+               }
+       }
+       
+       /**
+        * Returns true for metrics enabled, or false for not
+        * @return boolean
+        */
+       @Override
+       public boolean isMetricsEnabled(){                      
+               if(PolicyLogger.METRICS_LEVEL != null && PolicyLogger.METRICS_LEVEL.toString().equals(Level.OFF.toString())){
+                       return false;
+               }else {
+                       return true;
+               }
+       }
+       
+       /**
+        * Returns true for trace enabled, or false for not
+        * @return boolean
+        */
+       @Override
+       public boolean isTraceEnabled(){                
+               return PolicyLogger.isDebugEnabled();
+       }
+       
+       /**
+        * Records an audit message
+        * @param arg0
+        */
+       @Override
+       public void audit(Object arg0) {                
+               PolicyLogger.audit(className, ""+ arg0);                
+       }
+    
+       /**
+        * Records a message 
+        * @param message
+        * @param t
+        */
+       @Override
+       public void debug(Object message, Throwable t) { 
+               PolicyLogger.debug(MessageCodes.GENERAL_INFO, t, message.toString()); 
+       }
+
+       /**
+        * Records an error message 
+        * @param message
+        * @param t
+        */
+       @Override
+       public void error(Object message, Throwable t) { 
+               PolicyLogger.error(MessageCodes.ERROR_UNKNOWN, t, message.toString()); 
+       }
+
+       /**
+        * Records a message 
+        * @param message
+        * @param t
+        */
+       @Override
+       public void info(Object message, Throwable t) { 
+               PolicyLogger.info(MessageCodes.GENERAL_INFO, t, message.toString()); 
+       }
+
+       /**
+        * Records a message 
+        * @param message
+        * @param t
+        */
+       @Override
+       public void warn(Object message, Throwable t) { 
+               PolicyLogger.warn(MessageCodes.GENERAL_WARNING, t, message.toString()); 
+       }
+
+       /**
+        * Records a message 
+        * @param message
+        * @param t
+        */
+       @Override
+       public void trace(Object message, Throwable t) { 
+               PolicyLogger.trace(message); 
+       } 
+       
+       /**
+        * Records an audit message 
+        * @param arg0
+        * @param t
+        */
+       @Override
+       public void audit(Object arg0, Throwable t) { 
+               PolicyLogger.audit(arg0); 
+       } 
+       
+       /**
+        * Records an audit message 
+        * @param eventId
+        */     
+       @Override
+       public void recordAuditEventStart(String eventId) {             
+               PolicyLogger.recordAuditEventStart(eventId);
+       }
+
+       /**
+        * Records an audit message 
+        * @param eventId
+        */     
+       @Override
+       public void recordAuditEventStart(UUID eventId) {               
+               PolicyLogger.recordAuditEventStart(eventId);
+       }
+
+       /**
+        * Records an audit message 
+        * @param eventId
+        * @param rule
+        * @param policyVersion
+        */     
+       @Override
+       public void recordAuditEventEnd(String eventId, String rule, String policyVersion) {            
+               PolicyLogger.recordAuditEventEnd(eventId, rule, policyVersion);
+       }
+
+       /**
+        * Records an audit message 
+        * @param eventId
+        * @param rule
+        * @param policyVersion
+        */     
+       @Override
+       public void recordAuditEventEnd(UUID eventId, String rule, String policyVersion) {      
+               PolicyLogger.recordAuditEventEnd(eventId, rule, policyVersion);
+       }
+       
+       /**
+        * Records an audit message 
+        * @param eventId
+        * @param rule
+        */     
+       @Override
+       public void recordAuditEventEnd(String eventId, String rule) {          
+               PolicyLogger.recordAuditEventEnd(eventId, rule);
+       }
+
+       /**
+        * Records an audit message 
+        * @param eventId
+        * @param rule
+        */     
+       @Override
+       public void recordAuditEventEnd(UUID eventId, String rule) {            
+               PolicyLogger.recordAuditEventEnd(eventId, rule);
+       }       
+
+       /**
+        * Records a metrics message 
+        * @param eventId
+        * @param arg1
+        */     
+       @Override
+       public void recordMetricEvent(String eventId, String arg1) {
+               PolicyLogger.recordMetricEvent(eventId, arg1);
+       }
+
+       /**
+        * Records a metrics message 
+        * @param eventId
+        * @param arg1
+        */     
+       @Override
+       public void recordMetricEvent(UUID eventId, String arg1) {              
+               PolicyLogger.recordMetricEvent(eventId, arg1);
+       }
+
+       /**
+        * Records a metrics message 
+        * @param arg0
+        */     
+       @Override
+       public void metrics(Object arg0) {
+               PolicyLogger.metrics(className, arg0);
+       }
+
+       /**
+        * Records an error message 
+        * @param msg
+        * @param arg0
+        * @param arguments
+        */             
+       @Override
+       public void error(MessageCodes msg, Throwable arg0, String... arguments){               
+               PolicyLogger.error(msg, className, arg0, arguments);
+       }
+       
+       /**
+        * Records an error message 
+        * @param msg
+        * @param arguments
+        */     
+       @Override
+       public void error(MessageCodes msg, String... arguments){               
+               PolicyLogger.error(msg, arguments);  
+       }
+       
+       /**
+        * Populates MDC Info
+        * @param transId
+        */     
+       @Override
+       public String postMDCInfoForEvent(String transId) {             
+               return PolicyLogger.postMDCInfoForEvent(transId);
+       
+       }
+       
+       /**
+        * Records a message 
+        * @param msg
+        * @param arguments
+        */
+    @Override
+       public void warn(MessageCodes msg, String... arguments){        
+       PolicyLogger.warn(msg, className, arguments);
+    }
+       
+       /**
+        * Records a message 
+        * @param msg
+        * @param arg0
+        * @param arguments
+        */
+    @Override
+       public void warn(MessageCodes msg, Throwable arg0, String... arguments){        
+       PolicyLogger.warn(msg, className, arg0, arguments);     
+    }
+       
+       /**
+        * Populates MDC Info for the rule triggered
+        * @param transId
+        */
+    @Override
+    public void postMDCInfoForTriggeredRule(String transId){           
+       PolicyLogger.postMDCInfoForTriggeredRule(transId);
+    }
+    
+       /**
+        * Populates MDC Info
+        * @param o
+        */    
+    @Override
+       public void postMDCInfoForEvent(Object o){
+       PolicyLogger.postMDCInfoForEvent(o);
+       }
+}
diff --git a/common-logging/src/main/java/org/openecomp/policy/common/logging/flexlogger/FlexLogger.java b/common-logging/src/main/java/org/openecomp/policy/common/logging/flexlogger/FlexLogger.java
new file mode 100644 (file)
index 0000000..4748e34
--- /dev/null
@@ -0,0 +1,366 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP-Logging
+ * ================================================================================
+ * 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.logging.flexlogger;
+
+import java.io.IOException;
+import java.text.SimpleDateFormat;
+import java.time.Instant;
+import java.util.Date;
+import java.util.Properties;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.openecomp.policy.common.logging.eelf.PolicyLogger;
+import org.openecomp.policy.common.logging.flexlogger.PropertyUtil;
+import org.openecomp.policy.common.logging.flexlogger.PropertyUtil.Listener;
+
+/**
+ * 
+ * FlexLogger acts as factory to generate instances of Logger based on logger type
+ *
+ */
+public class FlexLogger extends SecurityManager{
+
+       private static LoggerType loggerType = LoggerType.EELF;
+       private static boolean initLoggerCalled = false;
+    private static ConcurrentHashMap<String, Logger4J> logger4JMap = new ConcurrentHashMap<String, Logger4J>();
+    private static ConcurrentHashMap<String, EelfLogger> eelfLoggerMap = new ConcurrentHashMap<String, EelfLogger>();
+    private static ConcurrentHashMap<String, SystemOutLogger> systemOutMap = new ConcurrentHashMap<String, SystemOutLogger>();
+    //--- init logger first
+       static {
+               loggerType = initlogger();
+       }
+    
+       /**
+        * Returns an instance of Logger
+        * @param clazz
+        */
+       static public Logger getLogger(Class clazz) {
+               
+               if (initLoggerCalled == false) {
+                       loggerType = initlogger();
+               }
+               Logger logger = null;
+               System.out.println("FlexLogger:getLogger : loggerType = " + loggerType);
+               switch (loggerType) {
+
+               case EELF:
+                       logger = getEelfLogger(clazz, false);                   
+                       break;
+               case LOG4J:                     
+                       logger = getLog4JLogger(clazz);                 
+                       break;
+               case SYSTEMOUT:
+                       logger = getSystemOutLogger(null);
+                       break;
+               }
+
+               return logger;
+
+       }
+
+       /**
+        * Returns an instance of Logger
+        * @param s
+        */
+       static public Logger getLogger(String s) {
+
+               if (initLoggerCalled == false) {
+                       loggerType = initlogger();
+               }               
+               Logger logger = null;
+               System.out.println("FlexLogger:getLogger : loggerType = " + loggerType);
+               switch (loggerType) {
+
+               case EELF:
+                       logger = getEelfLogger(null,false);
+                       break;
+               case LOG4J:                     
+                       logger = getLog4JLogger(s);
+                       break;                  
+               case SYSTEMOUT:
+                       logger = getSystemOutLogger(null);
+                       break;
+               }
+
+               return logger;
+
+       }
+       
+       /**
+        * Returns an instance of Logger
+        * @param clazz
+        * @param isNewTransaction
+        */
+       static public Logger getLogger(Class clazz, boolean isNewTransaction) {
+
+               if (initLoggerCalled == false) {
+                       loggerType = initlogger();
+               }
+               Logger logger = null;
+               System.out.println("FlexLogger:getLogger : loggerType = " + loggerType);
+               switch (loggerType) {
+
+               case EELF:
+                       logger = getEelfLogger(clazz, isNewTransaction);
+                       break;
+               case LOG4J:
+                       logger = getLog4JLogger(clazz);
+                       break;
+               case SYSTEMOUT:
+                       logger = getSystemOutLogger(null);
+                       break;
+               }
+
+               return logger;
+
+       }
+
+       /**
+        * Returns an instance of Logger
+        * @param s
+        * @param isNewTransaction
+        */
+       static public Logger getLogger(String s, boolean isNewTransaction) {
+
+               if (initLoggerCalled == false) {
+                       loggerType = initlogger();
+               }
+               Logger logger = null;
+               System.out.println("FlexLogger:getLogger : loggerType = " + loggerType);
+               switch (loggerType) {
+
+               case EELF:
+                       logger = getEelfLogger(null, isNewTransaction);
+                       break;
+               case LOG4J:
+                       logger = getLog4JLogger(s);
+                       break;
+               case SYSTEMOUT:
+                       logger = getSystemOutLogger(null);
+                       break;
+               }
+
+               return logger;
+       }
+   
+       /**
+        * Returns the calling class name
+        */
+   public String getClassName(){       
+           System.out.println("getClassContext()[3].getName() " + getClassContext()[3].getName());
+           return getClassContext()[3].getName();
+       }
+   
+       /**
+        * Returns an instance of Logger4J
+        * @param clazz
+        */
+   private static Logger4J getLog4JLogger(Class clazz){
+                String className = new FlexLogger().getClassName();
+
+               if(!logger4JMap.containsKey(className)){
+                       //for 1610 release use the default debug.log for log4j
+                       Logger4J logger = new Logger4J("debugLogger", className);       
+                       logger4JMap.put(className, logger);
+               }
+               
+               return logger4JMap.get(className);
+   }
+   
+       /**
+        * Returns an instance of Logger4J
+        * @param s
+        */
+   private static Logger4J getLog4JLogger(String s){
+                String className = new FlexLogger().getClassName();
+
+               if(!logger4JMap.containsKey(className)){
+                       Logger4J logger = new Logger4J(s, className);   
+                       logger4JMap.put(className, logger);
+               }
+               
+               return logger4JMap.get(className);
+   }
+   
+       /**
+        * Returns an instance of EelfLogger
+        * @param clazz
+        * @param isNewTransaction
+        */
+   private static EelfLogger getEelfLogger(Class clazz, boolean isNewTransaction){
+
+               String className = "";
+               EelfLogger logger = null;
+               if(clazz != null){
+                       className = clazz.getName();
+               }else{
+                       className = new FlexLogger().getClassName();
+               }
+               
+               if(!eelfLoggerMap.containsKey(className)){
+                       logger = new EelfLogger(clazz, isNewTransaction);
+                       eelfLoggerMap.put(className, logger);
+               }else{ 
+               logger = eelfLoggerMap.get(className);
+               if(logger == null){
+                       logger = new EelfLogger(clazz, isNewTransaction);
+                       eelfLoggerMap.put(className, logger);
+               }
+                       //installl already created but it is new transaction
+               if(isNewTransaction){                   
+                       String transId = PolicyLogger.postMDCInfoForEvent(null);
+                       logger.setTransId(transId);
+               }
+               }
+               System.out.println("eelfLoggerMap size : " + eelfLoggerMap.size() + " class name: " + className);
+               return logger;
+   }
+   
+       /**
+        * Returns an instance of SystemOutLogger
+        * @param clazz
+        */
+   private static SystemOutLogger getSystemOutLogger(Class clazz){
+
+                String className = new FlexLogger().getClassName();
+               
+               if(!systemOutMap.containsKey(className)){
+                       SystemOutLogger logger = new SystemOutLogger(className);
+                       systemOutMap.put(className, logger);
+               }
+               
+               return systemOutMap.get(className);
+   }
+   
+       /**
+        * loads the logger properties
+        */
+       private static LoggerType initlogger() {
+               LoggerType loggerType = LoggerType.EELF;
+               String overrideLogbackLevel = "FALSE";
+               String logger_Type = "";
+               try {
+
+                        Properties properties = null;
+                    properties = PropertyUtil.getProperties(
+                                "config/policyLogger.properties");
+                    System.out.println("FlexLogger:properties => " + properties); 
+                    
+                   if(properties != null) {
+                       overrideLogbackLevel = properties.getProperty("override.logback.level.setup");  
+                       System.out.println("FlexLogger:overrideLogbackLevel => " + overrideLogbackLevel);
+                       logger_Type = properties.getProperty("logger.type");
+                               if (logger_Type != null){
+                                       
+                                       if (logger_Type.equalsIgnoreCase("EELF")){
+                                               
+                                               loggerType = LoggerType.EELF;
+                                               
+                                       }else if (logger_Type.equalsIgnoreCase("LOG4J")){
+                                               
+                                               loggerType = LoggerType.LOG4J;
+                                               
+                                       }else if (logger_Type.equalsIgnoreCase("SYSTEMOUT")){
+                                               
+                                               loggerType = LoggerType.SYSTEMOUT;
+                                               
+                                       }
+                                       
+                                   System.out.println("FlexLogger.logger_Type value: " + logger_Type);
+                               }
+                   }
+                       //--- only use reload policyLogger.properties file listener for logger type EEFL and overrideLogbackLevel flag is true
+                       if(logger_Type.equalsIgnoreCase("EELF") && overrideLogbackLevel != null && overrideLogbackLevel.equalsIgnoreCase("TRUE")){
+                               
+                                System.out.println("FlexLogger: start listener.");
+                            properties = PropertyUtil.getProperties(
+                                        "config/policyLogger.properties", new PropertiesCallBack(
+                                                       "FlexLogger-CallBack"));
+                       }else{
+                               System.out.println("FlexLogger: no listener needed.");
+                       }
+                       
+                       try {
+
+                               loggerType = PolicyLogger.init(properties);
+                               initLoggerCalled = true;
+
+                       } catch (Exception e) {
+                               System.out.println("initlogger" + e);
+                       }
+                       
+               } catch (IOException e1) {
+                       System.out.println("initlogger" + e1);
+               }
+
+               return loggerType;
+       }
+       
+       /**
+        * PropertiesCallBack is listening any updates on the policyLogger.properties
+        */
+       static public class PropertiesCallBack implements Listener {
+               String name;
+
+               public PropertiesCallBack(String name) {
+                       this.name = name;
+               }
+        
+               /**
+                * This method will be called automatically if he policyLogger.properties got updated
+                */
+               public void propertiesChanged(Properties properties,
+                               Set<String> changedKeys) {
+                       
+                       String debugLevel = properties.getProperty("debugLogger.level");
+                       String metricsLevel = properties.getProperty("metricsLogger.level");
+                       String auditLevel = properties.getProperty("audit.level");
+                       String errorLevel = properties.getProperty("error.level");
+                       
+                       SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS+00:00");
+                       Instant startTime = Instant.now();
+                       String formatedTime = sdf.format(Date.from(startTime));
+                       System.out.println("FlexLogger.propertiesChanged : called at time : " + formatedTime);
+                       System.out.println("FlexLogger.propertiesChanged : debugLevel : " + debugLevel);
+                       
+                       if (changedKeys != null) {
+
+                               if (changedKeys.contains("debugLogger.level")) {
+                                       PolicyLogger.setDebugLevel(debugLevel);
+                               }
+
+                               if (changedKeys.contains("metricsLogger.level")) {
+                                       PolicyLogger.setMetricsLevel(metricsLevel);
+                               }
+
+                               if (changedKeys.contains("error.level")) {
+                                       PolicyLogger.setErrorLevel(errorLevel);
+                               }
+
+                               if (changedKeys.contains("audit.level")) {
+                                       PolicyLogger.setAuditLevel(auditLevel);
+                               }
+                       }                               
+                 }
+         }
+       
+}
diff --git a/common-logging/src/main/java/org/openecomp/policy/common/logging/flexlogger/FlexLoggerTester.java b/common-logging/src/main/java/org/openecomp/policy/common/logging/flexlogger/FlexLoggerTester.java
new file mode 100644 (file)
index 0000000..3e0d558
--- /dev/null
@@ -0,0 +1,81 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP-Logging
+ * ================================================================================
+ * 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.logging.flexlogger;
+
+import java.util.UUID;
+
+public class FlexLoggerTester {
+
+       
+       public void testLogging(){
+               
+               // get an instance of logger 
+               Logger  logger = FlexLogger.getLogger(FlexLoggerTester.class);
+               
+               //logger.info("this is a testing of FlexLogger with logger type:" + FlexLogger.loggerType);
+               
+               logger.info("logger.isAuditEnabled():" + logger.isAuditEnabled());
+               logger.info("logger.isDebugEnabled():" + logger.isDebugEnabled());
+               logger.info("logger.isErrorEnabled():" + logger.isErrorEnabled());
+               logger.info("logger.isInfoEnabled():" + logger.isInfoEnabled());
+               logger.info("logger.isMetricsEnabled():" + logger.isMetricsEnabled());
+               logger.info("logger.isWarnEnabled():" + logger.isWarnEnabled());
+               
+               if(logger.isDebugEnabled())
+                   logger.debug("this is from logger.debug call");
+               else
+                       logger.info("this is from logger.info call");
+
+               if(logger.isMetricsEnabled()) logger.metrics("this is from logger.metrics call");
+               
+               logger.error("this is from logger.error call");
+               if(logger.isAuditEnabled()) 
+                       logger.audit("this is from logger.audit call");
+               else{
+                       logger.audit("shouldn't see this line in audit log");
+                       logger.info("shouldn't see this line in audit log");
+               }
+               
+               if(logger.isMetricsEnabled()) 
+                       logger.metrics("this is from logger.metrics call");
+               else{
+                       logger.metrics("shouldn't see this line in metrics log");
+                       logger.info("shouldn't see this line in metrics log");
+               }
+               
+               if(logger.isErrorEnabled()) {
+                       logger.error("this is from logger.error call");
+               }else{
+                       logger.error("shouldn't see this logger.error call in error.log");
+                       logger.info("error is not enabled");
+               }
+               
+               logger.info("logger.isDebugEnabled() returned value:" + logger.isDebugEnabled());
+               logger.recordAuditEventEnd("123345456464998", "from recordAuditEventEnd call", "12345");
+               logger.recordAuditEventEnd(UUID.randomUUID(), "from recordAuditEventEnd call", "abcdf");
+               logger.recordAuditEventStart("from recordAuditEventStart call");
+               logger.recordAuditEventStart(UUID.randomUUID().toString());
+               logger.recordMetricEvent("123345456464998", "from recordMetricEvent call");
+               logger.recordMetricEvent(UUID.randomUUID(), "from recordMetricEvent call");
+               logger.trace("from trace call");
+
+       }
+}
diff --git a/common-logging/src/main/java/org/openecomp/policy/common/logging/flexlogger/Logger.java b/common-logging/src/main/java/org/openecomp/policy/common/logging/flexlogger/Logger.java
new file mode 100644 (file)
index 0000000..ae21008
--- /dev/null
@@ -0,0 +1,226 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP-Logging
+ * ================================================================================
+ * 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.logging.flexlogger;
+
+import static org.openecomp.policy.common.logging.eelf.Configuration.STATUS_CODE;
+
+import static com.att.eelf.configuration.Configuration.MDC_SERVICE_NAME;
+import java.util.UUID;
+
+import org.slf4j.MDC;
+
+import org.openecomp.policy.common.logging.eelf.MessageCodes;
+
+/**
+ * 
+ * Interface Logger - implemented by Logger4J, EelfLogger and SystemOutLogger
+ *
+ */
+public interface Logger {      
+       
+       /**
+        * Prints messages with the level.DEBUG
+        */
+       public void debug(Object message);
+       
+       /**
+        * Prints messages with the level.ERROR
+        */
+       public void error(Object message);
+       
+       /**
+        * Prints messages with the level.ERROR
+        */
+       public void error(MessageCodes msg, Throwable arg0, String... arguments);
+
+       /**
+        * Prints messages with the level.INFO
+        */
+       public void info(Object message);
+       
+       /**
+        * Prints messages with the level.WARN
+        */
+       public void warn(Object message);               
+
+       /**
+        * Prints messages with the level.TRACE
+        */
+       public void trace(Object message);      
+       
+       /**
+        * Prints messages in audit log with the level.INFO
+        */
+       public void audit(Object arg0);
+       
+       /**
+        * Prints messages with the level.DEBUG
+        */
+       public void debug(Object message, Throwable t);
+       
+       /**
+        * Prints messages with the level.ERROR
+        */
+       public void error(Object message, Throwable t);
+
+       /**
+        * Prints messages with the level.INFO
+        */
+       public void info(Object message, Throwable t);
+       
+       /**
+        * Prints messages with the level.WARN
+        */
+       public void warn(Object message, Throwable t);          
+
+       /**
+        * Prints messages with the level.TRACE
+        */
+       public void trace(Object message, Throwable t); 
+       
+       /**
+        * Prints messages in audit log with the level.INFO
+        */
+       public void audit(Object arg0, Throwable t);
+       
+       /**
+        * Records event Id in audit log with the level.INFO
+        */
+       public void recordAuditEventStart(String eventId);
+       
+       /**
+        * Records the starting time of the event with its request Id as the key
+        */
+       public void recordAuditEventStart(UUID eventId);
+       
+       /**
+        * Records the ending time of the event with its request Id as the key
+        */
+       public void recordAuditEventEnd(String eventId, String rule, String policyVersion );
+       
+       /**
+        * Records the ending time of the event with its request Id as the key
+        */
+       public void recordAuditEventEnd(UUID eventId, String rule, String policyVersion);
+       
+       /**
+        * Records the ending time of the event with its request Id as the key
+        */
+       public void recordAuditEventEnd(String eventId, String rule);
+       
+       /**
+        * Records the ending time of the event with its request Id as the key
+        */
+       public void recordAuditEventEnd(UUID eventId, String rule);
+       
+       
+       /**
+        * Records the Metrics with event Id and log message 
+        */
+       public void recordMetricEvent(String eventId, String arg1);
+       
+       /**
+        * Records the Metrics with event Id and log message 
+        */
+       public void recordMetricEvent(UUID eventId, String arg1);
+       
+       /**
+        * Records the Metrics log message
+        */
+       public void metrics(Object arg0);
+       
+       /**
+        * Returns a boolean value, true for debug logging enabled, false for not enabled
+        */
+       public boolean isDebugEnabled();
+       
+       /**
+        * Returns a boolean value, true for error logging enabled, false for not enabled
+        */
+       public boolean isErrorEnabled();
+       
+       /**
+        * Returns a boolean value, true for warn logging enabled, false for not enabled
+        */
+       public boolean isWarnEnabled();
+       
+       /**
+        * Returns a boolean value, true for info logging enabled, false for not enabled
+        */
+       public boolean isInfoEnabled(); 
+
+       /**
+        * Returns a boolean value, true for error logging enabled, false for not enabled
+        */
+       public boolean isAuditEnabled();
+       
+       /**
+        * Returns a boolean value, true for warn logging enabled, false for not enabled
+        */
+       public boolean isMetricsEnabled();
+       
+       /**
+        * Returns a boolean value, true for trace logging enabled, false for not enabled
+        */
+       public boolean isTraceEnabled();
+       
+       
+       /**
+        * Populates MDC info
+        */     
+       public String postMDCInfoForEvent(String transId);
+       
+       /**
+        * Prints messages with the level.WARN
+        */
+       public void warn(MessageCodes msg, String... arguments) ;
+       
+       /**
+        * Prints messages with the level.WARN
+        */
+       public void warn(MessageCodes msg, Throwable arg0, String... arguments) ;
+       
+       /**
+        * Prints messages with the level.ERROR
+        */
+       public void error(MessageCodes msg, String... arguments) ;
+       
+       /**
+        * Sets transaction Id
+        */
+       public void setTransId(String transId);
+
+       /**
+        * Returns transaction Id
+        */
+       String getTransId();
+       
+       /**
+        * Populates MDC Info for the rule triggered
+        */
+       public void postMDCInfoForTriggeredRule(String transId);
+       
+       /**
+        * Populates MDC Info
+        */
+       public void postMDCInfoForEvent(Object o);
+       
+}
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
new file mode 100644 (file)
index 0000000..02f95cf
--- /dev/null
@@ -0,0 +1,454 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP-Logging
+ * ================================================================================
+ * 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.logging.flexlogger;
+
+import java.util.UUID;
+
+import org.apache.log4j.Logger;
+import org.apache.log4j.Priority;
+
+import org.openecomp.policy.common.logging.eelf.MessageCodes;
+import org.openecomp.policy.common.logging.eelf.PolicyLogger;
+import com.att.eelf.configuration.EELFLogger.Level;
+
+/**
+ * 
+ * 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 {
+       
+       private Logger log = null;
+    private String methodName = "";
+    private String className = "";
+       private String transId = UUID.randomUUID().toString();
+       
+    /**
+     * Constructor
+     * @param clazz
+     */
+       public Logger4J (Class clazz){
+               System.out.println("create instance of Logger4J");
+               if(clazz != null){
+                  log = Logger.getLogger(clazz);
+                  className = clazz.getName();
+               }
+       }
+       
+    /**
+     * Constructor
+     * @param s
+     * @param className
+     */
+       public Logger4J (String s, String className){
+               System.out.println("create instance of Logger4J");
+               if(s != null){
+                  log = Logger.getLogger(s);
+               }
+               this.className = className;
+       }
+
+    /**
+     * Sets transaction Id
+     */
+       @Override
+       public void setTransId(String transId){         
+               log.info(transId);
+               this.transId = transId;
+       }
+       
+    /**
+     * Returns transaction Id
+     */
+       @Override
+       public String getTransId(){             
+               return transId;
+       }
+
+       /**
+        * Records a message
+        * @param message
+        */
+       @Override
+       public void debug(Object message) {             
+               if(isDebugEnabled()){
+                  log.debug(transId + "|" + message);
+               }
+       }
+
+       /**
+        * Records an error message
+        * @param message
+        */
+       @Override
+       public void error(Object message) {
+               log.error( transId + "|" + className +"|" + message);
+       }
+
+       /**
+        * Records a message
+        * @param message
+        */
+       @Override
+       public void info(Object message) {
+               log.info( transId + "|" + className +"|" + message);
+       }
+       
+       /**
+        * Records a message
+        * @param message
+        */
+       @Override
+       public void warn(Object message) {
+               log.warn( transId + "|" + className +"|" + message);
+       }
+
+       /**
+        * Records a message
+        * @param message
+        */
+       @Override
+       public void trace(Object message) {
+               log.trace(transId + "|"+ className +"|"  + message);
+       }
+       
+       /**
+        * Returns true for debug enabled, or false for not
+        * @return boolean
+        */
+       @Override
+       public boolean isDebugEnabled(){
+               return log.isDebugEnabled();
+       }
+       
+       /**
+        * Returns true for error enabled, or false for not
+        * @return boolean
+        */
+       @SuppressWarnings("deprecation")
+       @Override
+       public boolean isErrorEnabled(){
+               return log.isEnabledFor(Priority.ERROR);
+       }
+       
+       /**
+        * Returns true for info enabled, or false for not
+        * @return boolean
+        */
+       @Override
+       public boolean isInfoEnabled(){
+               return log.isInfoEnabled();
+       }
+       
+       /**
+        * Returns true for warn enabled, or false for not
+        * @return boolean
+        */
+       @SuppressWarnings("deprecation")
+       @Override
+       public boolean isWarnEnabled(){
+               //return log4j value
+               return log.isEnabledFor(Priority.WARN);
+       }
+       
+       /**
+        * Returns true for audit enabled, or false for not
+        * @return boolean
+        */
+       @Override
+       public boolean isAuditEnabled(){                
+               if(PolicyLogger.AUDIT_LEVEL != null && PolicyLogger.AUDIT_LEVEL.toString().equals(Level.OFF.toString())){
+                       return false;
+               }else {
+                       return true;
+               }
+       }
+       
+       /**
+        * Returns true for metrics enabled, or false for not
+        * @return boolean
+        */
+       @Override
+       public boolean isMetricsEnabled(){                      
+               if(PolicyLogger.METRICS_LEVEL != null && PolicyLogger.METRICS_LEVEL.toString().equals(Level.OFF.toString())){
+                       return false;
+               }else {
+                       return true;
+               }
+       }
+
+       /**
+        * Records an audit message
+        * @param arg0
+        */
+       @Override
+       public void audit(Object arg0) {
+               log.info(className +"|" +arg0);
+       }
+
+       /**
+        * Records an audit message 
+        * @param eventId
+        */     
+       @Override
+       public void recordAuditEventStart(String eventId) {
+               log.info(className +"|recordAuditEventStart with eventId " + eventId);
+       }
+
+       /**
+        * Records an audit message 
+        * @param eventId
+        */     
+       @Override
+       public void recordAuditEventStart(UUID eventId) {
+               if(eventId != null){
+                  recordAuditEventStart(eventId.toString());   
+               }
+       }
+
+       /**
+        * Records an audit message 
+        * @param eventId
+        * @param rule
+        * @param policyVersion
+        */
+       @Override
+       public void recordAuditEventEnd(String eventId, String rule, String policyVersion) {            
+               log.info(className +"|"+ eventId + ":" + rule);
+       }
+
+       /**
+        * Records an audit message 
+        * @param eventId
+        * @param rule
+        * @param policyVersion
+        */     
+       @Override
+       public void recordAuditEventEnd(UUID eventId, String rule, String policyVersion) {
+               if(eventId != null){
+                       recordAuditEventEnd(eventId.toString(), rule, policyVersion);
+               }else{
+                       recordAuditEventEnd(eventId, rule, policyVersion);
+               }
+       }
+
+       /**
+        * Records an audit message 
+        * @param eventId
+        * @param rule
+        */     
+       @Override
+       public void recordAuditEventEnd(String eventId, String rule) {          
+               log.info(className +"|" +eventId + ":" + rule);
+       }
+
+       /**
+        * Records an audit message 
+        * @param eventId
+        * @param rule
+        */     
+       @Override
+       public void recordAuditEventEnd(UUID eventId, String rule) {
+               if(eventId != null){
+                       recordAuditEventEnd(eventId.toString(), rule);
+               }else{
+                       recordAuditEventEnd(eventId, rule);
+               }
+       }
+
+       /**
+        * Records a metrics message 
+        * @param eventId
+        * @param arg1
+        */     
+       @Override
+       public void recordMetricEvent(String eventId, String arg1) {            
+               log.info(className +"|" +eventId + ":" + arg1);
+               
+       }
+
+       /**
+        * Records a metrics message 
+        * @param eventId
+        * @param arg1
+        */     
+       @Override
+       public void recordMetricEvent(UUID eventId, String arg1) {              
+               if(eventId != null){
+                       recordMetricEvent(eventId.toString(), arg1);
+               }else{
+                       recordMetricEvent(eventId, arg1);
+               }               
+       }
+
+       /**
+        * Records a metrics message 
+        * @param arg0
+        */     
+       @Override
+       public void metrics(Object arg0) {              
+               log.info(arg0);
+       }
+
+       /**
+        * Records an error message 
+        * @param msg
+        * @param arg0
+        * @param arguments
+        */             
+       @Override
+       public void error(MessageCodes msg, Throwable arg0, String... arguments){
+               log.error(transId + "|" + className +"|" + "MessageCodes :" + msg + arguments);
+
+       }
+       
+       /**
+        * Records an error message 
+        * @param msg
+        * @param arguments
+        */             
+       @Override
+       public void error(MessageCodes msg, String... arguments){               
+               log.error(transId + "|" + className +"|" + "MessageCode:" + msg + arguments);
+       }
+       
+       /**
+        * Returns transaction Id 
+        * @param transId
+        */     
+       @Override
+       public String postMDCInfoForEvent(String transId) {             
+               if(transId == null || transId.isEmpty()){
+                       transId = UUID.randomUUID().toString();
+               }
+               
+           return transId;
+       }
+       
+       /**
+        * Records a message 
+        * @param msg
+        * @param arguments
+        */
+    @Override
+       public void warn(MessageCodes msg, String... arguments){        
+       log.warn(className +"|" +"MessageCodes:" + msg + arguments);
+    }
+
+       /**
+        * Records a message 
+        * @param msg
+        * @param arg0
+        * @param arguments
+        */
+    @Override
+       public void warn(MessageCodes msg, Throwable arg0, String... arguments){
+       log.warn(className +"|" +"MessageCodes:" + msg + arguments);            
+    }
+
+       /**
+        * Records a message
+        * @param message
+        * @param t
+        */
+       @Override
+       public void debug(Object message, Throwable t) {
+               log.debug(message, t);          
+       }
+
+       /**
+        * Records an error message
+        * @param message
+        * @param t
+        */
+       @Override
+       public void error(Object message, Throwable t) {
+               log.error(message, t);
+       }
+
+       /**
+        * Records a message 
+        * @param message
+        * @param t
+        */
+       @Override
+       public void info(Object message, Throwable t) {
+               log.info(message, t);
+       }
+
+       /**
+        * Records a message 
+        * @param message
+        * @param t
+        */
+       @Override
+       public void warn(Object message, Throwable t) {
+               log.warn(message, t);
+       }
+
+       /**
+        * Records a message 
+        * @param message
+        * @param t
+        */
+       @Override
+       public void trace(Object message, Throwable t) {
+               log.trace(message, t);
+       }
+       
+       /**
+        * Records an audit message 
+        * @param arg0
+        * @param t
+        */
+
+       @Override
+       public void audit(Object arg0, Throwable t) {
+               log.info(arg0, t);
+       }
+
+       /**
+        * Returns true for trace enabled, or false for not
+        * @return boolean
+        */
+       @Override
+       public boolean isTraceEnabled() {
+               return log.isTraceEnabled();
+       }
+       
+       /**
+        * Records transaction Id
+        * @param transId
+        */
+    @Override
+    public void postMDCInfoForTriggeredRule(String transId){           
+       log.info(transId);
+    }
+    
+       /**
+        * Records transaction Id
+        * @param o
+        */      
+    @Override
+       public void postMDCInfoForEvent(Object o){
+       log.info(o);
+       }
+}
diff --git a/common-logging/src/main/java/org/openecomp/policy/common/logging/flexlogger/LoggerType.java b/common-logging/src/main/java/org/openecomp/policy/common/logging/flexlogger/LoggerType.java
new file mode 100644 (file)
index 0000000..8fe55b2
--- /dev/null
@@ -0,0 +1,30 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP-Logging
+ * ================================================================================
+ * 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.logging.flexlogger;
+
+/**
+ * 
+ * Logger types
+ *
+ */
+public enum LoggerType {
+       EELF, LOG4J, SYSTEMOUT
+}
diff --git a/common-logging/src/main/java/org/openecomp/policy/common/logging/flexlogger/PropertyUtil.java b/common-logging/src/main/java/org/openecomp/policy/common/logging/flexlogger/PropertyUtil.java
new file mode 100644 (file)
index 0000000..462e10c
--- /dev/null
@@ -0,0 +1,403 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP-Logging
+ * ================================================================================
+ * 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.logging.flexlogger;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.Properties;
+import java.util.Set;
+import java.util.Timer;
+import java.util.TimerTask;
+
+/**
+ * This class provides utilities to read properties from a properties
+ * file, and optionally get notifications of future changes
+ */
+public class PropertyUtil
+{
+  /**
+   * Read in a properties file
+   * @param file the properties file
+   * @return a Properties object, containing the associated properties
+   * @throws IOException - subclass 'FileNotFoundException' if the file
+   *   does not exist or can't be opened, and 'IOException' if there is
+   *   a problem loading the properties file.
+   */
+  static public Properties getProperties(File file) throws IOException
+  {
+       // create an InputStream (may throw a FileNotFoundException)
+       FileInputStream fis = new FileInputStream(file);
+       try
+         {
+               // create the properties instance
+               Properties rval = new Properties();
+
+               // load properties (may throw an IOException)
+               rval.load(fis);
+               return(rval);
+         }
+       finally
+         {
+               // close input stream
+               fis.close();
+         }
+  }
+
+  /**
+   * Read in a properties file
+   * @param fileName the properties file
+   * @return a Properties object, containing the associated properties
+   * @throws IOException - subclass 'FileNotFoundException' if the file
+   *   does not exist or can't be opened, and 'IOException' if there is
+   *   a problem loading the properties file.
+   */
+  static public Properties getProperties(String fileName) throws IOException
+  {
+       return(getProperties(new File(fileName)));
+  }
+
+  /* ============================================================ */
+
+  // timer thread used for polling for property file changes
+  private static Timer timer = null;
+
+  /**
+   * This is the callback interface, used for sending notifications of
+   * changes in the properties file.
+   */
+  public interface Listener
+  {
+       /**
+        * Notification of a properties file change
+        * @param properties the new properties
+        * @param the set of property names that have changed, including
+        *              additions and removals
+        */
+       void propertiesChanged(Properties properties, Set<String> changedKeys);
+  }
+
+  // this table maps canonical file into a 'ListenerRegistration' instance
+  static private HashMap<File, ListenerRegistration> registrations =
+       new HashMap<File, ListenerRegistration>();
+
+  /**
+   * This is an internal class - one instance of this exists for each
+   * property file that is being monitored. Note that multiple listeners
+   * can be registered for the same file.
+   */
+  private static class ListenerRegistration
+  {
+       // the canonical path of the file being monitored
+       File file;
+
+       // the most recent value of 'file.lastModified()'
+       long lastModified;
+
+       // the most recent set of properties
+       Properties properties;
+
+       // the set of listeners monitoring this file
+       LinkedList<Listener> listeners;
+
+       // the 'TimerTask' instance, used for periodic polling
+       TimerTask timerTask;
+
+       /**
+        * Constructor - create a 'ListenerRegistration' instance for this
+        * file, but with no listeners
+        */
+       ListenerRegistration(File file) throws IOException
+       {
+         this.file = file;
+
+         // The initial value of 'lastModified' is set to 0 to ensure that we
+         // correctly handle the case where the file is modified within the
+         // same second that polling begins.
+         lastModified = 0;
+
+         // fetch current properties
+         properties = getProperties(file);
+
+         // no listeners yet
+         listeners = new LinkedList<Listener>();
+
+         // add to static table, so this instance can be shared
+         registrations.put(file, this);
+
+         if (timer == null)
+               {
+                 // still need to create a timer thread
+                 synchronized(PropertyUtil.class)
+                       {
+                         // an additional check is added inside the 'synchronized' block,
+                         // just in case someone beat us to it
+                         if (timer == null)
+                               {
+                                 timer = new Timer("PropertyUtil-Timer", true);
+                               }
+                       }
+               }
+
+         // create and schedule the timer task, so this is periodically polled
+         timerTask = new TimerTask()
+               {
+                 public void run()
+                 {
+                       try
+                         {
+                               poll();
+                         }
+                       catch (Exception e)
+                         {
+                               System.err.println(e);
+                         }
+                 }
+               };
+         timer.schedule(timerTask, 10000L, 10000L);
+       }
+
+       /**
+        * Add a listener to the notification list
+        * @param listener this is the listener to add to the list
+        * @return the properties at the moment the listener was added to the list
+        */
+       synchronized Properties addListener(Listener listener)
+       {
+         listeners.add(listener);
+         return((Properties)properties.clone());
+       }
+
+       /**
+        * Remove a listener from the notification list
+        * @param listener this is the listener to remove
+        */
+       synchronized void removeListener(Listener listener)
+       {
+         listeners.remove(listener);
+
+         // See if we need to remove this 'ListenerRegistration' instance
+         // from the table. The 'synchronized' block is needed in case
+         // another listener is being added at about the same time that this
+         // one is being removed.
+         synchronized(registrations)
+               {
+                 if (listeners.size() == 0)
+                       {
+                         timerTask.cancel();
+                         registrations.remove(file);
+                       }
+               }
+       }
+
+       /**
+        * This method is periodically called to check for property list updates
+        * @throws IOException if there is an error in reading the properties file
+        */
+       synchronized void poll() throws IOException
+       {
+         long timestamp = file.lastModified();
+         if (timestamp != lastModified)
+               {
+                 // update the record, and send out the notifications
+                 lastModified = timestamp;
+
+                 // Save old set, and initial set of changed properties.
+                 Properties oldProperties = properties;
+                 HashSet<String> changedProperties =
+                       new HashSet<String>(oldProperties.stringPropertyNames());
+
+                 // Fetch the list of listeners that we will potentially notify,
+                 // and the new properties. Note that this is in a 'synchronized'
+                 // block to ensure that all listeners receiving notifications
+                 // actually have a newer list of properties than the one
+                 // returned on the initial 'getProperties' call.
+                 properties = getProperties(file);
+                 
+                 Set<String> newPropertyNames = properties.stringPropertyNames();
+                 changedProperties.addAll(newPropertyNames);
+
+                 // At this point, 'changedProperties' is the union of all properties
+                 // in both the old and new properties files. Iterate through all
+                 // of the entries in the new properties file - if the entry
+                 // matches the one in the old file, remove it from
+                 // 'changedProperties'.
+                 for (String name : newPropertyNames)
+                       {
+                         if (properties.getProperty(name).equals
+                                 (oldProperties.getProperty(name)))
+                               {
+                                 // Apparently, any property that exists must be of type
+                                 // 'String', and can't be null. For this reason, we don't
+                                 // need to worry about the case where
+                                 // 'properties.getProperty(name)' returns 'null'. Note that
+                                 // 'oldProperties.getProperty(name)' may be 'null' if the
+                                 // old property does not exist.
+                                 changedProperties.remove(name);
+                               }
+                       }
+
+                 // 'changedProperties' should be correct at this point
+                 if (changedProperties.size() != 0)
+                       {
+                         // there were changes - notify everyone in 'listeners'
+                         for (final Listener notify : listeners)
+                               {
+                                 // Copy 'properties' and 'changedProperties', so it doesn't
+                                 // cause problems if the recipient makes changes.
+                                 final Properties tmpProperties =
+                                       (Properties)(properties.clone());
+                                 final HashSet<String> tmpChangedProperties =
+                                       new HashSet<String>(changedProperties);
+
+                                 // Do the notification in a separate thread, so blocking
+                                 // won't cause any problems.
+                                 new Thread()
+                                 {
+                                       public void run()
+                                       {
+                                         notify.propertiesChanged
+                                               (tmpProperties, tmpChangedProperties);
+                                       }
+                                 }.start();
+                               }
+                       }
+               }
+       }
+  }
+
+  /**
+   * Read in a properties file, and register for update notifications.
+   * NOTE: it is possible that the first callback will occur while this
+   * method is still in progress. To avoid this problem, use 'synchronized'
+   * blocks around this invocation and in the callback -- that will ensure
+   * that the processing of the initial properties complete before any
+   * updates are processed.
+   *
+   * @param file the properties file
+   * @param notify if not null, this is a callback interface that is used for
+   *   notifications of changes
+   * @return a Properties object, containing the associated properties
+   * @throws IOException - subclass 'FileNotFoundException' if the file
+   *   does not exist or can't be opened, and 'IOException' if there is
+   *   a problem loading the properties file.
+   */
+  static public Properties getProperties(File file, Listener listener)
+       throws IOException
+  {
+       if (listener == null)
+         {
+               // no listener specified -- just fetch the properties
+               return(getProperties(file));
+         }
+
+       // Convert the file to a canonical form in order to avoid the situation
+       // where different names refer to the same file.
+       file = file.getCanonicalFile();
+
+       // See if there is an existing registration. The 'synchronized' block
+       // is needed to handle the case where a new listener is added at about
+       // the same time that another one is being removed.
+       synchronized(registrations)
+         {
+               ListenerRegistration reg = registrations.get(file);
+               if (reg == null)
+                 {
+                       // a new registration is needed
+                       reg = new ListenerRegistration(file);
+                 }
+               return(reg.addListener(listener));
+         }
+  }
+
+  /**
+   * Read in a properties file, and register for update notifications.
+   * NOTE: it is possible that the first callback will occur while this
+   * method is still in progress. To avoid this problem, use 'synchronized'
+   * blocks around this invocation and in the callback -- that will ensure
+   * that the processing of the initial properties complete before any
+   * updates are processed.
+   *
+   * @param fileName the properties file
+   * @param notify if not null, this is a callback interface that is used for
+   *   notifications of changes
+   * @return a Properties object, containing the associated properties
+   * @throws IOException - subclass 'FileNotFoundException' if the file
+   *   does not exist or can't be opened, and 'IOException' if there is
+   *   a problem loading the properties file.
+   */
+  static public Properties getProperties(String fileName, Listener listener)
+       throws IOException
+  {
+       return(getProperties(new File(fileName), listener));
+  }
+
+  /**
+   * Stop listenening for updates
+   * @param file the properties file
+   * @param notify if not null, this is a callback interface that was used for
+   *   notifications of changes
+   */
+  static public void stopListening(File file, Listener listener)
+  {
+       if (listener != null)
+         {
+               ListenerRegistration reg = registrations.get(file);
+               if (reg != null)
+                 {
+                       reg.removeListener(listener);
+                 }
+         }
+  }
+
+  /**
+   * Stop listenening for updates
+   * @param fileName the properties file
+   * @param notify if not null, this is a callback interface that was used for
+   *   notifications of changes
+   */
+  static public void stopListening(String fileName, Listener listener)
+  {
+       stopListening(new File(fileName), listener);
+  }
+
+  /* ============================================================ */
+
+  // TEMPORARY - used to test callback interface
+  static public class Test implements Listener
+  {
+       String name;
+
+       public Test(String name)
+         {
+               this.name = name;
+         }
+
+       public void propertiesChanged(Properties properties, Set<String> changedKeys)
+         {
+               System.out.println("Test(" + name + ")\nproperties = " + properties
+                                                  + "\nchangedKeys = " + changedKeys);
+         }
+  }
+} 
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
new file mode 100644 (file)
index 0000000..26f0664
--- /dev/null
@@ -0,0 +1,497 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP-Logging
+ * ================================================================================
+ * 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.logging.flexlogger;
+
+import java.util.UUID;
+
+import org.openecomp.policy.common.logging.eelf.MessageCodes;
+import org.openecomp.policy.common.logging.eelf.PolicyLogger;
+import com.att.eelf.configuration.EELFLogger.Level;
+
+/**
+ * 
+ * SystemOutLogger implements all the methods of interface Logger by calling System.out.println
+ *
+ */
+public class SystemOutLogger implements Logger {
+       
+       private String className = "";
+       private boolean isDebugEnabled = true;
+       private boolean isInfoEnabled = true;
+       private boolean isWarnEnabled = true;
+       private boolean isErrorEnabled = true;
+       private boolean isAuditEnabled = true;
+       private boolean isMetricsEnabled = true;        
+       private String transId = UUID.randomUUID().toString();
+
+    /**
+     * Constructor
+     * @param clazz
+     */
+       public SystemOutLogger (Class clazz){
+               System.out.println("create instance of SystemOutLogger");
+               if(clazz != null){
+                       className = clazz.getName();
+               }
+        initLevel();
+       }
+       
+    /**
+     * Constructor
+     * @param s
+     */
+       public SystemOutLogger (String s){
+               System.out.println("create instance of SystemOutLogger");
+               if(s != null){
+                       className = s;
+               }
+        initLevel();
+       }
+       
+       /**
+        * Sets logging levels
+        */
+       private void initLevel(){
+               
+               if(PolicyLogger.DEBUG_LEVEL != null && PolicyLogger.DEBUG_LEVEL.toString().equals(Level.DEBUG.toString())){
+                       isDebugEnabled = true;
+                       isInfoEnabled = true;
+                       isWarnEnabled = true;
+               }else{
+                       isDebugEnabled = false;
+               }
+               
+               if(PolicyLogger.DEBUG_LEVEL != null && PolicyLogger.DEBUG_LEVEL.toString().equals(Level.INFO.toString())){
+                       isInfoEnabled = true;
+                       isWarnEnabled = true;
+                       isDebugEnabled = false;
+               }
+               
+               if(PolicyLogger.DEBUG_LEVEL != null && PolicyLogger.DEBUG_LEVEL.toString().equals(Level.OFF.toString())){
+                       isInfoEnabled = false;
+                       isWarnEnabled = false;
+                       isDebugEnabled = false;
+               }
+               
+               if(PolicyLogger.ERROR_LEVEL != null && PolicyLogger.ERROR_LEVEL.toString().equals(Level.OFF.toString())){
+                       isErrorEnabled = false;
+               }
+
+               if(PolicyLogger.AUDIT_LEVEL != null && PolicyLogger.AUDIT_LEVEL.toString().equals(Level.OFF.toString())){
+                       isAuditEnabled = false;
+               }
+               
+               if(PolicyLogger.METRICS_LEVEL != null && PolicyLogger.METRICS_LEVEL.toString().equals(Level.OFF.toString())){
+                       isMetricsEnabled = false;
+               }
+       }
+       
+    /**
+     * Sets transaction Id
+     */
+       @Override
+       public void setTransId(String transId){
+               
+               System.out.println(transId);
+               this.transId = transId;
+       }
+       
+    /**
+     * Returns transaction Id
+     */
+       @Override
+       public String getTransId(){
+               
+               return transId;
+       }
+       
+       /**
+        * Records a message
+        * @param message
+        */
+       @Override
+       public void debug(Object message) {
+
+               System.out.println(transId + "|" + className+" : "+message);
+       }
+
+       /**
+        * Records an error message
+        * @param message
+        */
+       @Override
+       public void error(Object message) {
+
+               System.out.println(transId + "|" + className+" : "+message);
+       }
+
+       /**
+        * Records a message
+        * @param message
+        */
+       @Override
+       public void info(Object message) {
+       
+               System.out.println(transId + "|" + className+" : "+message);
+
+       }
+
+       /**
+        * Records a message
+        * @param message
+        */
+       @Override
+       public void warn(Object message) {
+
+               System.out.println(transId + "|" + className+" : "+message);
+       }
+
+       /**
+        * Records a message
+        * @param message
+        */
+       @Override
+       public void trace(Object message) {
+               
+               System.out.println(transId + "|" + className+" : "+message);
+       }
+       
+       /**
+        * Returns true for debug enabled, or false for not
+        * @return boolean
+        */
+       @Override
+       public boolean isDebugEnabled(){
+               
+               return isDebugEnabled;
+       }       
+       
+       /**
+        * Returns true for warn enabled, or false for not
+        * @return boolean
+        */
+       @Override
+       public boolean isWarnEnabled(){
+
+               return isWarnEnabled;
+       }
+       
+       /**
+        * Returns true for info enabled, or false for not
+        * @return boolean
+        */
+       @Override
+       public boolean isInfoEnabled(){
+
+               return isInfoEnabled;
+       }
+       
+       /**
+        * Returns true for error enabled, or false for not
+        * @return boolean
+        */
+       @Override
+       public boolean isErrorEnabled(){
+
+               return isErrorEnabled;
+       }
+       
+       /**
+        * Returns true for audit enabled, or false for not
+        * @return boolean
+        */
+       @Override
+       public boolean isAuditEnabled(){
+
+               return isAuditEnabled;
+       }
+       
+       /**
+        * Returns true for metrics enabled, or false for not
+        * @return boolean
+        */
+       @Override
+       public boolean isMetricsEnabled(){
+
+               return isMetricsEnabled;
+       }
+
+       /**
+        * Records an audit message
+        * @param arg0
+        */
+       @Override
+       public void audit(Object arg0) {
+
+               System.out.println(transId + "|" +className+" : "+arg0);
+       }
+
+       /**
+        * Records an audit message 
+        * @param eventId
+        */
+       @Override
+       public void recordAuditEventStart(String eventId) {
+
+               System.out.println(transId + "|" +className+" : "+eventId);
+               
+       }
+
+       /**
+        * Records an audit message 
+        * @param eventId
+        */
+       @Override
+       public void recordAuditEventStart(UUID eventId) {
+
+               System.out.println(eventId);
+       }
+
+       /**
+        * Records an audit message 
+        * @param eventId
+        * @param rule
+        * @param policyVersion
+        */
+       @Override
+       public void recordAuditEventEnd(String eventId, String rule, String policyVersion) {
+
+               System.out.println(className+" : "+eventId  + ":" + rule + ":" + policyVersion);
+       }
+
+       /**
+        * Records an audit message 
+        * @param eventId
+        * @param rule
+        * @param policyVersion
+        */     
+       @Override
+       public void recordAuditEventEnd(UUID eventId, String rule, String policyVersion) {              
+               
+               System.out.println(className+" : "+eventId  + ":" + rule + ":" + policyVersion);                
+       }
+
+       /**
+        * Records an audit message 
+        * @param eventId
+        * @param rule
+        */     
+       @Override
+       public void recordAuditEventEnd(String eventId, String rule) {
+
+               System.out.println(className+" : "+eventId  + ":" + rule);
+       }
+
+       /**
+        * Records an audit message 
+        * @param eventId
+        * @param rule
+        */     
+       @Override
+       public void recordAuditEventEnd(UUID eventId, String rule) {            
+               
+               System.out.println(className+" : "+eventId  + ":" + rule);              
+       }       
+       
+       /**
+        * Records a metrics message 
+        * @param eventId
+        * @param arg1
+        */     
+       @Override
+       public void recordMetricEvent(String eventId, String arg1) {
+               
+               System.out.println(className+" : "+"eventId:" + ":" + eventId + "message:" + arg1);     
+               
+       }
+
+       /**
+        * Records a metrics message 
+        * @param eventId
+        * @param arg1
+        */             
+       @Override
+       public void recordMetricEvent(UUID eventId, String arg1) {
+
+               System.out.println(className+" : "+eventId  + ":" + arg1);
+       }
+
+       /**
+        * Records a metrics message 
+        * @param arg0
+        */     
+       @Override
+       public void metrics(Object arg0) {
+
+               System.out.println(className+" : "+arg0);               
+       }
+       
+       /**
+        * Records an error message 
+        * @param msg
+        * @param arg0
+        * @param arguments
+        */             
+       @Override
+       public void error(MessageCodes msg, Throwable arg0, String... arguments){
+
+               System.out.println(className+" : "+"MessageCodes :" + msg + arguments);
+
+       }
+       
+       /**
+        * Records an error message 
+        * @param msg
+        * @param arguments
+        */     
+       @Override
+       public void error(MessageCodes msg, String... arguments){
+               
+               System.out.println(transId + "|" + className+" : "+"MessageCode:" + msg + arguments);
+       }
+       
+       /**
+        * Returns transaction Id
+        * @param transId
+        */
+       @Override
+       public String postMDCInfoForEvent(String transId) {
+               
+               if(transId == null || transId.isEmpty()){
+                       transId = UUID.randomUUID().toString();
+               }
+               
+           return transId;
+       }
+       
+       /**
+        * Records a message 
+        * @param msg
+        * @param arguments
+        */
+    @Override
+       public void warn(MessageCodes msg, String... arguments){
+       
+       System.out.println(transId + "|" + className+" : "+"MessageCodes:" + msg + arguments);
+    }
+
+       /**
+        * Records a message 
+        * @param msg
+        * @param arg0
+        * @param arguments
+        */
+    @Override
+       public void warn(MessageCodes msg, Throwable arg0, String... arguments){
+       
+       System.out.println(transId + "|" + className+" : "+"MessageCodes:" + msg + arguments);
+       
+    }
+
+       /**
+        * Records a message 
+        * @param message
+        * @param t
+        */
+       @Override
+       public void debug(Object message, Throwable t) {
+               System.out.println(transId + "|" + className+" : "+ message + ":" + t);
+       }
+
+       /**
+        * Records an error message
+        * @param message
+        * @param t
+        */
+       @Override
+       public void error(Object message, Throwable t) {
+               System.out.println(transId + "|" + className+" : "+ message + ":" + t);
+       }
+
+       /**
+        * Records a message
+        * @param message
+        * @param t
+        */
+       @Override
+       public void info(Object message, Throwable t) {
+               System.out.println(transId + "|" + className+" : "+ message + ":" + t);
+       }
+
+       /**
+        * Records a message
+        * @param message
+        * @param t
+        */
+       @Override
+       public void warn(Object message, Throwable t) {
+               System.out.println(transId + "|" + className+" : "+ message + ":" + t);
+       }
+
+       /**
+        * Records a message
+        * @param message
+        * @param t
+        */
+       @Override
+       public void trace(Object message, Throwable t) {
+               System.out.println(transId + "|" + className+" : "+ message + ":" + t);
+       }
+       
+       /**
+        * Records an audit message 
+        * @param arg0
+        * @param t
+        */
+       @Override
+       public void audit(Object arg0, Throwable t) {
+               System.out.println(transId + "|" + className+" : "+ arg0 + ":" + t);
+       }
+       
+       /**
+        * Returns true for trace enabled, or false for not
+        * @return boolean
+        */
+       @Override
+       public boolean isTraceEnabled() {
+               // default
+               return false;
+       }
+       
+       /**
+        * Records transaction Id
+        * @param transId
+        */
+    @Override
+    public void postMDCInfoForTriggeredRule(String transId){
+       
+       System.out.println(transId);
+    }
+    
+       /**
+        * Records transaction Id
+        * @param o
+        */
+    @Override
+       public void postMDCInfoForEvent(Object o){
+       System.out.println(o);
+       }
+}
diff --git a/common-logging/src/main/java/org/openecomp/policy/common/logging/nsa/LoggingContext.java b/common-logging/src/main/java/org/openecomp/policy/common/logging/nsa/LoggingContext.java
new file mode 100644 (file)
index 0000000..56f6686
--- /dev/null
@@ -0,0 +1,61 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP-Logging
+ * ================================================================================
+ * 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.logging.nsa;
+
+/**
+ * An interface for providing data into the underlying logging context.  Systems should use
+ * this interface rather than log system specific MDC solutions in order to reduce dependencies.
+ * 
+ * A LoggingContext is specific to the calling thread.
+ * 
+ */
+public interface LoggingContext
+{
+       /**
+        * Put a key/value pair into the logging context, replacing an entry with the same key.
+        * @param key
+        * @param value
+        */
+       void put ( String key, String value );
+
+       /**
+        * Put a key/value pair into the logging context, replacing an entry with the same key.
+        * @param key
+        * @param value
+        */
+       void put ( String key, long value );
+
+       /**
+        * Get a string value, returning the default value if the value is missing.
+        * @param key
+        * @param defaultValue
+        * @return a string value
+        */
+       String get ( String key, String defaultValue );
+       
+       /**
+        * Get a long value, returning the default value if the value is missing or not a long.
+        * @param key
+        * @param defaultValue
+        * @return a long value
+        */
+       long get ( String key, long defaultValue );
+}
diff --git a/common-logging/src/main/java/org/openecomp/policy/common/logging/nsa/LoggingContextFactory.java b/common-logging/src/main/java/org/openecomp/policy/common/logging/nsa/LoggingContextFactory.java
new file mode 100644 (file)
index 0000000..b8fce10
--- /dev/null
@@ -0,0 +1,55 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP-Logging
+ * ================================================================================
+ * 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.logging.nsa;
+
+
+import org.openecomp.policy.common.logging.nsa.impl.SharedContext;
+import org.openecomp.policy.common.logging.nsa.impl.Slf4jLoggingContext;
+
+/**
+ * A factory for setting up a LoggingContext
+ * 
+ */
+public class LoggingContextFactory
+{
+       public static class Builder
+       {
+               public Builder withBaseContext ( LoggingContext lc )
+               {
+                       fBase = lc;
+                       return this;
+               }
+
+               public Builder forSharing ()
+               {
+                       fShared = true;
+                       return this;
+               }
+
+               public LoggingContext build ()
+               {
+                       return fShared ? new SharedContext ( fBase ) : new Slf4jLoggingContext ( fBase );
+               }
+
+               private LoggingContext fBase = null;
+               private boolean fShared = false;
+       }
+}
diff --git a/common-logging/src/main/java/org/openecomp/policy/common/logging/nsa/SharedLoggingContext.java b/common-logging/src/main/java/org/openecomp/policy/common/logging/nsa/SharedLoggingContext.java
new file mode 100644 (file)
index 0000000..2ecbcb0
--- /dev/null
@@ -0,0 +1,37 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP-Logging
+ * ================================================================================
+ * 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.logging.nsa;
+
+/**
+ * A logging context must be thread-specific. Contexts that implement SharedLoggingContext
+ * are expected to be shared across threads, and they have to be able to populate another
+ * logging context with their data.
+ * 
+ */
+public interface SharedLoggingContext extends LoggingContext
+{
+       /**
+        * Copy this context's data to the given context. This must work across threads so that
+        * a base context can be shared in another thread.
+        * @param lc
+        */
+       void transferTo ( SharedLoggingContext lc );
+}
diff --git a/common-logging/src/main/java/org/openecomp/policy/common/logging/nsa/impl/SharedContext.java b/common-logging/src/main/java/org/openecomp/policy/common/logging/nsa/impl/SharedContext.java
new file mode 100644 (file)
index 0000000..96ffbf6
--- /dev/null
@@ -0,0 +1,58 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP-Logging
+ * ================================================================================
+ * 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.logging.nsa.impl;
+
+import java.util.HashMap;
+import java.util.Map.Entry;
+
+import org.openecomp.policy.common.logging.nsa.LoggingContext;
+import org.openecomp.policy.common.logging.nsa.SharedLoggingContext;
+
+/**
+ * A shared logging context for SLF4J
+ *
+ */
+public class SharedContext extends Slf4jLoggingContext implements SharedLoggingContext
+{
+       public SharedContext ( LoggingContext base )
+       {
+               super ( base );
+               fMap = new HashMap<String,String> ();
+       }
+
+       @Override
+       public void put ( String key, String value )
+       {
+               super.put ( key, value );
+               fMap.put ( key, value );
+       }
+
+       @Override
+       public void transferTo ( SharedLoggingContext lc )
+       {
+               for ( Entry<String,String> e : fMap.entrySet () )
+               {
+                       lc.put ( e.getKey(), e.getValue() );
+               }
+       }
+
+       private final HashMap<String,String> fMap;
+}
diff --git a/common-logging/src/main/java/org/openecomp/policy/common/logging/nsa/impl/Slf4jLoggingContext.java b/common-logging/src/main/java/org/openecomp/policy/common/logging/nsa/impl/Slf4jLoggingContext.java
new file mode 100644 (file)
index 0000000..de31af9
--- /dev/null
@@ -0,0 +1,71 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP-Logging
+ * ================================================================================
+ * 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.logging.nsa.impl;
+
+import org.slf4j.MDC;
+
+import org.openecomp.policy.common.logging.nsa.LoggingContext;
+
+/**
+ * A logging context for SLF4J
+ *
+ */
+public class Slf4jLoggingContext implements LoggingContext
+{
+       public Slf4jLoggingContext ( LoggingContext base )
+       {
+       }
+
+       @Override
+       public void put ( String key, String value )
+       {
+               MDC.put ( key, value );
+       }
+
+       public void put ( String key, long value )
+       {
+               put ( key, "" + value );
+       }
+
+       
+       public String get ( String key, String defaultValue )
+       {
+               String result = MDC.get ( key );
+               if ( result == null )
+               {
+                       result = defaultValue;
+               }
+               return result;
+       }
+
+       public long get ( String key, long defaultValue )
+       {
+               final String str = get ( key, "" + defaultValue );
+               try
+               {
+                       return Long.parseLong ( str );
+               }
+               catch ( NumberFormatException x )
+               {
+                       return defaultValue;
+               }
+       }
+}
diff --git a/common-logging/src/main/java/org/openecomp/policy/common/logging/nsa/package-info.java b/common-logging/src/main/java/org/openecomp/policy/common/logging/nsa/package-info.java
new file mode 100644 (file)
index 0000000..e1ef710
--- /dev/null
@@ -0,0 +1,27 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP-Logging
+ * ================================================================================
+ * 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=========================================================
+ */
+
+/**
+ * This package provides a logging context infrastructure and a corresponding
+ * implementation based on the SLF4J/Log4j "MDC" (Mapped Diagnostic Context) feature.
+ * 
+ */
+package org.openecomp.policy.common.logging.nsa;
+
diff --git a/common-logging/src/main/resources/org/openecomp/policy/common/logging/eelf/Resources.properties b/common-logging/src/main/resources/org/openecomp/policy/common/logging/eelf/Resources.properties
new file mode 100644 (file)
index 0000000..c79061b
--- /dev/null
@@ -0,0 +1,245 @@
+###
+# ============LICENSE_START=======================================================
+# ECOMP-Logging
+# ================================================================================
+# 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=========================================================
+###
+
+#Resource key=Error Code|Message text|Resolution text |Description text
+#######
+# {APP}-{4-digit}{classification}
+
+#Newlines can be utilized to add some clarity ensuring continuing line
+#has atleast one leading space
+#ResourceKey=\
+#             ERR0000E\
+#             Sample error msg txt\
+#             Sample resolution msg\
+#             Sample description txt
+#
+######
+#Error code classification category
+#100-199       Permission/Security Related
+#200-299       Availability/Timeout Related
+#300-399       Data Access/Integrity Related
+#400-499       Schema Interface type/validation Related
+#500-599       Business/Flow Processing Related
+#900-999       Unknown errors
+#
+#{classification} description
+# I = Information
+# W = Warning
+# E = Error
+# F = Fatal
+
+########################################################################
+
+GENERAL_INFO=\
+             POLICY-500I|\
+             INFO: {0}|\
+             No resolution needed|\
+             General flow processing info
+GENERAL_WARNING=\
+             POLICY-501W|\
+             WARNING: {0}|\
+             Please check other logs for more information|\
+             General warning   
+UPDATE_ERROR=\
+             POLICY-502E|\
+             ERROR: Could not update {0}|\
+             Please check other logs for more information|\
+             Exception caught during server management         
+            
+EXCEPTION_ERROR=\
+             POLICY-503E|\
+             ERROR: Error Message: {0}|\
+             Please check other logs for more information|\
+             Exception caught during server management
+             
+MISS_PROPERTY_ERROR=\
+             POLICY-504E|\
+             ERROR: {0} property not set in {1}.properties|\
+             Please check other logs for more information|\
+             Exception caught during server management  
+                        
+BAD_TYPE_WARNING=\
+             POLICY-505W|\
+             WARNING: Bad types for Double Metric: {0} path: {1}|\
+             Please check other logs for more information|\
+             General warning 
+             
+MISS_PROPERTY_INFO=\
+             POLICY-506I|\
+             INFO: report: {0} not set|\
+             No resolution needed|\
+             General flow processing info
+             
+RULE_AUDIT_EXEC_INFO=\
+             POLICY-507I|\
+             Service Name: {0}:Executing rule: {1}|\
+             No resolution needed|\
+             Executing method     
+
+RULE_AUDIT_BEGIN_INFO=\
+             POLICY-508I|\
+             Service Name: {0}:Entering rule: {1}|\
+             No resolution needed|\
+             Entering method
+             
+RULE_AUDIT_END_INFO=\
+             POLICY-509I|\
+             Service Name: {0}:Exiting rule: {1}|\
+             No resolution needed|\
+             Exiting method                
+              
+RULE_METRICS_INFO=\
+             POLICY-510I|\
+             Service Name: {0}:Executing method: {1}|\
+             No resolution needed|\
+             Generate information for Metric events   
+
+UEB_AUDIT_EXEC_INFO=\
+             POLICY-511I|\
+             Service Name: {0}:Executing UEB: {1}|\
+             No resolution needed|\
+             Executing method     
+
+UEB_AUDIT_BEGIN_INFO=\
+             POLICY-512I|\
+             Service Name: {0}:Entering UEB: {1}|\
+             No resolution needed|\
+             Entering method
+                          
+UEB_AUDIT_END_INFO=\
+             POLICY-513I|\
+             Service Name: {0}:Exiting UEB: {1}|\
+             No resolution needed|\
+             Exiting method  
+             
+             
+             
+RULE_AUDIT_START_END_INFO=\
+             POLICY-514I|\
+             Service Name: {0}:Executing rule:{1}:Starting Time:{2}:Ending Time:{3}:Executing Time:{4}:Policy version:{5}|\
+             No resolution needed|\
+             Executing method 
+             
+GENERAL_ERROR=\
+             POLICY-515E|\
+             ERROR: {0}|\
+             Please check other logs for more information|\
+             error caught during server management  
+             
+ERROR_SYSTEM_ERROR=\
+             POLICY-516E|\
+             ERROR: {0}|\
+             Please check other logs for more information|\
+             error caught during server management  
+             
+ERROR_DATA_ISSUE=\
+             POLICY-517E|\
+             ERROR: {0}|\
+             Please check other logs for more information|\
+             error caught during server management 
+             
+ERROR_PERMISSIONS=\
+             POLICY-100E|\
+             ERROR: {0}|\
+             Please check other logs for more information|\
+             error caught during server management 
+             
+ERROR_PROCESS_FLOW=\
+             POLICY-518E|\
+             ERROR: {0}|\
+             Please check other logs for more information|\
+             error caught during server management 
+             
+ERROR_SCHEMA-INVALID=\
+             POLICY-400E|\
+             ERROR: {0}|\
+             Please check other logs for more information|\
+             error caught during server management 
+             
+ERROR_UNKNOWN=\
+             POLICY-519E|\
+             ERROR: {0}|\
+             Please check other logs for more information|\
+             error caught during server management   
+             
+ERROR_AUDIT=\
+             POLICY-520E|\
+             ERROR: {0}|\
+             Please check other logs for more information|\
+             error caught during audit process                       
+
+########################################################################
+########################################################################
+########################################################################             
+#---------------- The message codes below should not be used anymore since 1607 release -----------------------------
+
+MESSAGE_SAMPLE_NOARGS=\
+                  APP1234I|\
+                  App1 message text sample1|\
+                  App1 resolution text sample1|\
+                  App1 description text sample1
+                  
+MESSAGE_SAMPLE_ONEARGUMENT=\
+                  APP3456I|\
+                  App1 msg smpl w arg: {0}|\
+                  App1 resolution text sample2|\
+                  App1 description text sample2
+
+AUDIT_MESSAGE_ONEARGUMENT=\
+                  AUD0000I|\
+                  Audit msg: {0}|\
+                  Audit resolution text sample2|\
+                  Audit description text sample2   
+                  
+ERROR_MESSAGE_ONEARGUMENT=\
+                  ERR0000E|\
+                  Error msg: {0}|\
+                  Error resolution text sample2|\
+                  Error description text sample2       
+                  
+METRICS_MESSAGE_ONEARGUMENT=\
+                  MET0000I|\
+                  Metrics msg: {0}|\
+                  Metrics resolution text sample2|\
+                  Metrics description text sample2   
+                  
+DUBUG_MESSAGE_ONEARGUMENT=\
+                  DEB0000I|\
+                  Debug msg: {0}|\
+                  Debug resolution text sample2|\
+                  Debug description text sample2                                       
+MESSAGE_SAMPLE_TWOARGUMENTS=\
+                  APP4567I|\
+                  App1 message text sample with argument {0} and {1}|\
+                  App1 resolution text sample3|\
+                  App1 description text sample3
+                  
+MESSAGE_SAMPLE_EXCEPTION=\
+                  APP6789E|\
+                  App1 message text sample4|\
+                  App1 resolution text sample4|\
+                  App1 description text sample4
+                  
+MESSAGE_SAMPLE_EXCEPTION_ONEARGUMENT=\
+                  APP6790E|\
+                  This is the text exception in method {0}|\
+                  App1 resolution text sample5|\
+                  App1 description text sample5
+    
diff --git a/integrity-audit/config/policyLogger.properties b/integrity-audit/config/policyLogger.properties
new file mode 100644 (file)
index 0000000..1e7187f
--- /dev/null
@@ -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-audit/policyLogger.properties b/integrity-audit/policyLogger.properties
new file mode 100644 (file)
index 0000000..1e7187f
--- /dev/null
@@ -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-audit/pom.xml b/integrity-audit/pom.xml
new file mode 100644 (file)
index 0000000..26ffdea
--- /dev/null
@@ -0,0 +1,119 @@
+<!--
+  ============LICENSE_START=======================================================
+  ECOMP Policy Engine - Common Modules
+  ================================================================================
+  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=========================================================
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+       <modelVersion>4.0.0</modelVersion>
+
+       <groupId>org.openecomp.policy.common</groupId>
+       <artifactId>integrity-audit</artifactId>
+
+       <packaging>jar</packaging>
+
+       <parent>
+               <groupId>org.openecomp.policy.common</groupId>
+               <artifactId>common-modules</artifactId>
+               <version>1.0.0-SNAPSHOT</version>
+       </parent>
+
+       <name>Integrity Audit</name>
+
+       <dependencies>
+               <dependency>
+                       <groupId>log4j</groupId>
+                       <artifactId>log4j</artifactId>
+                       <version>1.2.17</version>
+               </dependency>
+               <dependency>
+                       <groupId>junit</groupId>
+                       <artifactId>junit</artifactId>
+                       <version>4.11</version>
+                       <scope>test</scope>
+               </dependency>
+               <dependency>
+                       <groupId>org.eclipse.persistence</groupId>
+                       <artifactId>javax.persistence</artifactId>
+                       <version>2.1.0</version>
+               </dependency>
+               <dependency>
+                       <groupId>org.eclipse.persistence</groupId>
+                       <artifactId>eclipselink</artifactId>
+                       <version>2.6.0</version>
+               </dependency>
+               <dependency>
+                       <groupId>com.h2database</groupId>
+                       <artifactId>h2</artifactId>
+                       <version>[1.4.186,)</version>
+               </dependency>
+               <!-- <dependency>
+                       <groupId>org.openecomp.policy.common</groupId>
+                       <artifactId>integrity-monitor</artifactId>
+                       <version>[1.0.0-SNAPSHOT],[1607.31.6-1,) </version>
+               </dependency> -->
+               <dependency>
+                        <groupId>org.apache.commons</groupId>
+                        <artifactId>commons-lang3</artifactId>
+                        <version>3.4</version>
+               </dependency>
+               <dependency>
+                        <groupId>org.openecomp.policy.common</groupId>
+                        <artifactId>ECOMP-Logging</artifactId>
+                        <version>${project.version}</version>
+               </dependency>
+       </dependencies>
+
+       <build>
+               <pluginManagement>
+                       <plugins>
+                               <!--This plugin's configuration is used to store Eclipse m2e settings 
+                                       only. It has no influence on the Maven build itself. -->
+                               <plugin>
+                                       <groupId>org.eclipse.m2e</groupId>
+                                       <artifactId>lifecycle-mapping</artifactId>
+                                       <version>1.0.0</version>
+                                       <configuration>
+                                               <lifecycleMappingMetadata>
+                                                       <pluginExecutions>
+                                                               <pluginExecution>
+                                                                       <pluginExecutionFilter>
+                                                                               <groupId>org.jacoco</groupId>
+                                                                               <artifactId>
+                                                                                       jacoco-maven-plugin
+                                                                               </artifactId>
+                                                                               <versionRange>
+                                                                                       [0.7.1.201405082137,)
+                                                                               </versionRange>
+                                                                               <goals>
+                                                                                       <goal>prepare-agent</goal>
+                                                                               </goals>
+                                                                       </pluginExecutionFilter>
+                                                                       <action>
+                                                                               <ignore></ignore>
+                                                                       </action>
+                                                               </pluginExecution>
+                                                       </pluginExecutions>
+                                               </lifecycleMappingMetadata>
+                                       </configuration>
+                               </plugin>
+                       </plugins>
+               </pluginManagement>
+       </build>
+</project>
\ No newline at end of file
diff --git a/integrity-audit/src/main/java/org/openecomp/policy/common/ia/AuditThread.java b/integrity-audit/src/main/java/org/openecomp/policy/common/ia/AuditThread.java
new file mode 100644 (file)
index 0000000..2319f21
--- /dev/null
@@ -0,0 +1,769 @@
+/*-
+ * ============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=========================================================
+ */
+
+package org.openecomp.policy.common.ia;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Date;
+import java.util.List;
+import java.util.Properties;
+//import org.apache.log4j.Logger;
+
+
+import org.openecomp.policy.common.ia.jpa.IntegrityAuditEntity;
+import org.openecomp.policy.common.logging.eelf.MessageCodes;
+import org.openecomp.policy.common.logging.flexlogger.FlexLogger; 
+import org.openecomp.policy.common.logging.flexlogger.Logger;
+
+/**
+ * AuditThread is the main thread for the IntegrityAudit
+ * 
+ */
+public class AuditThread extends Thread {
+
+       private static final Logger logger = FlexLogger.getLogger(AuditThread.class);
+
+       /*
+        * Number of milliseconds that must elapse for audit to be considered
+        * complete. It's public for access by JUnit test logic.
+        */
+       public static final long AUDIT_COMPLETION_INTERVAL = 30000;
+
+       /*
+        * Number of iterations for audit simulation.
+        */
+       public static final long AUDIT_SIMULATION_ITERATIONS = 3;
+
+       /*
+        * Number of milliseconds to sleep between audit simulation iterations. It's
+        * public for access by JUnit test logic.
+        */
+       public static final long AUDIT_SIMULATION_SLEEP_INTERVAL = 5000;
+
+       /*
+        * Unless audit has already been run on this entity, number of milliseconds
+        * to sleep between audit thread iterations. If audit has already been run,
+        * we sleep integrityAuditPeriodMillis.
+        */
+       private static final long AUDIT_THREAD_SLEEP_INTERVAL = 5000;
+
+       /*
+        * DB access class.
+        */
+       private DbDAO dbDAO;
+
+       /*
+        * E.g. pdp_xacml
+        */
+       private String nodeType;
+
+       /*
+        * Persistence unit for which this audit is being run.
+        */
+       private String persistenceUnit;
+
+       /*
+        * Name of this resource
+        */
+       private String resourceName;
+
+       /*
+        * E.g. DB_DRIVER, SITE_NAME, NODE_TYPE
+        */
+       private Properties properties;
+
+       /*
+        * See IntegrityAudit class for usage.
+        */
+       private int integrityAuditPeriodMillis;
+       
+       /*
+        * The containing IntegrityAudit instance
+        */
+       private IntegrityAudit integrityAudit;
+
+       /**
+        * AuditThread constructor
+        * @param resourceName
+        * @param persistenceUnit
+        * @param properties
+        * @param integrityAuditPeriodSeconds
+        * @param integrityAudit
+        * @throws Exception
+        */
+       public AuditThread(String resourceName, String persistenceUnit,
+                       Properties properties, int integrityAuditPeriodSeconds, IntegrityAudit integrityAudit)
+                       throws Exception {
+               this.resourceName = resourceName;
+               this.persistenceUnit = persistenceUnit;
+               this.properties = properties;
+               this.integrityAuditPeriodMillis = integrityAuditPeriodSeconds * 1000;
+               this.integrityAudit = integrityAudit;
+
+               /*
+                * The DbDAO Constructor registers this node in the IntegrityAuditEntity
+                * table. Each resource (node) inserts its own name, persistenceUnit, DB
+                * access properties and other pertinent properties in the table. This
+                * allows the audit on each node to compare its own version of the
+                * entities for the persistenceUnit in question with the versions from
+                * all other nodes of similar type.
+                */
+               dbDAO = new DbDAO(this.resourceName, this.persistenceUnit,
+                               this.properties);
+               this.nodeType = properties.getProperty(IntegrityAuditProperties.NODE_TYPE);
+
+       }
+
+       public void run() {
+
+               logger.info("AuditThread.run: Entering");
+
+               try {
+                       
+                       /*
+                        * Triggers change in designation, unless no other viable candidate.
+                        */
+                       boolean auditCompleted = false;
+
+                       DbAudit dbAudit = new DbAudit(dbDAO);
+
+                       IntegrityAuditEntity entityCurrentlyDesignated = null;
+                       IntegrityAuditEntity thisEntity = null;
+                       integrityAudit.setThreadInitialized(true); // An exception will set
+                                                                                                               // it to false
+
+                       while (true) {
+                               try{
+
+                                       /*
+                                        * It may have been awhile since we last cycled through this
+                                        * loop, so refresh the list of IntegrityAuditEntities.
+                                        */
+                                       List<IntegrityAuditEntity> integrityAuditEntityList = getIntegrityAuditEntityList();
+
+                                       /*
+                                        * We could've set entityCurrentlyDesignated as a side effect of
+                                        * getIntegrityAuditEntityList(), but then we would've had to
+                                        * make entityCurrentlyDesignated a class level attribute. Using
+                                        * this approach, we can keep it local to the run() method.
+                                        */
+                                       entityCurrentlyDesignated = getEntityCurrentlyDesignated(integrityAuditEntityList);
+
+                                       /*
+                                        * Need to refresh thisEntity each time through loop, because we
+                                        * need a fresh version of lastUpdated.
+                                        */
+                                       thisEntity = getThisEntity(integrityAuditEntityList);
+
+                                       /*
+                                        * If we haven't done the audit yet, note that we're current and
+                                        * see if we're designated.
+                                        */
+                                       if (!auditCompleted) {
+                                               dbDAO.setLastUpdated();
+
+                                               /*
+                                                * If no current designation or currently designated node is
+                                                * stale, see if we're the next node to be designated.
+                                                */
+                                               if (entityCurrentlyDesignated == null
+                                                               || isStale(entityCurrentlyDesignated)) {
+                                                       IntegrityAuditEntity designationCandidate = getDesignationCandidate(integrityAuditEntityList);
+
+                                                       /*
+                                                        * If we're the next node to be designated, run the
+                                                        * audit.
+                                                        */
+                                                       if (designationCandidate.getResourceName().equals(
+                                                                       this.resourceName)) {
+                                                               runAudit(dbAudit);
+                                                               auditCompleted = true;
+                                                       } else {
+                                                               if (logger.isDebugEnabled()) {
+                                                                       logger.debug("AuditThread.run: designationCandidate, "
+                                                                                       + designationCandidate
+                                                                                       .getResourceName()
+                                                                                       + ", not this entity, "
+                                                                                       + thisEntity.getResourceName());
+                                                               }
+                                                       }
+
+                                                       /*
+                                                        * Application may have been stopped and restarted, in
+                                                        * which case we might be designated but auditCompleted
+                                                        * will have been reset to false, so account for this.
+                                                        */
+                                               } else if (thisEntity.getResourceName().equals(
+                                                               entityCurrentlyDesignated.getResourceName())) {
+
+                                                       if (logger.isDebugEnabled()) {
+                                                               logger.debug("AuditThread.run: Re-running audit for "
+                                                                               + thisEntity.getResourceName());
+                                                       }
+                                                       runAudit(dbAudit);
+                                                       auditCompleted = true;
+
+                                               } else {
+                                                       if (logger.isDebugEnabled()) {
+                                                               logger.debug("AuditThread.run: Currently designated node, "
+                                                                               + entityCurrentlyDesignated
+                                                                               .getResourceName()
+                                                                               + ", not yet stale and not this node");
+                                                       }
+                                               }
+
+
+                                               /*
+                                                * Audit already completed on this node, so allow the node
+                                                * to go stale until twice the AUDIT_COMPLETION_PERIOD has
+                                                * elapsed. This should give plenty of time for another node
+                                                * (if another node is out there) to pick up designation.
+                                                */
+                                       } else {
+
+                                               auditCompleted = resetAuditCompleted(auditCompleted,
+                                                               thisEntity);
+
+                                       }
+
+                                       /*
+                                        * If we've just run audit, sleep per the
+                                        * integrity_audit_period_seconds property, otherwise just sleep
+                                        * the normal interval.
+                                        */
+                                       if (auditCompleted) {
+
+                                               if (logger.isDebugEnabled()) {
+                                                       logger.debug("AuditThread.run: Audit completed; resourceName="
+                                                                       + this.resourceName
+                                                                       + " sleeping "
+                                                                       + integrityAuditPeriodMillis + "ms");
+                                               }
+                                               Thread.sleep(integrityAuditPeriodMillis);
+                                               if (logger.isDebugEnabled()) {
+                                                       logger.debug("AuditThread.run: resourceName="
+                                                                       + this.resourceName + " awaking from "
+                                                                       + integrityAuditPeriodMillis + "ms sleep");
+                                               }
+
+                                       } else {
+
+                                               if (logger.isDebugEnabled()) {
+                                                       logger.debug("AuditThread.run: resourceName="
+                                                                       + this.resourceName + ": Sleeping "
+                                                                       + AuditThread.AUDIT_THREAD_SLEEP_INTERVAL
+                                                                       + "ms");
+                                               }
+                                               Thread.sleep(AuditThread.AUDIT_THREAD_SLEEP_INTERVAL);
+                                               if (logger.isDebugEnabled()) {
+                                                       logger.debug("AuditThread.run: resourceName="
+                                                                       + this.resourceName + ": Awaking from "
+                                                                       + AuditThread.AUDIT_THREAD_SLEEP_INTERVAL
+                                                                       + "ms sleep");
+                                               }
+
+                                       }
+                               } catch (Exception e){
+                                       String msg = "AuditThread.run loop - Exception thrown: " + e.getMessage() 
+                                                       + "; Will try audit again in " + (integrityAuditPeriodMillis/1000) + " seconds";
+                                       logger.error(MessageCodes.EXCEPTION_ERROR, e, msg);
+                                       // Sleep and try again later
+                                       Thread.sleep(integrityAuditPeriodMillis);
+                                       continue;
+                               }
+
+                       }
+
+               } catch (Exception e) {
+                       String msg = "AuditThread.run: Could not start audit loop. Exception thrown; message="+ e.getMessage();
+                       logger.error(MessageCodes.EXCEPTION_ERROR, e, msg);
+                       integrityAudit.setThreadInitialized(false);
+               }
+
+               logger.info("AuditThread.run: Exiting");
+       }
+
+       /*
+        * Used to create a list that is sorted lexicographically by resourceName.
+        */
+       Comparator<IntegrityAuditEntity> comparator = new Comparator<IntegrityAuditEntity>() {
+               @Override
+               public int compare(final IntegrityAuditEntity r1,
+                               final IntegrityAuditEntity r2) {
+                       return r1.getResourceName().compareTo(r2.getResourceName());
+               }
+       };
+
+       /**
+        * getDesignationCandidate()
+        * Using round robin algorithm, gets next candidate to be designated. Assumes
+        * list is sorted lexicographically by resourceName.
+        */
+       private IntegrityAuditEntity getDesignationCandidate(
+                       List<IntegrityAuditEntity> integrityAuditEntityList) {
+               
+               //Note: assumes integrityAuditEntityList is already lexicographically sorted by resourceName
+
+               if (logger.isDebugEnabled()) {
+                       logger.debug("getDesignationCandidate: Entering, integrityAuditEntityList.size()="
+                                       + integrityAuditEntityList.size());
+               }
+
+               IntegrityAuditEntity designationCandidate = null;
+               IntegrityAuditEntity thisEntity = null;
+
+               int designatedEntityIndex = -1;
+               int entityIndex = 0;
+               int priorCandidateIndex = -1;
+               int subsequentCandidateIndex = -1;
+
+               for (IntegrityAuditEntity integrityAuditEntity : integrityAuditEntityList) {
+
+                       if (logger.isDebugEnabled()) {
+                               logIntegrityAuditEntity(integrityAuditEntity);
+                       }
+
+                       if (integrityAuditEntity.getResourceName()
+                                       .equals(this.resourceName)) {
+                               if (logger.isDebugEnabled()) {
+                                       logger.debug("getDesignationCandidate: thisEntity="
+                                                       + integrityAuditEntity.getResourceName());
+                               }
+                               thisEntity = integrityAuditEntity;
+                       }
+
+                       if (integrityAuditEntity.isDesignated()) {
+                               if (logger.isDebugEnabled()) {
+                                       logger.debug("getDesignationCandidate: Currently designated entity resourceName="
+                                                       + integrityAuditEntity.getResourceName()
+                                                       + ", persistenceUnit="
+                                                       + integrityAuditEntity.getPersistenceUnit()
+                                                       + ", lastUpdated="
+                                                       + integrityAuditEntity.getLastUpdated()
+                                                       + ", entityIndex=" + entityIndex);
+                               }
+                               designatedEntityIndex = entityIndex;
+
+                               /*
+                                * Entity not currently designated
+                                */
+                       } else {
+
+                               /*
+                                * See if non-designated entity is stale.
+                                */
+                               if (isStale(integrityAuditEntity)) {
+
+                                       if (logger.isDebugEnabled()) {
+                                               logger.debug("getDesignationCandidate: Entity is stale; resourceName="
+                                                               + integrityAuditEntity.getResourceName()
+                                                               + ", persistenceUnit="
+                                                               + integrityAuditEntity.getPersistenceUnit()
+                                                               + ", lastUpdated="
+                                                               + integrityAuditEntity.getLastUpdated()
+                                                               + ", entityIndex=" + entityIndex);
+                                       }
+
+                                       /*
+                                        * Entity is current.
+                                        */
+                               } else {
+
+                                       if (designatedEntityIndex == -1) {
+
+                                               if (priorCandidateIndex == -1) {
+                                                       if (logger.isDebugEnabled()) {
+                                                               logger.debug("getDesignationCandidate: Prior candidate found, resourceName="
+                                                                               + integrityAuditEntity
+                                                                                               .getResourceName()
+                                                                               + ", persistenceUnit="
+                                                                               + integrityAuditEntity
+                                                                                               .getPersistenceUnit()
+                                                                               + ", lastUpdated="
+                                                                               + integrityAuditEntity.getLastUpdated()
+                                                                               + ", entityIndex=" + entityIndex);
+                                                       }
+                                                       priorCandidateIndex = entityIndex;
+                                               } else {
+                                                       if (logger.isDebugEnabled()) {
+                                                               logger.debug("getDesignationCandidate: Prior entity current but prior candidate already found; resourceName="
+                                                                               + integrityAuditEntity
+                                                                                               .getResourceName()
+                                                                               + ", persistenceUnit="
+                                                                               + integrityAuditEntity
+                                                                                               .getPersistenceUnit()
+                                                                               + ", lastUpdated="
+                                                                               + integrityAuditEntity.getLastUpdated()
+                                                                               + ", entityIndex=" + entityIndex);
+                                                       }
+                                               }
+                                       } else {
+                                               if (subsequentCandidateIndex == -1) {
+                                                       if (logger.isDebugEnabled()) {
+                                                               logger.debug("getDesignationCandidate: Subsequent candidate found, resourceName="
+                                                                               + integrityAuditEntity
+                                                                                               .getResourceName()
+                                                                               + ", persistenceUnit="
+                                                                               + integrityAuditEntity
+                                                                                               .getPersistenceUnit()
+                                                                               + ", lastUpdated="
+                                                                               + integrityAuditEntity.getLastUpdated()
+                                                                               + ", entityIndex=" + entityIndex);
+                                                       }
+                                                       subsequentCandidateIndex = entityIndex;
+                                               } else {
+                                                       if (logger.isDebugEnabled()) {
+                                                               logger.debug("getDesignationCandidate: Subsequent entity current but subsequent candidate already found; resourceName="
+                                                                               + integrityAuditEntity
+                                                                                               .getResourceName()
+                                                                               + ", persistenceUnit="
+                                                                               + integrityAuditEntity
+                                                                                               .getPersistenceUnit()
+                                                                               + ", lastUpdated="
+                                                                               + integrityAuditEntity.getLastUpdated()
+                                                                               + ", entityIndex=" + entityIndex);
+                                                       }
+                                               }
+                                       }
+
+                               } // end entity is current
+
+                       } // end entity not currently designated
+
+                       entityIndex++;
+
+               } // end for loop
+
+               /*
+                * Per round robin algorithm, if a current entity is found that is
+                * lexicographically after the currently designated entity, this entity
+                * becomes the designation candidate. If no current entity is found that
+                * is lexicographically after currently designated entity, we cycle back
+                * to beginning of list and pick the first current entity as the
+                * designation candidate.
+                */
+               if (subsequentCandidateIndex != -1) {
+                       designationCandidate = integrityAuditEntityList
+                                       .get(subsequentCandidateIndex);
+                       if (logger.isDebugEnabled()) {
+                               logger.debug("getDesignationCandidate: Exiting and returning subsequent designationCandidate="
+                                               + designationCandidate.getResourceName());
+                       }
+               } else {
+                       if (priorCandidateIndex != -1) {
+                               designationCandidate = integrityAuditEntityList
+                                               .get(priorCandidateIndex);
+                               if (logger.isDebugEnabled()) {
+                                       logger.debug("getDesignationCandidate: Exiting and returning prior designationCandidate="
+                                                       + designationCandidate.getResourceName());
+                               }
+                       } else {
+                               logger.debug("getDesignationCandidate: No subsequent or prior candidate found; designating thisEntity, resourceName="
+                                               + thisEntity.getResourceName());
+                               designationCandidate = thisEntity;
+                       }
+               }
+
+               return designationCandidate;
+
+       }
+
+       /**
+        * getEntityCurrentlyDesignated()
+        * Returns entity that is currently designated.
+        * @param integrityAuditEntityList
+        * @return
+        */
+       private IntegrityAuditEntity getEntityCurrentlyDesignated(
+                       List<IntegrityAuditEntity> integrityAuditEntityList) {
+
+               if (logger.isDebugEnabled()) {
+                       logger.debug("getEntityCurrentlyDesignated: Entering, integrityAuditEntityList.size="
+                                       + integrityAuditEntityList.size());
+               }
+
+               IntegrityAuditEntity entityCurrentlyDesignated = null;
+
+               for (IntegrityAuditEntity integrityAuditEntity : integrityAuditEntityList) {
+
+                       if (integrityAuditEntity.isDesignated()) {
+                               if (logger.isDebugEnabled()) {
+                                       logger.debug("getEntityCurrentlyDesignated: Currently designated entity resourceName="
+                                                       + integrityAuditEntity.getResourceName()
+                                                       + ", persistenceUnit="
+                                                       + integrityAuditEntity.getPersistenceUnit()
+                                                       + ", lastUpdated="
+                                                       + integrityAuditEntity.getLastUpdated());
+                               }
+                               entityCurrentlyDesignated = integrityAuditEntity;
+                       }
+
+               } // end for loop
+
+               if (logger.isDebugEnabled()) {
+                       if (entityCurrentlyDesignated != null) {
+                               logger.debug("getEntityCurrentlyDesignated: Exiting and returning entityCurrentlyDesignated="
+                                               + entityCurrentlyDesignated.getResourceName());
+                       } else {
+                               logger.debug("getEntityCurrentlyDesignated: Exiting and returning entityCurrentlyDesignated="
+                                               + entityCurrentlyDesignated);
+                       }
+               }
+               return entityCurrentlyDesignated;
+
+       }
+
+       /**
+        * getIntegrityAuditEnityList gets the list of IntegrityAuditEntity 
+        * @return
+        * @throws DbDaoTransactionException
+        */
+       private List<IntegrityAuditEntity> getIntegrityAuditEntityList()
+                       throws DbDaoTransactionException {
+
+               if (logger.isDebugEnabled()) {
+                       logger.debug("getIntegrityAuditEntityList: Entering");
+               }
+
+               /*
+                * Get all records for this nodeType and persistenceUnit and then sort
+                * them lexicographically by resourceName. Get index of designated
+                * entity, if any.
+                */
+               /*
+                * Sorted list of entities for a particular nodeType and
+                * persistenceUnit.
+                */
+               List<IntegrityAuditEntity> integrityAuditEntityList = new ArrayList<IntegrityAuditEntity>();
+               integrityAuditEntityList = dbDAO.getIntegrityAuditEntities(
+                               this.persistenceUnit, this.nodeType);
+               int listSize = integrityAuditEntityList.size();
+               if (logger.isDebugEnabled()) {
+                       logger.debug("getIntegrityAuditEntityList: Got " + listSize
+                                       + " IntegrityAuditEntity records");
+               }
+               Collections.sort((List<IntegrityAuditEntity>) integrityAuditEntityList,
+                               comparator);
+
+               if (logger.isDebugEnabled()) {
+                       logger.debug("getIntegrityAuditEntityList: Exiting and returning integrityAuditEntityList, size="
+                                       + listSize);
+               }
+               return integrityAuditEntityList;
+
+       }
+
+
+       /**
+        * Returns the IntegrityAuditEntity for this entity.
+        * @param integrityAuditEntityList
+        * @return
+        */
+       private IntegrityAuditEntity getThisEntity(
+                       List<IntegrityAuditEntity> integrityAuditEntityList) {
+
+               if (logger.isDebugEnabled()) {
+                       logger.debug("getThisEntity: Entering, integrityAuditEntityList.size="
+                                       + integrityAuditEntityList.size());
+               }
+
+               IntegrityAuditEntity thisEntity = null;
+
+               for (IntegrityAuditEntity integrityAuditEntity : integrityAuditEntityList) {
+
+                       if (integrityAuditEntity.getResourceName().equals(this.resourceName)) {
+                               if (logger.isDebugEnabled()) {
+                                       logger.debug("getThisEntity: For this entity, resourceName="
+                                                       + integrityAuditEntity.getResourceName()
+                                                       + ", persistenceUnit="
+                                                       + integrityAuditEntity.getPersistenceUnit()
+                                                       + ", lastUpdated="
+                                                       + integrityAuditEntity.getLastUpdated());
+                               }
+                               thisEntity = integrityAuditEntity;
+                       }
+
+               } // end for loop
+
+               if (logger.isDebugEnabled()) {
+                       if (thisEntity != null) {
+                               logger.debug("getThisEntity: Exiting and returning thisEntity="
+                                               + thisEntity.getResourceName());
+                       } else {
+                               logger.debug("getThisEntity: Exiting and returning thisEntity="
+                                               + thisEntity);
+                       }
+               }
+               return thisEntity;
+
+       }
+
+
+       /**
+        * Returns false if the lastUpdated time for the record in question is more
+        * than AUDIT_COMPLETION_INTERVAL seconds ago. During an audit, lastUpdated is updated every five
+        * seconds or so, but when an audit finishes, the node doing the audit stops
+        * updating lastUpdated.
+        * @param integrityAuditEntity
+        * @return
+        */
+       private boolean isStale(IntegrityAuditEntity integrityAuditEntity) {
+
+               if (logger.isDebugEnabled()) {
+                       logger.debug("isStale: Entering, resourceName="
+                                       + integrityAuditEntity.getResourceName()
+                                       + ", persistenceUnit="
+                                       + integrityAuditEntity.getPersistenceUnit()
+                                       + ", lastUpdated=" + integrityAuditEntity.getLastUpdated());
+               }
+
+               boolean stale = false;
+
+               Date currentTime = new Date();
+               Date lastUpdated = integrityAuditEntity.getLastUpdated();
+
+               /*
+                * If lastUpdated is null, we assume that the audit never ran for that
+                * node.
+                */
+               long lastUpdatedTime = 0;
+               if (lastUpdated != null) {
+                       lastUpdatedTime = lastUpdated.getTime();
+               }
+               long timeDifference = currentTime.getTime() - lastUpdatedTime;
+               if (timeDifference > AUDIT_COMPLETION_INTERVAL) {
+                       stale = true;
+               }
+
+               if (logger.isDebugEnabled()) {
+                       logger.debug("isStale: Exiting and returning stale=" + stale
+                                       + ", timeDifference=" + timeDifference);
+               }
+
+               return stale;
+       }
+
+       private void logIntegrityAuditEntity(
+                       IntegrityAuditEntity integrityAuditEntity) {
+
+               logger.debug("logIntegrityAuditEntity: id="
+                               + integrityAuditEntity.getId() + ", jdbcDriver="
+                               + integrityAuditEntity.getJdbcDriver() + ", jdbcPassword="
+                               + integrityAuditEntity.getJdbcPassword() + ", jdbcUrl="
+                               + integrityAuditEntity.getJdbcUrl() + ", jdbcUser="
+                               + integrityAuditEntity.getJdbcUser() + ", nodeType="
+                               + integrityAuditEntity.getNodeType() + ", persistenceUnit="
+                               + integrityAuditEntity.getPersistenceUnit() + ", resourceName="
+                               + integrityAuditEntity.getResourceName() + ", site="
+                               + integrityAuditEntity.getSite() + ", createdDate="
+                               + integrityAuditEntity.getCreatedDate() + ", lastUpdated="
+                               + integrityAuditEntity.getLastUpdated() + ", designated="
+                               + integrityAuditEntity.isDesignated());
+       }
+       
+       /*
+        * If more than (AUDIT_COMPLETION_INTERVAL * 2) milliseconds have elapsed
+        * since we last ran the audit, reset auditCompleted, so
+        * 
+        * 1) we'll eventually re-run the audit, if no other node picks up the
+        * designation.
+        * 
+        * or
+        * 
+        * 2) We'll run the audit when the round robin comes back to us.
+        */
+       private boolean resetAuditCompleted(boolean auditCompleted,
+                       IntegrityAuditEntity thisEntity) {
+
+               if (logger.isDebugEnabled()) {
+                       logger.debug("resetAuditCompleted: auditCompleted="
+                                       + auditCompleted + "; for thisEntity, resourceName="
+                                       + thisEntity.getResourceName() + ", persistenceUnit="
+                                       + thisEntity.getPersistenceUnit() + ", lastUpdated="
+                                       + thisEntity.getLastUpdated());
+               }
+
+               long timeDifference = -1;
+
+               Date currentTime = new Date();
+               Date lastUpdated = thisEntity.getLastUpdated();
+
+               long lastUpdatedTime = lastUpdated.getTime();
+               timeDifference = currentTime.getTime() - lastUpdatedTime;
+
+               if (timeDifference > (AUDIT_COMPLETION_INTERVAL * 2)) {
+                       if (logger.isDebugEnabled()) {
+                               logger.debug("resetAuditCompleted: Resetting auditCompleted for resourceName="
+                                               + this.resourceName);
+                       }
+                       auditCompleted = false;
+               } else {
+                       if (logger.isDebugEnabled()) {
+                               logger.debug("resetAuditCompleted: For resourceName="
+                                               + resourceName
+                                               + ", time since last update is only "
+                                               + timeDifference + "; retaining current value for auditCompleted");
+                       }
+               }
+
+               if (logger.isDebugEnabled()) {
+                       logger.debug("resetAuditCompleted: Exiting and returning auditCompleted="
+                                       + auditCompleted + ", timeDifference=" + timeDifference);
+               }
+               return auditCompleted;
+       }
+
+       private void runAudit(DbAudit dbAudit) throws Exception {
+
+               if (logger.isDebugEnabled()) {
+                       logger.debug("runAudit: Entering, dbAudit=" + dbAudit
+                                       + "; notifying other resources that resourceName="
+                                       + this.resourceName + " is current");
+               }
+
+               /*
+                * changeDesignated marks all other nodes as non-designated and this
+                * node as designated.
+                */
+               dbDAO.changeDesignated(this.resourceName, this.persistenceUnit,
+                               this.nodeType);
+
+               if (logger.isDebugEnabled()) {
+                       logger.debug("runAudit: Running audit for persistenceUnit="
+                                       + this.persistenceUnit + " on resourceName="
+                                       + this.resourceName);
+               }
+               if (IntegrityAudit.isUnitTesting) {
+                       dbAudit.dbAuditSimulate(this.resourceName, this.persistenceUnit,
+                                       this.nodeType);
+               } else {
+                       dbAudit.dbAudit(this.resourceName, this.persistenceUnit,
+                                       this.nodeType);
+               }
+
+               if (logger.isDebugEnabled()) {
+                       logger.debug("runAudit: Exiting");
+               }
+
+       }
+
+}
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
new file mode 100644 (file)
index 0000000..9af8999
--- /dev/null
@@ -0,0 +1,464 @@
+/*-
+ * ============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=========================================================
+ */
+
+package org.openecomp.policy.common.ia;
+
+import java.io.Serializable;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Properties;
+
+import javax.persistence.Table;
+
+import org.apache.commons.lang3.SerializationUtils;
+import org.apache.commons.lang3.builder.RecursiveToStringStyle;
+import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+//import org.apache.log4j.Logger;
+
+
+
+
+
+import org.openecomp.policy.common.ia.jpa.IntegrityAuditEntity;
+import org.openecomp.policy.common.logging.eelf.MessageCodes;
+import org.openecomp.policy.common.logging.flexlogger.FlexLogger; 
+import org.openecomp.policy.common.logging.flexlogger.Logger;
+
+/**
+ * class DbAudit does actual auditing of DB tables.
+ */
+public class DbAudit {
+       
+       private static final Logger logger = FlexLogger.getLogger(DbAudit.class);
+       
+       DbDAO dbDAO = null;
+       
+       public DbAudit(DbDAO dbDAO) {
+               
+               if (logger.isDebugEnabled()) {
+                       logger.debug("Constructor: Entering");
+               }
+
+               this.dbDAO = dbDAO;
+               
+               if (logger.isDebugEnabled()) {
+                       logger.debug("Constructor: Exiting");
+               }
+
+       }
+       
+       /**
+        * dbAudit actually does the audit
+        * @param resourceName
+        * @param persistenceUnit
+        * @param nodeType
+        * @throws Exception
+        */
+       public void dbAudit(String resourceName, String persistenceUnit, String nodeType) throws Exception {
+               
+               if (logger.isDebugEnabled()) {
+                       logger.debug("dbAudit: Entering, resourceName=" + resourceName
+                                       + ", persistenceUnit=" + persistenceUnit + ", nodeType="
+                                       + nodeType);
+               }
+       
+               // Get all IntegrityAudit entries so we can get the DB access info
+               List<IntegrityAuditEntity> iaeList = dbDAO.getIntegrityAuditEntities(persistenceUnit, nodeType);
+               if(iaeList == null || iaeList.isEmpty()){
+                       
+                       String msg = "DbAudit: for node " + resourceName + " Found no IntegrityAuditEntity entries";
+                       logger.error(MessageCodes.ERROR_AUDIT,  msg);
+                       throw new DbAuditException(msg);
+                       
+               }else if(iaeList.size() == 1){
+                       
+                       Long iaeId = null;
+                       String iaeRN = null;
+                       String iaeNT = null;
+                       String iaeS = null;
+                       for (IntegrityAuditEntity iae : iaeList){
+                               iaeId = iae.getId();
+                               iaeRN = iae.getResourceName();
+                               iaeNT = iae.getNodeType();
+                               iaeS = iae.getSite();
+                       }
+                       String msg = "DbAudit: Found only one IntegrityAuditEntity entry:"
+                                       + " ID = " + iaeId
+                                       + " ResourceName = " + iaeRN
+                                       + " NodeType = " + iaeNT
+                                       + " Site = " + iaeS;
+                       logger.warn(msg);
+                       return;
+               }
+               
+               // Obtain all persistence class names for the PU we are auditing
+               HashSet<String> classNameSet = dbDAO.getPersistenceClassNames();
+               if(classNameSet == null || classNameSet.isEmpty()){
+                       
+                       String msg = "DbAudit: For node " + resourceName + " Found no persistence class names";
+                       logger.error(MessageCodes.ERROR_AUDIT,  msg);
+                       throw new DbAuditException(msg);
+                       
+               }
+               
+               /*
+                * Retrieve myIae.  We are going to compare the local class entries against
+                * all other DB nodes. Since the audit is run in a round-robin, every instance
+                * will be compared against every other instance.
+                */
+               IntegrityAuditEntity myIae = dbDAO.getMyIntegrityAuditEntity();
+
+               if(myIae == null){
+                       
+                       String msg = "DbAudit: Found no IntegrityAuditEntity entry for resourceName: " + resourceName
+                                       + " persistenceUnit: " + persistenceUnit;
+                       logger.error(MessageCodes.ERROR_AUDIT,  msg);
+                       throw new DbAuditException(msg);
+                       
+               }
+               /*
+                * This is the map of mismatched entries indexed by className. For
+                * each class name there is a list of mismatched entries
+                */
+               HashMap<String,HashSet<Object>> misMatchedMap = new HashMap<String,HashSet<Object>>();
+               
+               // We need to keep track of how long the audit is taking
+               long startTime = System.currentTimeMillis();
+               
+               // Retrieve all instances of the class for each node                    
+               if (logger.isDebugEnabled()) {
+                       logger.debug("dbAudit: Traversing classNameSet, size=" + classNameSet.size());
+               }
+               for(String clazzName: classNameSet){
+                       
+                       if (logger.isDebugEnabled()) {
+                               logger.debug("dbAudit: clazzName=" + clazzName);
+                       }
+       
+                       // all instances of the class for myIae
+                       HashMap<Object,Object> myEntries = dbDAO.getAllMyEntries(clazzName);
+                       //get a map of the objects indexed by id. Does not necessarily have any entries
+                       
+                       if (logger.isDebugEnabled()) {
+                               logger.debug("dbAudit: Traversing iaeList, size=" + iaeList.size());
+                       }
+                       for (IntegrityAuditEntity iae : iaeList){
+                               if(iae.getId() == myIae.getId()){
+                                       if (logger.isDebugEnabled()) {
+                                               logger.debug("dbAudit: My Id=" + iae.getId()
+                                                               + ", resourceName=" + iae.getResourceName());
+                                       }
+                                       continue; //no need to compare with self
+                               } else {
+                                       if (logger.isDebugEnabled()) {
+                                               logger.debug("dbAudit: Id=" + iae.getId()
+                                                               + ", resourceName=" + iae.getResourceName());
+                                       }
+                               }
+                               // Create properties for the other db node
+                               Properties theirProperties = new Properties();
+                               theirProperties.put(IntegrityAuditProperties.DB_DRIVER, iae.getJdbcDriver());
+                               theirProperties.put(IntegrityAuditProperties.DB_URL, iae.getJdbcUrl());
+                               theirProperties.put(IntegrityAuditProperties.DB_USER, iae.getJdbcUser());
+                               theirProperties.put(IntegrityAuditProperties.DB_PWD, iae.getJdbcPassword());
+                               theirProperties.put(IntegrityAuditProperties.SITE_NAME, iae.getSite());
+                               theirProperties.put(IntegrityAuditProperties.NODE_TYPE, iae.getNodeType());
+                               
+                               //get a map of the instances for their iae indexed by id
+                               HashMap<Object,Object> theirEntries = dbDAO.getAllEntries(persistenceUnit, theirProperties, clazzName);
+                               if (logger.isDebugEnabled()) {
+                                       logger.debug("dbAudit: For persistenceUnit="
+                                                       + persistenceUnit + ", clazzName=" + clazzName
+                                                       + ", theirEntries.size()="
+                                                       + theirEntries.size());
+                               }
+                               
+                               /*
+                                * Compare myEntries with theirEntries and get back a set of mismatched IDs.
+                                * Collect the IDs for the class where a mismatch occurred.  We will check
+                                * them again for all nodes later.
+                                */
+                               HashSet<Object> misMatchedKeySet = compareEntries(myEntries, theirEntries);
+                               if(!misMatchedKeySet.isEmpty()){
+                                       HashSet<Object> misMatchedEntry = misMatchedMap.get(clazzName);
+                                       if(misMatchedEntry == null){
+                                               misMatchedMap.put(clazzName, misMatchedKeySet);
+                                       }else{
+                                               misMatchedEntry.addAll(misMatchedKeySet);
+                                               misMatchedMap.put(clazzName, misMatchedEntry);
+                                       }
+                               }
+                       } //end for (IntegrityAuditEntity iae : iaeList)
+                       //Time check
+                       if((System.currentTimeMillis() - startTime) >= 5000){ //5 seconds
+                               //update the timestamp
+                               dbDAO.setLastUpdated();
+                               //reset the startTime
+                               startTime=System.currentTimeMillis();
+                       }else{
+                               //sleep a couple seconds to break up the activity
+                               if (logger.isDebugEnabled()) {
+                                       logger.debug("dbAudit: Sleeping 2 seconds");
+                               }
+                               Thread.sleep(2000);
+                               if (logger.isDebugEnabled()) {
+                                       logger.debug("dbAudit: Waking from sleep");
+                               }
+                       }
+               }//end: for(String clazzName: classNameList)
+               
+               //check if misMatchedMap is empty
+               if(misMatchedMap.isEmpty()){
+                       
+                       if (logger.isDebugEnabled()) {
+                               logger.debug("dbAudit: Exiting, misMatchedMap is empty");
+                       }
+                       //we are done
+                       return;
+               } else {
+                       if (logger.isDebugEnabled()) {
+                               logger.debug("dbAudit: Doing another comparison; misMatchedMap.size()=" + misMatchedMap.size());
+                       }
+               }
+               
+               // 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();
+               
+               // Retrieve all instances of the class for each node                    
+               if (logger.isDebugEnabled()) {
+                       logger.debug("dbAudit: Second comparison; traversing classNameSet, size=" + classNameSet.size());
+               }
+               
+               int errorCount = 0;
+               
+               for(String clazzName: classNameSet){
+                       
+                       if (logger.isDebugEnabled()) {
+                               logger.debug("dbAudit: Second comparison; clazzName=" + clazzName);
+                       }
+       
+                       // all instances of the class for myIae
+                       HashSet<Object> keySet = misMatchedMap.get(clazzName);
+                       HashMap<Object,Object> myEntries = dbDAO.getAllMyEntries(clazzName, keySet);
+                       //get a map of the objects indexed by id
+                       
+                       if (logger.isDebugEnabled()) {
+                               logger.debug("dbAudit: Second comparison; traversing iaeList, size=" + iaeList.size());
+                       }
+                       for (IntegrityAuditEntity iae : iaeList){
+                               if(iae.getId() == myIae.getId()){
+                                       if (logger.isDebugEnabled()) {
+                                               logger.debug("dbAudit: Second comparison; My Id=" + iae.getId()
+                                                               + ", resourceName=" + iae.getResourceName());
+                                       }
+                                       continue; //no need to compare with self
+                               } else {
+                                       if (logger.isDebugEnabled()) {
+                                               logger.debug("dbAudit: Second comparison; Id=" + iae.getId()
+                                                               + ", resourceName=" + iae.getResourceName());
+                                       }
+                               }
+                               // Create properties for the other db node
+                               Properties theirProperties = new Properties();
+                               theirProperties.put(IntegrityAuditProperties.DB_DRIVER, iae.getJdbcDriver());
+                               theirProperties.put(IntegrityAuditProperties.DB_URL, iae.getJdbcUrl());
+                               theirProperties.put(IntegrityAuditProperties.DB_USER, iae.getJdbcUser());
+                               theirProperties.put(IntegrityAuditProperties.DB_PWD, iae.getJdbcPassword());
+                               theirProperties.put(IntegrityAuditProperties.SITE_NAME, iae.getSite());
+                               theirProperties.put(IntegrityAuditProperties.NODE_TYPE, iae.getNodeType());
+                               
+                               //get a map of the instances for their iae indexed by id
+                               HashMap<Object,Object> theirEntries = dbDAO.getAllEntries(persistenceUnit, theirProperties, clazzName, keySet);
+                               
+                               /*
+                                * Compare myEntries with theirEntries and get back a set of mismatched IDs.
+                                * Collect the IDs for the class where a mismatch occurred.  We will now
+                                * write an error log for each.
+                                */
+                               HashSet<Object> misMatchedKeySet = compareEntries(myEntries, theirEntries);
+                               if(!misMatchedKeySet.isEmpty()){
+                                       String keysString = "";
+                                       for(Object key: misMatchedKeySet){
+                                               keysString = keysString.concat(key.toString() + ", ");
+                                               errorCount ++;
+                                       }
+                                       writeAuditSummaryLog(clazzName, resourceName, iae.getResourceName(), keysString);
+                                       if(logger.isDebugEnabled()){
+                                               for(Object key : misMatchedKeySet){
+                                                       writeAuditDebugLog(clazzName, resourceName, iae.getResourceName(), myEntries.get(key), theirEntries.get(key));
+                                               }
+                                       }
+                               }
+                       }
+                       //Time check
+                       if((System.currentTimeMillis() - startTime) >= 5000){ //5 seconds
+                               //update the timestamp
+                               dbDAO.setLastUpdated();
+                               //reset the startTime
+                               startTime=System.currentTimeMillis();
+                       }else{
+                               //sleep a couple seconds to break up the activity
+                               if (logger.isDebugEnabled()) {
+                                       logger.debug("dbAudit: Second comparison; sleeping 2 seconds");
+                               }
+                               Thread.sleep(2000);
+                               if (logger.isDebugEnabled()) {
+                                       logger.debug("dbAudit: Second comparison; waking from sleep");
+                               }
+                       }
+               }//end: for(String clazzName: classNameList)
+               
+               if(errorCount != 0){
+                       String msg = " DB Audit: " + errorCount + " errors found. A large number of errors may indicate DB replication has stopped";
+                       logger.error(MessageCodes.ERROR_AUDIT,  msg);
+               }
+               
+               if (logger.isDebugEnabled()) {
+                       logger.debug("dbAudit: Exiting");
+               }
+       
+               return; //all done
+       }
+
+       /**
+        * dbAuditSimulate simulates the DB audit
+        * @param resourceName
+        * @param persistenceUnit
+        * @param nodeType
+        * @throws InterruptedException
+        * @throws DbDaoTransactionException
+        */
+       public void dbAuditSimulate(String resourceName, String persistenceUnit,
+                       String nodeType) throws InterruptedException,
+                       DbDaoTransactionException {
+
+               logger.info("dbAuditSimulate: Starting audit simulation for resourceName="
+                               + resourceName + ", persistenceUnit=" + persistenceUnit);
+
+               for (int i = 0; i < AuditThread.AUDIT_SIMULATION_ITERATIONS; i++) {
+                       dbDAO.setLastUpdated();
+                       logger.info("dbAuditSimulate: i=" + i + ", sleeping "
+                                       + AuditThread.AUDIT_SIMULATION_SLEEP_INTERVAL + "ms");
+                       Thread.sleep(AuditThread.AUDIT_SIMULATION_SLEEP_INTERVAL);
+               }
+
+               logger.info("dbAuditSimulate: Finished audit simulation for resourceName="
+                               + resourceName + ", persistenceUnit=" + persistenceUnit);
+
+       }
+       
+       /**
+        * compareEntries() will compare the lists of entries from the DB
+        * @param myEntries
+        * @param theirEntries
+        * @return
+        */
+       public HashSet<Object> compareEntries(HashMap<Object,Object> myEntries, HashMap<Object,Object> theirEntries){
+               /*
+                * Compare the entries for the same key in each of the hashmaps.  The comparison will be done by serializing the objects 
+                * (create a byte array) and then do a byte array comparison.  The audit will walk the local repository hash map comparing 
+                * to the remote cluster hashmap and then turn it around and walk the remote hashmap and look for any entries that are not 
+                * present in the local cluster hashmap. 
+                * 
+                * If the objects are not identical, the audit will put the object IDs on a list to try after completing the audit of the table 
+                * it is currently working on.
+                * 
+                */
+               HashSet<Object> misMatchedKeySet = new HashSet<Object>();
+               for(Object key: myEntries.keySet()){
+                       byte[] mySerializedEntry = SerializationUtils.serialize((Serializable) myEntries.get(key));
+                       byte[] theirSerializedEntry = SerializationUtils.serialize((Serializable) theirEntries.get(key));
+                       if(!Arrays.equals(mySerializedEntry, theirSerializedEntry)){
+                               logger.debug("compareEntries: For myEntries.key=" + key + ", entries do not match");
+                               misMatchedKeySet.add(key);
+                       } else {
+                               logger.debug("compareEntries: For myEntries.key=" + key + ", entries match");
+                       }
+               }
+               //now compare it in the other direction to catch entries in their set that is not in my set
+               for(Object key: theirEntries.keySet()){
+                       byte[] mySerializedEntry = SerializationUtils.serialize((Serializable) myEntries.get(key));
+                       byte[] theirSerializedEntry = SerializationUtils.serialize((Serializable) theirEntries.get(key));
+                       if(!Arrays.equals(mySerializedEntry, theirSerializedEntry)){
+                               logger.debug("compareEntries: For theirEntries.key=" + key + ", entries do not match");
+                               misMatchedKeySet.add(key);
+                       } else {
+                               logger.debug("compareEntries: For theirEntries.key=" + key + ", entries match");
+                       }
+               }
+               
+               //return a Set of the object IDs
+               logger.debug("compareEntries: misMatchedKeySet.size()=" + misMatchedKeySet.size());
+               return misMatchedKeySet;
+       }
+       
+       /**
+        * writeAuditDebugLog() writes the mismatched entry details to the debug log
+        * @param clazzName
+        * @param resourceName1
+        * @param resourceName2
+        * @param entry1
+        * @param entry2
+        * @throws ClassNotFoundException
+        */
+       public void writeAuditDebugLog(String clazzName, String resourceName1,
+                       String resourceName2, Object entry1, Object entry2) throws ClassNotFoundException{
+               Class<?> entityClass = Class.forName(clazzName);
+               String tableName = entityClass.getAnnotation(Table.class).name();
+               String msg = "\nDB Audit Error: "
+                               + "\n    Table Name: " + tableName
+                               + "\n    Entry 1 (short prefix style): " + resourceName1 + ": " + new ReflectionToStringBuilder(entry1,ToStringStyle.SHORT_PREFIX_STYLE).toString()
+                               + "\n    Entry 2 (short prefix style): " + resourceName2 + ": " + new ReflectionToStringBuilder(entry2,ToStringStyle.SHORT_PREFIX_STYLE).toString()
+                               + "\n    Entry 1 (recursive style): " + resourceName1 + ": " + new ReflectionToStringBuilder(entry1, new RecursiveToStringStyle()).toString()
+                               + "\n    Entry 2 (recursive style): " + resourceName2 + ": " + new ReflectionToStringBuilder(entry2, new RecursiveToStringStyle()).toString();
+               logger.debug(msg);
+               
+       }
+       
+       /**
+        * writeAuditSummaryLog() writes a summary of the DB mismatches to the error log
+        * @param clazzName
+        * @param resourceName1
+        * @param resourceName2
+        * @param keys
+        * @throws ClassNotFoundException
+        */
+       public void writeAuditSummaryLog(String clazzName, String resourceName1, 
+                       String resourceName2, String keys) throws ClassNotFoundException{
+               Class<?> entityClass = Class.forName(clazzName);
+               String tableName = entityClass.getAnnotation(Table.class).name();
+               String msg = " DB Audit Error: Table Name: " + tableName
+                               + ";  Mismatch between nodes: " + resourceName1 +" and " + resourceName2
+                               + ";  Mismatched entries (keys): " + keys;
+               logger.info(msg);
+       }
+
+
+
+       
+
+}
diff --git a/integrity-audit/src/main/java/org/openecomp/policy/common/ia/DbAuditException.java b/integrity-audit/src/main/java/org/openecomp/policy/common/ia/DbAuditException.java
new file mode 100644 (file)
index 0000000..956dd43
--- /dev/null
@@ -0,0 +1,37 @@
+/*-
+ * ============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=========================================================
+ */
+
+package org.openecomp.policy.common.ia;
+
+public class DbAuditException extends Exception{
+       private static final long serialVersionUID = 1L;
+       public DbAuditException() {
+       }
+       public DbAuditException(String message) {
+               super(message);
+       }
+
+       public DbAuditException(Throwable cause) {
+               super(cause);
+       }
+       public DbAuditException(String message, Throwable cause) {
+               super(message, cause);
+       }
+}
diff --git a/integrity-audit/src/main/java/org/openecomp/policy/common/ia/DbDAO.java b/integrity-audit/src/main/java/org/openecomp/policy/common/ia/DbDAO.java
new file mode 100644 (file)
index 0000000..70f39a2
--- /dev/null
@@ -0,0 +1,740 @@
+/*-
+ * ============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=========================================================
+ */
+
+package org.openecomp.policy.common.ia;
+
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Properties;
+
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.EntityTransaction;
+import javax.persistence.LockTimeoutException;
+import javax.persistence.Persistence;
+import javax.persistence.PersistenceUnitUtil;
+import javax.persistence.Query;
+import javax.persistence.TypedQuery;
+import javax.persistence.criteria.CriteriaBuilder;
+import javax.persistence.criteria.CriteriaQuery;
+import javax.persistence.criteria.Root;
+import javax.persistence.metamodel.ManagedType;
+import javax.persistence.metamodel.Metamodel;
+
+//import org.apache.log4j.Logger;
+
+import org.openecomp.policy.common.ia.IntegrityAuditProperties.NodeTypeEnum;
+import org.openecomp.policy.common.ia.jpa.IntegrityAuditEntity;
+import org.openecomp.policy.common.logging.flexlogger.FlexLogger; 
+import org.openecomp.policy.common.logging.flexlogger.Logger;
+
+/**
+ * class DbDAO provides the inteface to the DBs for the purpose of audits.
+ * 
+ */
+public class DbDAO {
+       private static final Logger logger = FlexLogger.getLogger(DbDAO.class.getName());
+       private String resourceName;
+       private String persistenceUnit;
+       private String dbDriver;
+       private String dbUrl;
+       private String dbUser;
+       private String dbPwd;
+       private String siteName;
+       private String nodeType;
+       private Properties properties=null;
+       
+       private EntityManagerFactory emf;
+       
+       /*
+        * Supports designation serialization.
+        */
+    private static final Object lock = new Object();
+
+       
+       /**
+        * DbDAO Constructor
+     * @param resourceName
+     * @param persistenceUnit
+     * @param properties
+     * @throws Exception
+     */
+       public DbDAO(String resourceName, String persistenceUnit, Properties properties) throws Exception {
+               logger.debug("DbDAO contructor: enter");
+               
+               validateProperties(resourceName, persistenceUnit, properties);
+               
+               emf = Persistence.createEntityManagerFactory(persistenceUnit, properties);
+               
+               register();
+               
+               logger.debug("DbDAO contructor: exit");
+       }
+       
+       /**
+        * validateProperties will validate the properties
+        * @param resourceName
+        * @param persistenceUnit
+        * @param properties
+        * @throws IntegrityAuditPropertiesException
+        */
+       private void validateProperties(String resourceName, String persistenceUnit, Properties properties) throws IntegrityAuditPropertiesException{
+               String badparams="";
+               if(IntegrityAudit.parmsAreBad(resourceName, persistenceUnit, properties, badparams)){
+                       String msg = "DbDAO: Bad parameters: badparams" + badparams;
+                       throw new IntegrityAuditPropertiesException(msg);
+               }
+               this.resourceName = resourceName;
+               this.persistenceUnit = persistenceUnit;
+               this.dbDriver = properties.getProperty(IntegrityAuditProperties.DB_DRIVER).trim();
+               this.dbUrl = properties.getProperty(IntegrityAuditProperties.DB_URL).trim();
+               this.dbUser = properties.getProperty(IntegrityAuditProperties.DB_USER).trim();
+               this.dbPwd = properties.getProperty(IntegrityAuditProperties.DB_PWD).trim();
+               this.siteName = properties.getProperty(IntegrityAuditProperties.SITE_NAME).trim();
+               this.nodeType = properties.getProperty(IntegrityAuditProperties.NODE_TYPE).trim();
+               this.properties = properties;
+               logger.debug("DbDAO.assignProperties: exit:" 
+                               + "\nresourceName: " + this.resourceName
+                               + "\npersistenceUnit: " + this.persistenceUnit
+                               + "\nproperties: " + this.properties);
+       }
+       
+       /**
+        * getAllMyEntries gets all the DB entries for a particular class
+        * @param className
+        * @return
+        */
+       public HashMap<Object, Object> getAllMyEntries(String className) {
+               logger.debug("getAllMyEntries: Entering, className="
+                               + className);
+               HashMap<Object, Object> resultMap = new HashMap<Object,Object>();
+               EntityManager em = emf.createEntityManager();
+               try{
+                       CriteriaBuilder cb = em.getCriteriaBuilder();
+                       CriteriaQuery<Object> cq = cb.createQuery();
+                       Root<?> rootEntry = cq.from(Class.forName(className));
+                       CriteriaQuery<Object> all = cq.select(rootEntry);
+                       TypedQuery<Object> allQuery = em.createQuery(all);
+                       List<Object> objectList = allQuery.getResultList();
+                       //Now create the map
+
+                       PersistenceUnitUtil util = emf.getPersistenceUnitUtil();
+                       for (Object o: objectList){
+                               Object key = util.getIdentifier(o);
+                               resultMap.put(key, o);
+                       }
+               }catch(Exception e){
+                       String msg = "getAllEntries encountered exception: " + e;
+                       logger.error(msg);
+                       System.out.println(new Date());
+                       e.printStackTrace();
+               }
+               em.close();
+               logger.debug("getAllMyEntries: Exit, resultMap.keySet()=" + resultMap.keySet());
+               return resultMap;               
+       }
+       
+       /**
+        * getAllMyEntries gets all entries for a class
+        * @param className
+        * @param keySet
+        * @return
+        */
+       public HashMap<Object, Object> getAllMyEntries(String className, HashSet<Object> keySet){
+               logger.debug("getAllMyEntries: Entering, className="
+                               + className + ",\n keySet=" + keySet);
+
+               HashMap<Object, Object> resultMap = new HashMap<Object,Object>();
+               EntityManager em = emf.createEntityManager();
+               try{
+                       Class<?> clazz = Class.forName(className);
+                       for(Object key : keySet){
+                               Object entry = em.find(clazz, key);
+                               resultMap.put(key, entry);
+                       }
+               }catch(Exception e){
+                       String msg = "getAllMyEntries encountered exception: " + e;
+                       logger.error(msg);
+                       System.out.println(new Date());
+                       e.printStackTrace();
+               }
+               em.close();
+
+               logger.debug("getAllMyEntries: Returning resultMap, size=" + resultMap.size());
+               return resultMap;
+       }
+       
+       /**
+        * getAllEntries gets all entriesfor a particular persistence unit adn className
+        * @param persistenceUnit
+        * @param properties
+        * @param className
+        * @return
+        */
+       public HashMap<Object,Object> getAllEntries(String persistenceUnit, Properties properties, String className){
+               
+               logger.debug("getAllEntries: Entering, persistenceUnit="
+                               + persistenceUnit + ",\n className=" + className);
+               HashMap<Object, Object> resultMap = new HashMap<Object,Object>();
+
+               EntityManagerFactory theEmf = Persistence.createEntityManagerFactory(persistenceUnit, properties);
+               EntityManager em = theEmf.createEntityManager();
+               try{
+                       CriteriaBuilder cb = em.getCriteriaBuilder();
+                       CriteriaQuery<Object> cq = cb.createQuery();
+                       Root<?> rootEntry = cq.from(Class.forName(className));
+                       CriteriaQuery<Object> all = cq.select(rootEntry);
+                       TypedQuery<Object> allQuery = em.createQuery(all);
+                       List<Object> objectList = allQuery.getResultList();
+
+                       PersistenceUnitUtil util = theEmf.getPersistenceUnitUtil();
+                       for (Object o: objectList){
+                               Object key = util.getIdentifier(o);
+                               resultMap.put(key, o);
+                       }
+               }catch(Exception e){
+                       String msg = "getAllEntries encountered exception:" + e;
+                       logger.error(msg);
+                       System.out.println(new Date());
+                       e.printStackTrace();
+               }
+               em.close();
+               
+               logger.debug("getAllEntries: Returning resultMap, size=" + resultMap.size());
+               
+               return resultMap;               
+       }
+       
+
+       /**
+        * getAllEntries gest all entries for a persistence unit
+        * @param persistenceUnit
+        * @param properties
+        * @param className
+        * @param keySet
+        * @return
+        */
+
+       public HashMap<Object,Object> getAllEntries(String persistenceUnit, Properties properties, String className, HashSet<Object> keySet){
+               logger.debug("getAllEntries: Entering, persistenceUnit="
+                               + persistenceUnit + ",\n properties= " + properties + ",\n className=" + className + ",\n keySet= " + keySet);
+               EntityManagerFactory theEmf = Persistence.createEntityManagerFactory(persistenceUnit, properties);
+               EntityManager em = theEmf.createEntityManager();
+               HashMap<Object, Object> resultMap = new HashMap<Object,Object>();
+               try{
+                       Class<?> clazz = Class.forName(className);
+                       for(Object key : keySet){
+                               Object entry = em.find(clazz, key);
+                               resultMap.put(key, entry);
+                       }
+               }catch(Exception e){
+                       String msg = "getAllEntries encountered exception: " + e;
+                       logger.error(msg);
+                       System.out.println(new Date());
+                       e.printStackTrace();
+               }
+               em.close();
+               logger.debug("getAllEntries: Exit, resultMap, size=" + resultMap.size());
+               return resultMap;       
+       }
+       
+       /**
+        * getIntegrityAuditEntities() Get all the IntegrityAuditEntities for a particular persistence unit
+        * and node type
+        * @param persistenceUnit
+        * @param nodeType
+        * @return
+        * @throws DbDaoTransactionException
+        */
+       @SuppressWarnings("unchecked")
+       public List<IntegrityAuditEntity> getIntegrityAuditEntities(String persistenceUnit, String nodeType) throws DbDaoTransactionException {
+               logger.debug("getIntegrityAuditEntities: Entering, persistenceUnit="
+                               + persistenceUnit + ",\n nodeType= " + nodeType);
+               try{
+                       EntityManager em = emf.createEntityManager();
+                       // Start a transaction
+                       EntityTransaction et = em.getTransaction();
+
+                       et.begin();
+
+                       // if IntegrityAuditEntity entry exists for resourceName and PU, update it. If not found, create a new entry
+                       Query iaequery = em.createQuery("Select i from IntegrityAuditEntity i where i.persistenceUnit=:pu and i.nodeType=:nt");
+                       iaequery.setParameter("pu", persistenceUnit);
+                       iaequery.setParameter("nt", nodeType);
+
+                       List<IntegrityAuditEntity> iaeList = iaequery.getResultList();
+
+                       // commit transaction
+                       et.commit();
+                       em.close();
+                       logger.debug("getIntegrityAuditEntities: Exit, iaeList=" + iaeList);
+                       return iaeList;
+               }catch (Exception e){
+                       String msg = "DbDAO: " + "getIntegrityAuditEntities() " + "ecountered a problem in execution: ";
+                       logger.error(msg + e);
+                       System.out.println(new Date());
+                       e.printStackTrace();
+                       throw new DbDaoTransactionException(e);
+               }
+               
+       }
+       
+       /**
+        * getMyIntegrityAuditEntity() gets my IntegrityAuditEntity
+        * @return
+        * @throws DbDaoTransactionException
+        */
+       public IntegrityAuditEntity getMyIntegrityAuditEntity() throws DbDaoTransactionException{
+               try{
+                       EntityManager em = emf.createEntityManager();
+
+                       // Start a transaction
+                       EntityTransaction et = em.getTransaction();
+
+                       et.begin();
+
+                       // if IntegrityAuditEntity entry exists for resourceName and PU, retrieve it
+                       Query iaequery = em.createQuery("Select i from IntegrityAuditEntity i where i.resourceName=:rn and i.persistenceUnit=:pu");
+                       iaequery.setParameter("rn", this.resourceName);
+                       iaequery.setParameter("pu", this.persistenceUnit);
+
+                       @SuppressWarnings("rawtypes")
+                       List iaeList = iaequery.getResultList();
+                       IntegrityAuditEntity iae = null;
+
+                       if(!iaeList.isEmpty()){
+                               //ignores multiple results
+                               iae = (IntegrityAuditEntity) iaeList.get(0);
+                               // refresh the object from DB in case cached data was returned
+                               em.refresh(iae);
+                               logger.info("Resource: " + this.resourceName + " with PersistenceUnit: " + this.persistenceUnit
+                                               + " exists");
+                       }else{
+                               // If it does not exist, log an error
+                               logger.error("Attempting to setLastUpdated"
+                                               + " on an entry that does not exist:"
+                                               +" resource " + this.resourceName + " with PersistenceUnit: " + this.persistenceUnit);
+                       }
+
+                       // close the transaction
+                       et.commit();
+                       // close the EntityManager
+                       em.close();
+                       
+                       return iae;
+               }catch (Exception e){
+                       String msg = "DbDAO: " + "setLastUpdated() " + "ecountered a problem in execution: ";
+                       logger.error(msg + e);
+                       System.out.println(new Date());
+                       e.printStackTrace();
+                       throw new DbDaoTransactionException(e);
+               }       
+       }
+
+       
+       /**
+        * getIntegrityAuditEntity() gets the IntegrityAuditEntity with a particular ID
+        * @param id
+        * @return
+        * @throws DbDaoTransactionException
+        */
+       public IntegrityAuditEntity getIntegrityAuditEntity(long id) throws DbDaoTransactionException{
+               try{
+                       EntityManager em = emf.createEntityManager();
+
+                       // Start a transaction
+                       EntityTransaction et = em.getTransaction();
+
+                       et.begin();
+
+                       IntegrityAuditEntity iae = em.find(IntegrityAuditEntity.class, id);
+
+                       et.commit();
+                       em.close();
+
+                       return iae;
+               }catch (Exception e){
+                       String msg = "DbDAO: " + "getIntegrityAuditEntity() " + "ecountered a problem in execution: ";
+                       logger.error(msg + e);
+                       System.out.println(new Date());
+                       e.printStackTrace();
+                       throw new DbDaoTransactionException(e);
+               }
+       }
+       
+       /**
+        * getPersistenceClassNames() gets all the persistence class names.
+        * @return
+        */
+       public HashSet<String> getPersistenceClassNames(){
+               logger.debug("DbDAO: getPersistenceClassNames() entry");
+               HashSet<String> returnList = new HashSet<String>();
+               final Metamodel mm = emf.getMetamodel();
+               logger.debug("\n" + persistenceUnit +" persistence unit classes:");
+               for (final ManagedType<?> managedType : mm.getManagedTypes()) {
+                       Class<?> c = managedType.getJavaType();
+                       logger.debug("    " + c.getSimpleName());
+                       returnList.add(c.getName()); //the full class name needed to make a query using jpa
+               }
+               logger.debug("DbDAO: getPersistenceClassNames() exit");
+               return returnList;
+       }
+       
+       /**
+        * Register the IntegrityAudit instance
+        */
+       private void register() throws DbDaoTransactionException {
+               try{
+                       EntityManager em = emf.createEntityManager();
+
+                       // Start a transaction
+                       EntityTransaction et = em.getTransaction();
+
+                       et.begin();
+
+                       // if IntegrityAuditEntity entry exists for resourceName and PU, update it. If not found, create a new entry
+                       Query iaequery = em.createQuery("Select i from IntegrityAuditEntity i where i.resourceName=:rn and i.persistenceUnit=:pu");
+                       iaequery.setParameter("rn", this.resourceName);
+                       iaequery.setParameter("pu", this.persistenceUnit);
+
+                       @SuppressWarnings("rawtypes")
+                       List iaeList = iaequery.getResultList();
+                       IntegrityAuditEntity iae = null;
+
+                       //If it already exists, we just want to update the properties and lastUpdated date
+                       if(!iaeList.isEmpty()){
+                               //ignores multiple results
+                               iae = (IntegrityAuditEntity) iaeList.get(0);
+                               // refresh the object from DB in case cached data was returned
+                               em.refresh(iae);
+                               logger.info("Resource: " + this.resourceName + " with PersistenceUnit: " + this.persistenceUnit 
+                                               + " exists and entry be updated");
+                       }else{
+                               // If it does not exist, we also must add teh resourceName, persistenceUnit and designated values
+                               logger.info("Adding resource " + resourceName + " with PersistenceUnit: " + this.persistenceUnit
+                                               + " to IntegrityAuditEntity table");    
+                               iae = new IntegrityAuditEntity();
+                               iae.setResourceName(this.resourceName);
+                               iae.setPersistenceUnit(this.persistenceUnit);
+                               iae.setDesignated(false);
+                       }
+                       //update/set properties in entry
+                       iae.setSite(this.siteName);
+                       iae.setNodeType(this.nodeType);
+                       iae.setLastUpdated(new Date());
+                       iae.setJdbcDriver(this.dbDriver);
+                       iae.setJdbcPassword(this.dbPwd);
+                       iae.setJdbcUrl(dbUrl);
+                       iae.setJdbcUser(dbUser);
+
+                       em.persist(iae);
+                       // flush to the DB
+                       em.flush();
+
+                       // commit transaction
+                       et.commit();
+                       em.close();
+               }catch (Exception e){
+                       String msg = "DbDAO: " + "register() " + "ecountered a problem in execution: ";
+                       logger.error(msg + e);
+                       System.out.println(new Date());
+                       e.printStackTrace();
+                       throw new DbDaoTransactionException(e);
+               }
+
+       }
+       
+       public void setDesignated(boolean designated) throws DbDaoTransactionException{
+               setDesignated(this.resourceName, this.persistenceUnit, designated);
+       }
+       
+
+       public void setDesignated(String rName, String pUnit, boolean desig) throws DbDaoTransactionException{
+               logger.debug("setDesignated: enter, resourceName: " + rName + ", persistenceUnit: " 
+                               + pUnit + ", designated: " + desig);
+               try{
+
+                       EntityManager em = emf.createEntityManager();
+
+                       // Start a transaction
+                       EntityTransaction et = em.getTransaction();
+
+                       et.begin();
+
+                       // if IntegrityAuditEntity entry exists for resourceName and PU, update it. If not found, create a new entry
+                       Query iaequery = em.createQuery("Select i from IntegrityAuditEntity i where i.resourceName=:rn and i.persistenceUnit=:pu");
+                       iaequery.setParameter("rn", rName);
+                       iaequery.setParameter("pu", pUnit);
+
+                       @SuppressWarnings("rawtypes")
+                       List iaeList = iaequery.getResultList();
+                       IntegrityAuditEntity iae = null;
+
+                       if(!iaeList.isEmpty()){
+                               //ignores multiple results
+                               iae = (IntegrityAuditEntity) iaeList.get(0);
+                               // refresh the object from DB in case cached data was returned
+                               em.refresh(iae);
+                               logger.info("Resource: " + rName + " with PersistenceUnit: " + pUnit 
+                                               + " exists and designated be updated");
+                               iae.setDesignated(desig);
+
+                               em.persist(iae);
+                               // flush to the DB
+                               em.flush();
+                       }else{
+                               // If it does not exist, log an error
+                               logger.error("Attempting to setDesignated("
+                                               + desig + ") on an entry that does not exist:"
+                                               +" resource " + rName + " with PersistenceUnit: " + pUnit);
+                       }
+
+                       // close the transaction
+                       et.commit();
+                       // close the EntityManager
+                       em.close();
+               }catch (Exception e){
+                       String msg = "DbDAO: " + "setDesignated() " + "ecountered a problem in execution: ";
+                       logger.error(msg + e);
+                       System.out.println(new Date());
+                       e.printStackTrace();
+                       throw new DbDaoTransactionException(e);
+               }
+
+       }
+       
+       public void setLastUpdated() throws DbDaoTransactionException{
+               logger.debug("setLastUpdated: enter, resourceName: " + this.resourceName + ", persistenceUnit: " 
+                               + this.persistenceUnit);
+               try{
+                       EntityManager em = emf.createEntityManager();
+
+                       // Start a transaction
+                       EntityTransaction et = em.getTransaction();
+
+                       et.begin();
+
+                       // if IntegrityAuditEntity entry exists for resourceName and PU, update it. If not found, create a new entry
+                       Query iaequery = em.createQuery("Select i from IntegrityAuditEntity i where i.resourceName=:rn and i.persistenceUnit=:pu");
+                       iaequery.setParameter("rn", this.resourceName);
+                       iaequery.setParameter("pu", this.persistenceUnit);
+
+                       @SuppressWarnings("rawtypes")
+                       List iaeList = iaequery.getResultList();
+                       IntegrityAuditEntity iae = null;
+
+                       if(!iaeList.isEmpty()){
+                               //ignores multiple results
+                               iae = (IntegrityAuditEntity) iaeList.get(0);
+                               // refresh the object from DB in case cached data was returned
+                               em.refresh(iae);
+                               logger.info("Resource: " + this.resourceName + " with PersistenceUnit: " + this.persistenceUnit
+                                               + " exists and lastUpdated be updated");
+                               iae.setLastUpdated(new Date());
+
+                               em.persist(iae);
+                               // flush to the DB
+                               em.flush();
+                       }else{
+                               // If it does not exist, log an error
+                               logger.error("Attempting to setLastUpdated"
+                                               + " on an entry that does not exist:"
+                                               +" resource " + this.resourceName + " with PersistenceUnit: " + this.persistenceUnit);
+                       }
+
+                       // close the transaction
+                       et.commit();
+                       // close the EntityManager
+                       em.close();
+               }catch (Exception e){
+                       String msg = "DbDAO: " + "setLastUpdated() " + "ecountered a problem in execution: ";
+                       logger.error(msg + e);
+                       System.out.println(new Date());
+                       e.printStackTrace();
+                       throw new DbDaoTransactionException(e);
+               }
+
+       }
+       
+       /**
+        * Normally this method should only be used in a JUnit test environment.
+        * Manually deletes all PDP records in droolspdpentity table.
+        */
+       public int deleteAllIntegrityAuditEntities() throws DbDaoTransactionException {
+               
+               try{
+                       
+                       if (!IntegrityAudit.isUnitTesting) {
+                               String msg = "DbDAO: " + "deleteAllIntegrityAuditEntities() " + "should only be invoked during JUnit testing";
+                               logger.error(msg);
+                               throw new DbDaoTransactionException(msg);
+                       }
+                       
+                       EntityManager em = emf.createEntityManager();
+                       // Start a transaction
+                       EntityTransaction et = em.getTransaction();
+
+                       et.begin();
+
+                       // if IntegrityAuditEntity entry exists for resourceName and PU, update it. If not found, create a new entry
+                       Query iaequery = em.createQuery("Delete from IntegrityAuditEntity");
+
+                       int returnCode = iaequery.executeUpdate();
+
+                       // commit transaction
+                       et.commit();
+                       em.close();
+                       
+                       logger.info("deleteAllIntegrityAuditEntities: returnCode=" + returnCode);
+
+                       return returnCode;
+
+               }catch (Exception e){
+                       String msg = "DbDAO: " + "deleteAllIntegrityAuditEntities() " + "encountered a problem in execution: ";
+                       logger.error(msg + e);
+                       System.out.println(new Date());
+                       e.printStackTrace();
+                       throw new DbDaoTransactionException(e);
+               }
+               
+       }
+       
+       /**
+        * Changes designation to specified resourceName
+        * 
+        * static lock object in conjunction with synchronized keyword ensures that
+        * designation changes are done serially within a resource. I.e. static lock
+        * ensures that multiple instantiations of DbDAO don't interleave
+        * changeDesignated() invocations and potentially produce simultaneous
+        * designations.
+        * 
+        * Optimistic locking (the default, versus pessimistic) is sufficient to
+        * avoid simultaneous designations from interleaved changeDesignated()
+        * invocations from different resources (entities), because it prevents
+        * "dirty" and "non-repeatable" reads.
+        * 
+        * See http://www.objectdb.com/api/java/jpa/LockModeType
+        * 
+        * and
+        * 
+        * http://stackoverflow.com/questions/2120248/how-to-synchronize-a-static-
+        * variable-among-threads-running-different-instances-o
+        */
+       public void changeDesignated(String resourceName, String persistenceUnit,
+                       String nodeType) throws DbDaoTransactionException {
+
+               if (logger.isDebugEnabled()) {
+                       logger.debug("changeDesignated: Entering, resourceName="
+                                       + resourceName + ", persistenceUnit=" + persistenceUnit
+                                       + ", nodeType=" + nodeType);
+               }
+
+               long startTime = System.currentTimeMillis();
+
+               synchronized (lock) {
+
+                       EntityManager em = null;
+                       try {
+
+                               em = emf.createEntityManager();
+                               em.getTransaction().begin();
+
+                               /*
+                                * Define query
+                                */
+                               Query query = em
+                                               .createQuery("Select i from IntegrityAuditEntity i where i.persistenceUnit=:pu and i.nodeType=:nt");
+                               query.setParameter("pu", persistenceUnit);
+                               query.setParameter("nt", nodeType);
+
+                               /*
+                                * Execute query using pessimistic write lock.  This ensures that if anyone else is currently reading
+                                * the records we'll throw a LockTimeoutException.
+                                */
+                               @SuppressWarnings("unchecked")
+                               List<IntegrityAuditEntity> integrityAuditEntityList = (List<IntegrityAuditEntity>) query
+                                               .getResultList();
+                               for (Object o : integrityAuditEntityList) {
+                                       if (o instanceof IntegrityAuditEntity) {
+                                               IntegrityAuditEntity integrityAuditEntity = (IntegrityAuditEntity) o;
+                                               if (integrityAuditEntity.getResourceName().equals(
+                                                               resourceName)) {
+                                                       if (logger.isDebugEnabled()) {
+                                                               logger.debug("changeDesignated: Designating resourceName="
+                                                                               + integrityAuditEntity
+                                                                                               .getResourceName());
+                                                       }
+                                                       integrityAuditEntity.setDesignated(true);
+                                               } else {
+                                                       if (logger.isDebugEnabled()) {
+                                                               logger.debug("changeDesignated: Removing designation from resourceName="
+                                                                               + integrityAuditEntity
+                                                                                               .getResourceName());
+                                                       }
+                                                       integrityAuditEntity.setDesignated(false);
+                                               }
+                                       }
+                               }
+                               
+                               if (logger.isDebugEnabled()) {
+                                       logger.debug("changeDesignated: Committing designation to resourceName="
+                                                       + resourceName);
+                               }
+                               em.getTransaction().commit();
+
+                               /*
+                                * If we get a LockTimeoutException, no harm done really. We'll
+                                * probably be successful on the next attempt. The odds of
+                                * another DbDAO instance on this entity or another entity
+                                * attempting a simultaneous IntegrityAuditEntity table
+                                * read/update are pretty slim (we're only in this method for
+                                * two or three milliseconds)
+                                */
+                       } catch (LockTimeoutException e) {
+                               em.getTransaction().rollback();
+                               String msg = "DbDAO: " + "changeDesignated() "
+                                               + "caught LockTimeoutException, message=" + e.getMessage();
+                               logger.error(msg + e);
+                               System.out.println(new Date());
+                               e.printStackTrace();
+                               throw new DbDaoTransactionException(msg, e);
+                       } catch (Exception e) {
+                               em.getTransaction().rollback();
+                               String msg = "DbDAO: " + "changeDesignated() "
+                                               + "caught Exception, message=" + e.getMessage();
+                               logger.error(msg + e);
+                               System.out.println(new Date());
+                               e.printStackTrace();
+                               throw new DbDaoTransactionException(msg, e);
+                       }
+
+               } // end synchronized block
+
+               if (logger.isDebugEnabled()) {
+                       logger.debug("changeDesignated: Exiting; time expended="
+                                       + (System.currentTimeMillis() - startTime) + "ms");
+               }
+
+       }
+
+
+}
diff --git a/integrity-audit/src/main/java/org/openecomp/policy/common/ia/DbDaoTransactionException.java b/integrity-audit/src/main/java/org/openecomp/policy/common/ia/DbDaoTransactionException.java
new file mode 100644 (file)
index 0000000..fc2fea0
--- /dev/null
@@ -0,0 +1,37 @@
+/*-
+ * ============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=========================================================
+ */
+
+package org.openecomp.policy.common.ia;
+
+public class DbDaoTransactionException extends Exception{
+       private static final long serialVersionUID = 1L;
+       public DbDaoTransactionException() {
+       }
+       public DbDaoTransactionException(String message) {
+               super(message);
+       }
+
+       public DbDaoTransactionException(Throwable cause) {
+               super(cause);
+       }
+       public DbDaoTransactionException(String message, Throwable cause) {
+               super(message, cause);
+       }
+}
diff --git a/integrity-audit/src/main/java/org/openecomp/policy/common/ia/IntegrityAudit.java b/integrity-audit/src/main/java/org/openecomp/policy/common/ia/IntegrityAudit.java
new file mode 100644 (file)
index 0000000..1dd260d
--- /dev/null
@@ -0,0 +1,241 @@
+/*-
+ * ============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=========================================================
+ */
+
+package org.openecomp.policy.common.ia;
+
+import java.util.Properties;
+
+//import org.apache.log4j.Logger;
+
+import org.openecomp.policy.common.ia.IntegrityAuditProperties.NodeTypeEnum;
+import org.openecomp.policy.common.logging.flexlogger.FlexLogger; 
+import org.openecomp.policy.common.logging.flexlogger.Logger; 
+
+/**
+ * class IntegrityAudit
+ * Audits all persisted entities for all resource clusters for all sites and logs any anomalies.
+ */
+public class IntegrityAudit {
+       
+       private static final Logger logger = FlexLogger.getLogger(IntegrityAudit.class);
+
+       public static boolean isUnitTesting;
+       private boolean isThreadInitialized = false; 
+       
+       AuditThread auditThread = null;
+               
+       private String persistenceUnit;
+       private Properties properties;
+       private String resourceName;
+       
+       
+       /*
+        * This is the audit period in seconds. For example, if it had a value of 3600, the audit
+        * can only run once per hour.  If it has a value of 60, it can run once per minute.
+        * 
+        * Values: 
+        *    integrityAuditPeriodSeconds < 0 (negative number) indicates the audit is off
+        *    integrityAuditPeriodSecconds == 0 indicates the audit is to run continuously
+        *    integrityAuditPeriodSeconds > 0 indicates the audit is to run at most once during the indicated period
+        * 
+        */
+       private int integrityAuditPeriodSeconds;
+       
+       /**
+        * IntegrityAudit constructor
+        * @param resourceName
+        * @param persistenceUnit
+        * @param properties
+        * @throws Exception
+        */
+       public IntegrityAudit(String resourceName, String persistenceUnit, Properties properties) throws Exception {
+               
+               logger.info("Constructor: Entering and checking for nulls");
+               String parmList = "";
+               if (parmsAreBad(resourceName, persistenceUnit, properties, parmList)) {
+                       logger.error("Constructor: Parms contain nulls; cannot run audit for resourceName="
+                                       + resourceName + ", persistenceUnit=" + persistenceUnit
+                                       + ", bad parameters: " + parmList);
+                       throw new Exception(
+                                       "Constructor: Parms contain nulls; cannot run audit for resourceName="
+                                                       + resourceName + ", persistenceUnit="
+                                                       + persistenceUnit
+                                                       + ", bad parameters: " + parmList);
+               }
+               
+               this.persistenceUnit = persistenceUnit;
+               this.properties = properties;
+               this.resourceName = resourceName;
+               
+               if(properties.getProperty(IntegrityAuditProperties.AUDIT_PERIOD_SECONDS) != null){ //It is allowed to be null
+                       this.integrityAuditPeriodSeconds= Integer.parseInt(properties.getProperty(IntegrityAuditProperties.AUDIT_PERIOD_SECONDS).trim());
+               } else{
+                       //If it is null, set it to the default value
+                       this.integrityAuditPeriodSeconds = IntegrityAuditProperties.DEFAULT_AUDIT_PERIOD_SECONDS;
+               }
+               logger.info("Constructor: Exiting");
+               
+       }
+       
+       /**
+        * Used during JUnit testing by AuditPeriodTest.java
+        */
+       public int getIntegrityAuditPeriodSeconds() {
+               return integrityAuditPeriodSeconds;
+       }
+
+       /**
+        * Determine if the nodeType conforms to the required node types
+        */
+       public static boolean isNodeTypeEnum(String nt) {
+               for (NodeTypeEnum n : NodeTypeEnum.values()) {
+                       if (n.toString().equals(nt)) {
+                               return true;
+                       }
+               }
+               return false;
+       }
+       
+
+       /**
+        * Makes sure we don't try to run the audit with bad parameters.
+        */
+       public static boolean parmsAreBad(String resourceName, String persistenceUnit,
+                       Properties properties, String badparams) {
+
+               boolean parmsAreBad = false;
+               
+               if(resourceName == null || resourceName.isEmpty()){
+                       badparams = badparams.concat("resourceName ");
+                       parmsAreBad = true;
+               }
+               
+               if(persistenceUnit == null || persistenceUnit.isEmpty()){
+                       badparams = badparams.concat("persistenceUnit ");
+                       parmsAreBad = true;
+               }
+               
+               String dbDriver = properties.getProperty(IntegrityAuditProperties.DB_DRIVER).trim();
+               if(dbDriver == null || dbDriver.isEmpty()){
+                       badparams = badparams.concat("dbDriver ");
+                       parmsAreBad = true;
+               }
+
+               String dbUrl = properties.getProperty(IntegrityAuditProperties.DB_URL).trim();
+               if(dbUrl == null || dbUrl.isEmpty()){
+                       badparams = badparams.concat("dbUrl ");
+                       parmsAreBad = true;
+               }
+               
+               String dbUser = properties.getProperty(IntegrityAuditProperties.DB_USER).trim();
+               if(dbUser == null || dbUser.isEmpty()){
+                       badparams = badparams.concat("dbUser ");
+                       parmsAreBad = true;
+               }
+               
+               String dbPwd = properties.getProperty(IntegrityAuditProperties.DB_PWD).trim();
+               if(dbPwd == null){ //may be empty
+                       badparams = badparams.concat("dbPwd ");
+                       parmsAreBad = true;
+               }
+               
+               String siteName = properties.getProperty(IntegrityAuditProperties.SITE_NAME).trim();
+               if(siteName == null || siteName.isEmpty()){
+                       badparams = badparams.concat("siteName ");
+                       parmsAreBad = true;
+               }
+               
+               String nodeType = properties.getProperty(IntegrityAuditProperties.NODE_TYPE).trim();
+               if(nodeType == null || nodeType.isEmpty()){
+                       badparams = badparams.concat("nodeType ");
+                       parmsAreBad = true;
+               } else {
+                       if (!isNodeTypeEnum(nodeType)) {
+                               String nodetypes = "nodeType must be one of[";
+                               for (NodeTypeEnum n : NodeTypeEnum.values()) {
+                                       nodetypes = nodetypes.concat(n.toString() + " ");
+                               }
+                               badparams = badparams.concat(nodetypes + "] ");
+                               parmsAreBad = true;
+                       }
+               }
+               if(properties.getProperty(IntegrityAuditProperties.AUDIT_PERIOD_SECONDS) != null){ //It is allowed to be null
+                       try{
+                               Integer.parseInt(properties.getProperty(IntegrityAuditProperties.AUDIT_PERIOD_SECONDS).trim());
+                       }catch(NumberFormatException nfe){
+                               badparams = badparams.concat(", auditPeriodSeconds=" 
+                                               + properties.getProperty(IntegrityAuditProperties.AUDIT_PERIOD_SECONDS).trim());
+                               parmsAreBad = true;
+                       }
+               }
+               logger.debug("parmsAreBad: exit:" 
+                               + "\nresourceName: " + resourceName
+                               + "\npersistenceUnit: " + persistenceUnit
+                               + "\nproperties: " + properties);
+               
+               return parmsAreBad;
+       }       
+       /**
+        * Starts the audit thread
+        * @throws Exception
+        */
+       public void startAuditThread() throws Exception {
+
+               logger.info("startAuditThread: Entering");
+               
+               if (integrityAuditPeriodSeconds >= 0) {
+                       this.auditThread = new AuditThread(this.resourceName,
+                                       this.persistenceUnit, this.properties,
+                                       integrityAuditPeriodSeconds, this);
+                       logger.info("startAuditThread: Audit started and will run every "
+                                       + integrityAuditPeriodSeconds + " seconds");
+                       this.auditThread.start();
+               } else {
+                       logger.info("startAuditThread: Suppressing integrity audit, integrityAuditPeriodSeconds="
+                                       + integrityAuditPeriodSeconds);
+               }
+
+               logger.info("startAuditThread: Exiting");
+       }
+       /**
+        * Stops the audit thread
+        */
+       public void stopAuditThread() {
+
+               logger.info("stopAuditThread: Entering");
+               
+               if (this.auditThread != null) {
+                       this.auditThread.interrupt();
+               } else {
+                       logger.info("stopAuditThread: auditThread never instantiated; no need to interrupt");
+               }
+               
+               logger.info("stopAuditThread: Exiting");
+       }
+
+       public boolean isThreadInitialized() {
+               return isThreadInitialized;
+       }
+
+       public void setThreadInitialized(boolean isThreadInitialized) {
+               logger.info("setThreadInitialized: Setting isThreadInitialized=" + isThreadInitialized);
+               this.isThreadInitialized = isThreadInitialized;
+       }
+}
diff --git a/integrity-audit/src/main/java/org/openecomp/policy/common/ia/IntegrityAuditProperties.java b/integrity-audit/src/main/java/org/openecomp/policy/common/ia/IntegrityAuditProperties.java
new file mode 100644 (file)
index 0000000..5a87c9c
--- /dev/null
@@ -0,0 +1,54 @@
+/*-
+ * ============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=========================================================
+ */
+
+package org.openecomp.policy.common.ia;
+
+public class IntegrityAuditProperties {
+
+       public static final String DEFAULT_DB_DRIVER = "org.h2.Driver";
+       public static final String DEFAULT_DB_URL = "jdbc:h2:file:./sql/iaTest";
+       public static final String DEFAULT_DB_USER = "sa";
+       public static final String DEFAULT_DB_PWD = "";
+       public static final int DEFAULT_AUDIT_PERIOD_SECONDS = -1; // Audit does not run
+       
+       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";
+       public static final String AUDIT_PERIOD_SECONDS = "integrity_audit_period_seconds";
+       
+       
+       public static final String SITE_NAME = "site_name";
+       public static final String NODE_TYPE = "node_type";
+       
+       public static enum NodeTypeEnum {
+               pdp_xacml,
+               pdp_drools,
+               pap,
+               pap_admin,
+               logparser,
+               brms_gateway,
+               astra_gateway,
+               elk_server,
+               pypdp
+
+       }
+       
+}
diff --git a/integrity-audit/src/main/java/org/openecomp/policy/common/ia/IntegrityAuditPropertiesException.java b/integrity-audit/src/main/java/org/openecomp/policy/common/ia/IntegrityAuditPropertiesException.java
new file mode 100644 (file)
index 0000000..77c8558
--- /dev/null
@@ -0,0 +1,37 @@
+/*-
+ * ============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=========================================================
+ */
+
+package org.openecomp.policy.common.ia;
+
+public class IntegrityAuditPropertiesException extends Exception{
+       private static final long serialVersionUID = 1L;
+       public IntegrityAuditPropertiesException() {
+       }
+       public IntegrityAuditPropertiesException(String message) {
+               super(message);
+       }
+
+       public IntegrityAuditPropertiesException(Throwable cause) {
+               super(cause);
+       }
+       public IntegrityAuditPropertiesException(String message, Throwable cause) {
+               super(message, cause);
+       }
+}
diff --git a/integrity-audit/src/main/java/org/openecomp/policy/common/ia/jpa/IntegrityAuditEntity.java b/integrity-audit/src/main/java/org/openecomp/policy/common/ia/jpa/IntegrityAuditEntity.java
new file mode 100644 (file)
index 0000000..3d50d83
--- /dev/null
@@ -0,0 +1,204 @@
+/*-
+ * ============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=========================================================
+ */
+
+package org.openecomp.policy.common.ia.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 for management of IntegrityAudits
+ */
+
+@Entity
+@Table(name="IntegrityAuditEntity")
+@NamedQueries({
+       @NamedQuery(name=" IntegrityAuditEntity.findAll", query="SELECT e FROM IntegrityAuditEntity e "),
+       @NamedQuery(name="IntegrityAuditEntity.deleteAll", query="DELETE FROM IntegrityAuditEntity WHERE 1=1")
+})
+
+public class IntegrityAuditEntity implements Serializable {
+       private static final long serialVersionUID = 1L;
+
+       public static boolean isUnitTesting;
+       
+       @Id
+       @GeneratedValue(strategy = GenerationType.AUTO)
+       @Column(name="id")
+       private long id;
+       
+       @Column(name="persistenceUnit", nullable=false)
+       private String persistenceUnit;
+       
+       @Column(name="site", nullable=true)
+       private String site;
+       
+       @Column(name="nodeType", nullable=true)
+       private String nodeType;
+       
+       @Column(name="resourceName", nullable=false, unique=true)
+       private String resourceName;
+       
+       @Column(name="designated", nullable=true)
+       private boolean designated = false;
+
+       @Column(name="jdbcDriver", nullable=false)
+       private String jdbcDriver;
+       
+       @Column(name="jdbcUrl", nullable=false)
+       private String jdbcUrl;
+       
+       @Column(name="jdbcUser", nullable=false)
+       private String jdbcUser;
+       
+       @Column(name="jdbcPassword", nullable=false)
+       private String jdbcPassword;
+       
+       @Temporal(TemporalType.TIMESTAMP)
+       @Column(name="createdDate", updatable=true)
+       private Date createdDate;
+       
+       @Temporal(TemporalType.TIMESTAMP)
+       @Column(name="lastUpdated")
+       private Date lastUpdated;
+
+       
+       public IntegrityAuditEntity() {
+       }
+
+       @PrePersist
+       public void     prePersist() {
+               Date date = new Date();
+               this.createdDate = date;
+               this.lastUpdated = date;
+       }
+       
+       @PreUpdate
+       public void preUpdate() {
+               if (!isUnitTesting) {
+                       this.lastUpdated = new Date();
+               }
+       }
+
+       public long getId() {
+               return id;
+       }
+
+       public String getPersistenceUnit() {
+               return persistenceUnit;
+       }
+
+       public void setPersistenceUnit(String persistenceUnit) {
+               this.persistenceUnit = persistenceUnit;
+       }
+
+       public String getSite() {
+               return site;
+       }
+
+       public void setSite(String site) {
+               this.site = site;
+       }
+
+       public String getNodeType() {
+               return nodeType;
+       }
+
+       public void setNodeType(String nodeType) {
+               this.nodeType = nodeType;
+       }
+
+       public String getResourceName() {
+               return resourceName;
+       }
+
+       public void setResourceName(String resourceName) {
+               this.resourceName = resourceName;
+       }
+
+       public boolean isDesignated() {
+               return designated;
+       }
+
+       public void setDesignated(boolean designated) {
+               this.designated = designated;
+       }
+
+       public String getJdbcDriver() {
+               return jdbcDriver;
+       }
+
+       public void setJdbcDriver(String jdbcDriver) {
+               this.jdbcDriver = jdbcDriver;
+       }
+
+       public String getJdbcUrl() {
+               return jdbcUrl;
+       }
+
+       public void setJdbcUrl(String jdbcUrl) {
+               this.jdbcUrl = jdbcUrl;
+       }
+
+       public String getJdbcUser() {
+               return jdbcUser;
+       }
+
+       public void setJdbcUser(String jdbcUser) {
+               this.jdbcUser = jdbcUser;
+       }
+
+       public String getJdbcPassword() {
+               return jdbcPassword;
+       }
+
+       public void setJdbcPassword(String jdbcPassword) {
+               this.jdbcPassword = jdbcPassword;
+       }
+
+       public Date getLastUpdated() {
+               return lastUpdated;
+       }
+
+       public void setLastUpdated(Date lastUpdated) {
+               this.lastUpdated = lastUpdated;
+       }
+
+       public Date getCreatedDate() {
+               return createdDate;
+       }
+       
+       public void setCreatedDate(Date created) {
+               this.createdDate = created;
+       }
+}
diff --git a/integrity-audit/src/main/resources/META-INF/persistence.xml b/integrity-audit/src/main/resources/META-INF/persistence.xml
new file mode 100644 (file)
index 0000000..31ffb4d
--- /dev/null
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ============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=========================================================
+  -->
+
+<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
+       <persistence-unit name="testPU" transaction-type="RESOURCE_LOCAL">
+       <!-- Limited use for generating the DB and schema files for iatest DB - uses eclipselink -->
+               <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
+               <class>org.openecomp.policy.common.ia.jpa.IntegrityAuditEntity</class>
+               <class>org.openecomp.policy.common.ia.test.jpa.IaTestEntity</class>
+               <shared-cache-mode>NONE</shared-cache-mode>
+               <properties>
+                       <property name="javax.persistence.schema-generation.database.action" value="drop-and-create"/>
+                       <property name="javax.persistence.schema-generation.scripts.action" value="drop-and-create"/> 
+            <property name="javax.persistence.schema-generation.scripts.create-target" value="./sql/generatedCreateIA.ddl"/>
+            <property name="javax.persistence.schema-generation.scripts.drop-target" value="./sql/generatedDropIA.ddl"/>
+        </properties>
+       </persistence-unit>
+
+       <persistence-unit name="integrityAuditPU" transaction-type="RESOURCE_LOCAL">
+       <!-- For operational use -->
+               <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
+               <class>org.openecomp.policy.common.ia.jpa.IntegrityAuditEntity</class>          
+               <shared-cache-mode>NONE</shared-cache-mode>     
+               <properties>
+                       <!-- none -->
+        </properties>
+       </persistence-unit>
+</persistence>
diff --git a/integrity-audit/src/main/resources/log4j.properties b/integrity-audit/src/main/resources/log4j.properties
new file mode 100644 (file)
index 0000000..65b9e55
--- /dev/null
@@ -0,0 +1,48 @@
+###
+# ============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=========================================================
+###
+
+#
+# Use this properties for debugging and development.
+#
+#
+# Set root logger level to DEBUG and its only appender to A1.
+log4j.rootLogger=INFO, FILE
+
+# A1 is set to be a DailyRollingFileAppender.
+log4j.appender.FILE=org.apache.log4j.DailyRollingFileAppender
+
+# Set the name of the file
+log4j.appender.FILE.File=IntegrityMonitor.log
+
+# Set the immediate flush to true (default)
+log4j.appender.FILE.ImmediateFlush=true
+
+# Set the threshold to debug mode
+log4j.appender.FILE.Threshold=debug
+
+# Set the append to false, should not overwrite
+log4j.appender.FILE.Append=true
+
+# Set the DatePattern
+log4j.appender.FILE.DatePattern='.'yyyy-MM-dd
+
+# A1 uses PatternLayout.
+log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
+log4j.appender.FILE.layout.ConversionPattern=%d{yyyy_MM_dd_HH_mm_ss_SSS} [%t] %-5p %l- %m%n
diff --git a/integrity-audit/src/main/resources/logback.xml b/integrity-audit/src/main/resources/logback.xml
new file mode 100644 (file)
index 0000000..426adf9
--- /dev/null
@@ -0,0 +1,205 @@
+<!--
+  ============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=========================================================
+  -->
+
+<configuration scan="true" scanPeriod="3 seconds" debug="true">
+  <!--<jmxConfigurator /> -->
+  <!-- directory path for all other type logs -->
+  <property name="logDir" value="logs" />
+  
+  <!-- directory path for debugging type logs -->
+  <property name="debugDir" value="logs" />
+  
+  <!--  specify the component name 
+    <ECOMP-component-name>::= "MSO" | "DCAE" | "ASDC " | "AAI" |"Policy" | "SDNC" | "AC"  -->
+  <property name="componentName" value="common-modules"></property>
+  <property name="subComponentName" value="integrity-audit"></property>
+  
+  <!--  log file names -->
+  <property name="errorLogName" value="error" />
+  <property name="metricsLogName" value="metrics" />
+  <property name="auditLogName" value="audit" />
+  <property name="debugLogName" value="debug" />
+  
+   <property name="defaultPattern" value="%d{&quot;yyyy-MM-dd'T'HH:mm:ss.SSSXXX&quot;, UTC}|%X{requestId}|%X{serviceInstanceId}|%t|%X{serverName}|%X{serviceName}|%X{instanceUuid}|%p|%X{severity}|%X{serverIpAddress}|%X{server}|%X{clientIpAddress}|%c||%msg%n" />
+   <!--  <property name="defaultPattern" value="%d{&quot;yyyy-MM-dd'T'HH:mm:ss.SSSXXX&quot;, UTC}|%X{RequestId}|%X{ServiceInstanceId}|%thread||%X{ServiceName}|%X{InstanceUUID}|%.-5level|%X{AlertSeverity}|%X{ServerIPAddress}|%X{ServerFQDN}|%X{RemoteHost}||%X{Timer}|%msg%n" />  -->
+  <property name="logDirectory" value="${logDir}/${componentName}/${subComponentName}" />
+  <property name="debugLogDirectory" value="${debugDir}/${componentName}/${subComponentName}" />
+   <!--
+  <property name="logDirectory" value="${logDir}/${componentName}/${subComponentName}" />
+  <property name="debugLogDirectory" value="${debugDir}/${componentName}/${subComponentName}" />
+  -->
+  <!-- example from old log4j.properties:  ${catalina.base}/logs/pdp-rest.log  -->  
+  <!-- Example evaluator filter applied against console appender -->
+  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+    <encoder>
+      <pattern>${defaultPattern}</pattern>
+    </encoder>
+  </appender>
+
+  <!-- ============================================================================ -->
+  <!-- EELF Appenders -->
+  <!-- ============================================================================ -->
+
+  <!-- The EELFAppender is used to record events to the general application 
+    log -->
+    
+    
+
+  
+  <!-- EELF Audit Appender. This appender is used to record audit engine 
+    related logging events. The audit logger and appender are specializations 
+    of the EELF application root logger and appender. This can be used to segregate 
+    Policy engine events from other components, or it can be eliminated to record 
+    these events as part of the application root log. -->
+    
+  <appender name="EELFAudit"
+    class="ch.qos.logback.core.rolling.RollingFileAppender">
+    <file>${logDirectory}/${auditLogName}.log</file>
+    <rollingPolicy
+      class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
+      <fileNamePattern>${logDirectory}/${auditLogName}.%i.log.zip
+      </fileNamePattern>
+      <minIndex>1</minIndex>
+      <maxIndex>9</maxIndex>
+    </rollingPolicy>
+    <triggeringPolicy
+      class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
+      <maxFileSize>5MB</maxFileSize>
+    </triggeringPolicy>
+    <encoder>
+         <pattern>${defaultPattern}</pattern>
+    </encoder>
+  </appender>
+  <appender name="asyncEELFAudit" class="ch.qos.logback.classic.AsyncAppender">
+    <queueSize>256</queueSize>
+    <appender-ref ref="EELFAudit" />
+  </appender>
+
+<appender name="EELFMetrics"
+    class="ch.qos.logback.core.rolling.RollingFileAppender">
+    <file>${logDirectory}/${metricsLogName}.log</file>
+    <rollingPolicy
+      class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
+      <fileNamePattern>${logDirectory}/${metricsLogName}.%i.log.zip
+      </fileNamePattern>
+      <minIndex>1</minIndex>
+      <maxIndex>9</maxIndex>
+    </rollingPolicy>
+    <triggeringPolicy
+      class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
+      <maxFileSize>5MB</maxFileSize>
+    </triggeringPolicy>
+    <encoder>
+      <!-- <pattern>"%d{HH:mm:ss.SSS} [%thread] %-5level %logger{1024} - 
+        %msg%n"</pattern> -->
+      <pattern>${defaultPattern}</pattern>
+    </encoder>
+  </appender>
+  
+  
+  <appender name="asyncEELFMetrics" class="ch.qos.logback.classic.AsyncAppender">
+    <queueSize>256</queueSize>
+    <appender-ref ref="EELFMetrics"/>
+  </appender>
+   
+  <appender name="EELFError"
+    class="ch.qos.logback.core.rolling.RollingFileAppender">
+    <file>${logDirectory}/${errorLogName}.log</file>
+    <rollingPolicy
+      class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
+      <fileNamePattern>${logDirectory}/${errorLogName}.%i.log.zip
+      </fileNamePattern>
+      <minIndex>1</minIndex>
+      <maxIndex>9</maxIndex>
+    </rollingPolicy>
+    <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
+     <level>ERROR</level>
+     </filter>
+    <triggeringPolicy
+      class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
+      <maxFileSize>5MB</maxFileSize>
+    </triggeringPolicy>
+    <encoder>
+      <pattern>${defaultPattern}</pattern>
+    </encoder>
+  </appender>
+  
+  <appender name="asyncEELFError" class="ch.qos.logback.classic.AsyncAppender">
+    <queueSize>256</queueSize>
+    <appender-ref ref="EELFError"/>
+  </appender>
+  
+   <appender name="EELFDebug"
+    class="ch.qos.logback.core.rolling.RollingFileAppender">
+    <file>${debugLogDirectory}/${debugLogName}.log</file>
+    <rollingPolicy
+      class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
+      <fileNamePattern>${debugLogDirectory}/${debugLogName}.%i.log.zip
+      </fileNamePattern>
+      <minIndex>1</minIndex>
+      <maxIndex>9</maxIndex>
+    </rollingPolicy>
+    <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
+     <level>INFO</level>
+     </filter>
+    <triggeringPolicy
+      class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
+      <maxFileSize>5MB</maxFileSize>
+    </triggeringPolicy>
+    <encoder>
+      <pattern>${defaultPattern}</pattern>
+    </encoder>
+  </appender>
+  
+  <appender name="asyncEELFDebug" class="ch.qos.logback.classic.AsyncAppender">
+    <queueSize>256</queueSize>
+    <appender-ref ref="EELFDebug" />
+    <includeCallerData>true</includeCallerData>
+  </appender>
+  
+  <!-- ============================================================================ -->
+  <!--  EELF loggers -->
+  <!-- ============================================================================ -->
+  <logger name="com.att.eelf.audit" level="info" additivity="false">
+    <appender-ref ref="asyncEELFAudit" />
+  </logger>
+  
+  <logger name="com.att.eelf.metrics" level="info" additivity="false">
+        <appender-ref ref="asyncEELFMetrics" />
+  </logger>
+    <logger name="com.att.eelf.error" level="error" additivity="false">
+  <appender-ref ref="asyncEELFError" />
+  </logger>
+  
+   <logger name="com.att.eelf.debug" level="info" additivity="false">
+        <appender-ref ref="asyncEELFDebug" />
+  </logger>
+  
+  
+  <!-- <root level="INFO"> -->
+  <root level="INFO">
+        <appender-ref ref="asyncEELFDebug" />
+        <appender-ref ref="asyncEELFError" />
+  </root>
+
+</configuration>
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
new file mode 100644 (file)
index 0000000..649b71f
--- /dev/null
@@ -0,0 +1,475 @@
+/*-
+ * ============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=========================================================
+ */
+
+package org.openecomp.policy.common.ia.test;
+
+
+import static org.junit.Assert.*;
+
+import java.io.BufferedReader;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Properties;
+
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.EntityTransaction;
+import javax.persistence.Persistence;
+
+//import org.apache.commons.logging.Log;
+//import org.apache.commons.logging.LogFactory;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+
+import org.openecomp.policy.common.ia.AuditThread;
+import org.openecomp.policy.common.ia.IntegrityAudit;
+import org.openecomp.policy.common.ia.IntegrityAuditProperties;
+import org.openecomp.policy.common.logging.flexlogger.FlexLogger; 
+import org.openecomp.policy.common.logging.flexlogger.Logger;
+
+public class AuditPeriodTest {
+       
+       private static Logger logger = FlexLogger.getLogger(AuditPeriodTest.class);
+       
+       private static final String AUDIT_PERIOD_TEST_LOG = "./testingLogs/common-modules/integrity-audit/debug.log";
+               
+       private static String persistenceUnit;
+       private static Properties properties;
+       private static String resourceName;
+       
+       @Before
+       public void setUp() throws Exception {
+
+               
+               System.out.println("setUp: Clearing " + AUDIT_PERIOD_TEST_LOG);
+               FileOutputStream fstream = new FileOutputStream(AUDIT_PERIOD_TEST_LOG);
+               fstream.close();
+
+               logger.info("setUp: Entering");
+
+               IntegrityAudit.isUnitTesting = true;
+               
+               properties = new Properties();
+               properties.put(IntegrityAuditProperties.DB_DRIVER, IntegrityAuditProperties.DEFAULT_DB_DRIVER);
+               properties.put(IntegrityAuditProperties.DB_URL, IntegrityAuditProperties.DEFAULT_DB_URL);
+               properties.put(IntegrityAuditProperties.DB_USER, IntegrityAuditProperties.DEFAULT_DB_USER);
+               properties.put(IntegrityAuditProperties.DB_PWD, IntegrityAuditProperties.DEFAULT_DB_PWD);
+               properties.put(IntegrityAuditProperties.SITE_NAME, "SiteA");
+               properties.put(IntegrityAuditProperties.NODE_TYPE, "pdp_xacml");
+                               
+               persistenceUnit = "testPU";
+               resourceName = "pdp1";
+               
+               //Clean up the DB               
+               EntityManagerFactory emf = Persistence.createEntityManagerFactory(persistenceUnit, properties);
+               
+               EntityManager em = emf.createEntityManager();
+               // Start a transaction
+               EntityTransaction et = em.getTransaction();
+
+               et.begin();
+
+               // if IntegrityAuditEntity entry exists for resourceName and PU, update it. If not found, create a new entry
+               em.createQuery("Delete from IntegrityAuditEntity").executeUpdate();
+
+               // commit transaction
+               et.commit();
+               em.close();
+               
+               logger.info("setUp: Exiting");
+               
+       }
+       
+
+       @After
+       public void tearDown() throws Exception {
+               
+               logger.info("tearDown: Entering");
+                               
+               logger.info("tearDown: Exiting");
+
+       }
+
+       /*
+        * Verifies (via log parsing) that when a negative audit period is
+        * specified, the audit is suppressed.
+        */
+       @Ignore
+       @Test
+       public void testNegativeAuditPeriod() throws Exception {
+               
+               logger.info("testNegativeAuditPeriod: Entering");
+               
+               properties.put(IntegrityAuditProperties.AUDIT_PERIOD_SECONDS, "-1");
+
+               IntegrityAudit integrityAudit = new IntegrityAudit(resourceName, persistenceUnit, properties);
+               integrityAudit.startAuditThread();
+               
+               /*
+                * Sleep long enough to allow
+                * 
+                * 1) audit to immediately terminate.
+                */
+               Thread.sleep(1000);
+               
+               logger.info("testNegativeAuditPeriod: Stopping audit thread (should be a no-op!)");
+               integrityAudit.stopAuditThread();
+
+               FileInputStream fstream = new FileInputStream(AUDIT_PERIOD_TEST_LOG);
+               BufferedReader br = new BufferedReader(new InputStreamReader(fstream));
+               String strLine;
+               int startIndex;
+               ArrayList<String> expectedResult = new ArrayList<String>(Arrays.asList("-1"));
+               ArrayList<String> delegates = new ArrayList<String>();
+               while ((strLine = br.readLine()) != null)   {
+                       /* parse strLine to obtain what you want */
+                       if (strLine.contains("Suppressing integrity audit, integrityAuditPeriodSeconds=")) {
+                               startIndex = strLine.indexOf("integrityAuditPeriodSeconds=") + 28;
+                               
+                               String integrityAuditPeriodSeconds = strLine.substring(startIndex);
+                               
+                               delegates.add(integrityAuditPeriodSeconds);
+                       }
+               }
+                               
+               for (String delegate: delegates) {
+                       logger.info("testNegativeAuditPeriod: delegate: " + delegate);
+               }
+               
+               fstream.close();
+                               
+               assertTrue(expectedResult.equals(delegates));
+               
+               logger.info("testNegativeAuditPeriod: Exiting");
+
+       }
+       
+       /*
+        * Verifies (via log parsing) that when an audit period of zero is
+        * specified, the audit runs continuously, generating a number of
+        * sleep/wake sequences in a short period of time (e.g. 100ms).
+        */
+       @Ignore
+       @Test
+       public void testZeroAuditPeriod() throws Exception {
+
+               logger.info("testZeroAuditPeriod: Entering");
+
+               properties.put(IntegrityAuditProperties.AUDIT_PERIOD_SECONDS, "0");
+
+               IntegrityAudit integrityAudit = new IntegrityAudit(resourceName,
+                               persistenceUnit, properties);
+               integrityAudit.startAuditThread();
+
+               /*
+                * Sleep long enough to allow
+                * 
+                * 1) audit to generate a bunch of sleep wake sequences.
+                * 
+                * Note:
+                * 
+                * (AuditThread.AUDIT_SIMULATION_SLEEP_INTERVAL *
+                * AuditThread.AUDIT_SIMULATION_ITERATIONS) is the time it takes for the
+                * audit simulation to run.
+                * 
+                * (integrityAudit.getIntegrityAuditPeriodSeconds() should return a
+                * value of zero; i.e. audit should not sleep at all between iterations
+                * 
+                * "100"ms is the time we allow the audit to cycle continuously
+                */
+               long sleepMillis = (AuditThread.AUDIT_SIMULATION_SLEEP_INTERVAL * AuditThread.AUDIT_SIMULATION_ITERATIONS)
+                               + (integrityAudit.getIntegrityAuditPeriodSeconds() * 1000)
+                               + 100;
+               logger.info("testZeroAuditPeriod: Sleeping " + sleepMillis + "ms before stopping auditThread");
+               Thread.sleep(sleepMillis);
+               
+               logger.info("testZeroAuditPeriod: Stopping audit thread");
+               integrityAudit.stopAuditThread();
+
+               /*
+                * Before audit completion message upon awaking from sleep is upper case "Awaking".  After audit
+                * completion, all awakings are lower case "awaking".
+                */
+               logger.info("testZeroAuditPeriod: Parsing " + AUDIT_PERIOD_TEST_LOG + " for 'awaking'");
+               FileInputStream fstream = new FileInputStream(AUDIT_PERIOD_TEST_LOG);
+               BufferedReader br = new BufferedReader(new InputStreamReader(fstream));
+               String strLine = "";
+               int awakings = 0;
+               int lines = 0;
+               while ((strLine = br.readLine()) != null) {
+                       if (strLine.contains("Awaking from 0ms sleep")) {
+                               fail("Audit appears not to have run!?  Got '" + strLine + "'");
+                       } else {
+                               if (strLine.contains("awaking from 0ms sleep")) {
+                                       awakings++;
+                               }
+                       }
+                       lines++;
+               }
+               logger.info("testZeroAuditPeriod: Done parsing "
+                               + AUDIT_PERIOD_TEST_LOG + " for 'awaking'; lines parsed="
+                               + lines + ", closing stream");
+               fstream.close();
+
+               /*
+                * We should get at least 10 sleep/wake sequences.
+                */
+               assertTrue("Only " + awakings + " awakings", awakings > 10);
+               assertTrue(integrityAudit.getIntegrityAuditPeriodSeconds() == 0);
+
+               logger.info("testZeroAuditPeriod: Exiting, awakings="
+                               + awakings + ", integrityAuditPeriodSeconds="
+                               + integrityAudit.getIntegrityAuditPeriodSeconds());
+
+       }
+       
+       /*
+        * Verifies (via log parsing) that when an audit period of five minutes is
+        * specified, there is a five minute interval between the audits run
+        * on each of three different entities.
+        */
+       @Ignore
+       @Test
+       public void testFiveMinuteAuditPeriod() throws Exception {
+
+               logger.info("testFiveMinuteAuditPeriod: Entering");
+
+               properties.put(IntegrityAuditProperties.AUDIT_PERIOD_SECONDS, "300");
+
+               /*
+                * Start audit for pdp1.
+                */
+               IntegrityAudit integrityAudit = new IntegrityAudit(resourceName,
+                               persistenceUnit, properties);
+               integrityAudit.startAuditThread();
+               
+               /*
+                * Start audit for pdp2.
+                */
+               Properties properties2 = new Properties();
+               properties2.put(IntegrityAuditProperties.DB_DRIVER, IntegrityAuditProperties.DEFAULT_DB_DRIVER);
+               properties2.put(IntegrityAuditProperties.DB_URL, IntegrityAuditProperties.DEFAULT_DB_URL);
+               properties2.put(IntegrityAuditProperties.DB_USER, IntegrityAuditProperties.DEFAULT_DB_USER);
+               properties2.put(IntegrityAuditProperties.DB_PWD, IntegrityAuditProperties.DEFAULT_DB_PWD);
+               properties2.put(IntegrityAuditProperties.SITE_NAME, "SiteA");
+               properties2.put(IntegrityAuditProperties.NODE_TYPE, "pdp_xacml");
+               properties2.put(IntegrityAuditProperties.AUDIT_PERIOD_SECONDS, "300");
+               String persistenceUnit2 = "testPU";
+               String resourceName2 = "pdp2";
+               IntegrityAudit integrityAudit2 = new IntegrityAudit(resourceName2, persistenceUnit2, properties2);
+               integrityAudit2.startAuditThread();
+               
+               /*
+                * Start audit for pdp3.
+                */
+               Properties properties3 = new Properties();
+               properties3.put(IntegrityAuditProperties.DB_DRIVER, IntegrityAuditProperties.DEFAULT_DB_DRIVER);
+               properties3.put(IntegrityAuditProperties.DB_URL, IntegrityAuditProperties.DEFAULT_DB_URL);
+               properties3.put(IntegrityAuditProperties.DB_USER, IntegrityAuditProperties.DEFAULT_DB_USER);
+               properties3.put(IntegrityAuditProperties.DB_PWD, IntegrityAuditProperties.DEFAULT_DB_PWD);
+               properties3.put(IntegrityAuditProperties.SITE_NAME, "SiteA");
+               properties3.put(IntegrityAuditProperties.NODE_TYPE, "pdp_xacml");
+               properties3.put(IntegrityAuditProperties.AUDIT_PERIOD_SECONDS, "300");
+               String persistenceUnit3 = "testPU";
+               String resourceName3 = "pdp3";
+               IntegrityAudit integrityAudit3 = new IntegrityAudit(resourceName3, persistenceUnit3, properties3);
+               integrityAudit3.startAuditThread();
+
+
+               /*
+                * 1) All three audit run once.  This should take approximately 105 seconds, as follows:
+                * 
+                * T0: pdp1 runs audit (15 seconds), then sleeps for five minutes (300 seconds)
+                * pdp2 recognizes that pdp1 is stale (30 seconds) and runs its audit (15 seconds)
+                * pdp3 recognizes that pdp2 is stale (30 seconds) and runs its audit (15 seconds)
+                * 
+                * 2) Five minutes after T0, at T1, pdp1 wakes up and the above sequence begins again,
+                * which should take another 115 seconds:
+                * 
+                * T1: pdp1 runs audit (15 seconds), then sleeps for two minutes (300 seconds)
+                * pdp2 wakes up, resets auditCompleted and sleeps (5 seconds), recognizes that pdp1 is stale (30 seconds) and runs its audit (15 seconds)
+                * pdp3 wakes up, resets auditCompleted and sleeps (5 seconds), recognizes that pdp2 is stale (30 seconds) and runs its audit (15 seconds)
+                * 
+                * So, the entire sequence should take 15 + 300 + 115 = 430 seconds
+                * Adding a fudge factor, we sleep for 450 seconds
+                */
+               Thread.sleep(450000);
+               
+               
+               logger.info("testFiveMinuteAuditPeriod: Stopping all three audit threads");
+               integrityAudit.stopAuditThread();
+
+               integrityAudit.stopAuditThread();
+               integrityAudit2.stopAuditThread();
+               integrityAudit3.stopAuditThread();
+
+               FileInputStream fstream = new FileInputStream(AUDIT_PERIOD_TEST_LOG);
+               BufferedReader br = new BufferedReader(new InputStreamReader(fstream));
+               String strLine;
+               int startIndex;
+               int endIndex;
+               ArrayList<String> expectedResult = new ArrayList<String>(Arrays.asList("pdp1", "pdp2", "pdp3", "pdp1", "pdp2", "pdp3"));
+               ArrayList<String> delegates = new ArrayList<String>();
+               while ((strLine = br.readLine()) != null)   {
+                       /* parse strLine to obtain what you want */
+                       if (strLine.contains("Starting audit simulation for resourceName=")) {
+                               startIndex = strLine.indexOf("resourceName=") + 13;
+                               endIndex = strLine.indexOf(",");
+                               
+                               String rName = strLine.substring(startIndex, endIndex);
+                               
+                               delegates.add(rName);
+                       }
+               }
+                               
+               for (String delegate: delegates) {
+                       logger.info("testFiveMinuteAuditPeriod: delegate: " + delegate);
+               }
+               
+               fstream.close();
+               
+               assertTrue("delegate count only " + delegates.size(), delegates.size() >= 6);
+               assertTrue("delegate 0 is " + expectedResult.get(0), expectedResult.get(0).equals(delegates.get(0)));
+               assertTrue("delegate 1 is " + expectedResult.get(1), expectedResult.get(1).equals(delegates.get(1)));
+               assertTrue("delegate 2 is " + expectedResult.get(2), expectedResult.get(2).equals(delegates.get(2)));
+               assertTrue("delegate 3 is " + expectedResult.get(3), expectedResult.get(3).equals(delegates.get(3)));
+               assertTrue("delegate 4 is " + expectedResult.get(4), expectedResult.get(4).equals(delegates.get(4)));
+               assertTrue("delegate 5 is " + expectedResult.get(5), expectedResult.get(5).equals(delegates.get(5)));
+                               
+               logger.info("testFiveMinuteAuditPeriod: Exiting");
+       }
+       
+       /*
+        * Verifies (via log parsing) that when an audit period of 20 seconds is
+        * specified, there is a 20 second interval between the audits run
+        * on each of three different entities.
+        */
+       @Ignore
+       @Test
+       public void testTwentySecondAuditPeriod() throws Exception {
+
+               logger.info("testTwentySecondAuditPeriod: Entering");
+
+               properties.put(IntegrityAuditProperties.AUDIT_PERIOD_SECONDS, "20");
+
+               /*
+                * Start audit for pdp1.
+                */
+               IntegrityAudit integrityAudit = new IntegrityAudit(resourceName,
+                               persistenceUnit, properties);
+               integrityAudit.startAuditThread();
+               
+               /*
+                * Start audit for pdp2.
+                */
+               Properties properties2 = new Properties();
+               properties2.put(IntegrityAuditProperties.DB_DRIVER, IntegrityAuditProperties.DEFAULT_DB_DRIVER);
+               properties2.put(IntegrityAuditProperties.DB_URL, IntegrityAuditProperties.DEFAULT_DB_URL);
+               properties2.put(IntegrityAuditProperties.DB_USER, IntegrityAuditProperties.DEFAULT_DB_USER);
+               properties2.put(IntegrityAuditProperties.DB_PWD, IntegrityAuditProperties.DEFAULT_DB_PWD);
+               properties2.put(IntegrityAuditProperties.SITE_NAME, "SiteA");
+               properties2.put(IntegrityAuditProperties.NODE_TYPE, "pdp_xacml");
+               properties2.put(IntegrityAuditProperties.AUDIT_PERIOD_SECONDS, "20");
+               String persistenceUnit2 = "testPU";
+               String resourceName2 = "pdp2";
+               IntegrityAudit integrityAudit2 = new IntegrityAudit(resourceName2, persistenceUnit2, properties2);
+               integrityAudit2.startAuditThread();
+               
+               /*
+                * Start audit for pdp3.
+                */
+               Properties properties3 = new Properties();
+               properties3.put(IntegrityAuditProperties.DB_DRIVER, IntegrityAuditProperties.DEFAULT_DB_DRIVER);
+               properties3.put(IntegrityAuditProperties.DB_URL, IntegrityAuditProperties.DEFAULT_DB_URL);
+               properties3.put(IntegrityAuditProperties.DB_USER, IntegrityAuditProperties.DEFAULT_DB_USER);
+               properties3.put(IntegrityAuditProperties.DB_PWD, IntegrityAuditProperties.DEFAULT_DB_PWD);
+               properties3.put(IntegrityAuditProperties.SITE_NAME, "SiteA");
+               properties3.put(IntegrityAuditProperties.NODE_TYPE, "pdp_xacml");
+               properties3.put(IntegrityAuditProperties.AUDIT_PERIOD_SECONDS, "20");
+               String persistenceUnit3 = "testPU";
+               String resourceName3 = "pdp3";
+               IntegrityAudit integrityAudit3 = new IntegrityAudit(resourceName3, persistenceUnit3, properties3);
+               integrityAudit3.startAuditThread();
+
+
+               /*
+                * 1) All three audit run once.
+                * 
+                * pdp1 runs audit (15 seconds), then goes into 20 second sleep cycles
+                * pdp2 recognizes that pdp1 is stale (30 seconds), runs its audit (15 seconds), then goes into 20 second sleep cycles
+                * pdp3 recognizes that pdp2 is stale (30 seconds), runs its audit (15 seconds), then goes into 20 second sleep cycles 
+                * 
+                * 2) Eventually pdp2 gets stale, pdp1 recognizes this and cycle begins again. 
+                * 
+                * So, we allow 15 + (5 * 45) = 240 seconds plus a fudge factor.
+                * 
+                */
+               Thread.sleep(250000);
+               
+               
+               logger.info("testTwentySecondAuditPeriod: Stopping all three audit threads");
+               integrityAudit.stopAuditThread();
+
+               integrityAudit.stopAuditThread();
+               integrityAudit2.stopAuditThread();
+               integrityAudit3.stopAuditThread();
+
+               FileInputStream fstream = new FileInputStream(AUDIT_PERIOD_TEST_LOG);
+               BufferedReader br = new BufferedReader(new InputStreamReader(fstream));
+               String strLine;
+               int startIndex;
+               int endIndex;
+               ArrayList<String> expectedResult = new ArrayList<String>(Arrays.asList("pdp1", "pdp2", "pdp3", "pdp1", "pdp2", "pdp3"));
+               ArrayList<String> delegates = new ArrayList<String>();
+               while ((strLine = br.readLine()) != null)   {
+                       /* parse strLine to obtain what you want */
+                       if (strLine.contains("Starting audit simulation for resourceName=")) {
+                               startIndex = strLine.indexOf("resourceName=") + 13;
+                               endIndex = strLine.indexOf(",");
+                               
+                               String rName = strLine.substring(startIndex, endIndex);
+                               
+                               delegates.add(rName);
+                       }
+               }
+                               
+               for (String delegate: delegates) {
+                       logger.info("testTwentySecondAuditPeriod: delegate: " + delegate);
+               }
+               
+               fstream.close();
+               
+               assertTrue("delegate count only " + delegates.size(), delegates.size() >= 6);
+               assertTrue("delegate 0 is " + expectedResult.get(0), expectedResult.get(0).equals(delegates.get(0)));
+               assertTrue("delegate 1 is " + expectedResult.get(1), expectedResult.get(1).equals(delegates.get(1)));
+               assertTrue("delegate 2 is " + expectedResult.get(2), expectedResult.get(2).equals(delegates.get(2)));
+               assertTrue("delegate 3 is " + expectedResult.get(3), expectedResult.get(3).equals(delegates.get(3)));
+               assertTrue("delegate 4 is " + expectedResult.get(4), expectedResult.get(4).equals(delegates.get(4)));
+               assertTrue("delegate 5 is " + expectedResult.get(5), expectedResult.get(5).equals(delegates.get(5)));
+                               
+               logger.info("testTwentySecondAuditPeriod: Exiting");
+       }
+       
+}
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
new file mode 100644 (file)
index 0000000..92483c5
--- /dev/null
@@ -0,0 +1,615 @@
+/*-
+ * ============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=========================================================
+ */
+
+package org.openecomp.policy.common.ia.test;
+
+import static org.junit.Assert.*;
+
+import java.io.FileOutputStream;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Properties;
+
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.EntityTransaction;
+import javax.persistence.Persistence;
+
+
+//import org.apache.commons.logging.Log;
+//import org.apache.commons.logging.LogFactory;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+
+import org.openecomp.policy.common.ia.DbAudit;
+import org.openecomp.policy.common.ia.DbDAO;
+import org.openecomp.policy.common.ia.IntegrityAudit;
+import org.openecomp.policy.common.ia.IntegrityAuditProperties;
+import org.openecomp.policy.common.ia.jpa.IntegrityAuditEntity;
+import org.openecomp.policy.common.ia.test.jpa.IaTestEntity;
+import org.openecomp.policy.common.ia.test.jpa.PersonTest;
+import org.openecomp.policy.common.logging.flexlogger.FlexLogger; 
+import org.openecomp.policy.common.logging.flexlogger.Logger;
+
+public class DbAuditCompareEntriesTest {
+
+       private static Logger logger = FlexLogger.getLogger(DbAuditCompareEntriesTest.class);
+       private DbDAO dbDAO;
+       private static String persistenceUnit;
+       private static Properties properties;
+       private static String resourceName;
+       private String dbDriver;
+       private String dbUrl;
+       private String dbUser;
+       private String dbPwd;
+       private String siteName;
+       private String nodeType;
+       private static final String TEST_LOG = "./testingLogs/common-modules/integrity-audit/debug.log";
+       
+       @Before
+       public void setUp() throws Exception {
+               System.out.println("setUp: Clearing IntegrityAudit.log");
+               //FileOutputStream fstream = new FileOutputStream("IntegrityAudit.log");
+               FileOutputStream fstream = new FileOutputStream(TEST_LOG);
+               fstream.close();
+
+               logger.info("setUp: Entering");
+
+               IntegrityAudit.isUnitTesting = true;
+               
+               properties = new Properties();
+               properties.put(IntegrityAuditProperties.DB_DRIVER, IntegrityAuditProperties.DEFAULT_DB_DRIVER);
+               properties.put(IntegrityAuditProperties.DB_URL, IntegrityAuditProperties.DEFAULT_DB_URL);
+               properties.put(IntegrityAuditProperties.DB_USER, IntegrityAuditProperties.DEFAULT_DB_USER);
+               properties.put(IntegrityAuditProperties.DB_PWD, IntegrityAuditProperties.DEFAULT_DB_PWD);
+               properties.put(IntegrityAuditProperties.SITE_NAME, "SiteA");
+               properties.put(IntegrityAuditProperties.NODE_TYPE, "pdp_xacml");
+
+               dbDriver = IntegrityAuditProperties.DEFAULT_DB_DRIVER;
+               dbUrl = IntegrityAuditProperties.DEFAULT_DB_URL;
+               dbUser = IntegrityAuditProperties.DEFAULT_DB_USER;
+               dbPwd = IntegrityAuditProperties.DEFAULT_DB_PWD;
+               siteName = "SiteA";
+               nodeType = "pdp_xacml";
+               persistenceUnit = "testPU";
+               resourceName = "pdp1";
+                               
+               logger.info("setUp: Exiting");
+       }
+
+       /*
+        * Clean up DB after each test.
+        */
+       @After
+       public void tearDown() throws Exception {
+               logger.info("tearDown: Entering");
+       
+               logger.info("tearDown: Exiting");
+       }
+
+       /*
+        * Tests that a comparison between hashsets is successful if
+        * the entries match
+        */
+       //@Ignore
+       @Test
+       public void testSuccessfulComparison() throws Exception {
+               logger.info("testSuccessfulComparison: Entering");
+               
+               dbDAO = new DbDAO(resourceName, persistenceUnit, properties);
+               DbAudit dbAudit = new DbAudit(dbDAO);
+               
+               String className = null;
+               //There is only one entry IntegrityAuditEntity, but we will check anyway
+               HashSet<String> classNameSet = dbDAO.getPersistenceClassNames();
+               for(String c : classNameSet){
+                       if (c.equals("org.openecomp.policy.common.ia.jpa.IntegrityAuditEntity")){
+                               className = c;
+                       }
+               }
+               String resourceName1 = resourceName;
+               String resourceName2 = resourceName;
+               
+               IntegrityAuditEntity entry1 = new IntegrityAuditEntity();
+               IntegrityAuditEntity entry2 = new IntegrityAuditEntity();
+               Date date = new Date();
+               
+               /*
+                * Two entries with the same field values
+                */
+               entry1.setDesignated(false);
+               entry1.setJdbcDriver(dbDriver);
+               entry1.setJdbcPassword(dbPwd);
+               entry1.setJdbcUrl(dbUrl);
+               entry1.setJdbcUser(dbUser);
+               entry1.setLastUpdated(date);
+               entry1.setNodeType(nodeType);
+               entry1.setPersistenceUnit(persistenceUnit);
+               entry1.setResourceName(resourceName1);
+               entry1.setSite(siteName);
+               
+               entry2.setDesignated(false);
+               entry2.setJdbcDriver(dbDriver);
+               entry2.setJdbcPassword(dbPwd);
+               entry2.setJdbcUrl(dbUrl);
+               entry2.setJdbcUser(dbUser);
+               entry2.setLastUpdated(date);
+               entry2.setNodeType(nodeType);
+               entry2.setPersistenceUnit(persistenceUnit);
+               entry2.setResourceName(resourceName2);
+               entry2.setSite(siteName);
+               
+               dbAudit.writeAuditDebugLog(className, resourceName1, resourceName2, entry1, entry2);
+               
+               HashMap<Object, Object> myEntries = new HashMap<Object, Object>();
+               HashMap<Object, Object> theirEntries = new HashMap<Object, Object>();
+               
+               myEntries.put("pdp1", entry1);
+               theirEntries.put("pdp1", entry2);
+                               
+               HashSet<Object> result = dbAudit.compareEntries(myEntries, theirEntries);
+               
+               /*
+                * Assert that there are no mismatches returned
+                */
+               assertTrue(result.isEmpty());
+               
+               logger.info("testSuccessfulComparison: Exit");
+       }
+
+       /*
+        * Tests that an error is detected if an entry in one hashset doesn't
+        * match the other
+        */
+       //@Ignore
+       @Test
+       public void testComparisonError() throws Exception {
+               logger.info("testComparisonError: Entering");
+               
+               dbDAO = new DbDAO(resourceName, persistenceUnit, properties);
+               DbAudit dbAudit = new DbAudit(dbDAO);
+               
+               String resourceName1 = resourceName;
+               String resourceName2 = resourceName;
+               
+               IntegrityAuditEntity entry1 = new IntegrityAuditEntity();
+               IntegrityAuditEntity entry2 = new IntegrityAuditEntity();
+               Date date = new Date();
+               
+               /*
+                * Create two entries with different designated values
+                */
+               entry1.setDesignated(false);
+               entry1.setJdbcDriver(dbDriver);
+               entry1.setJdbcPassword(dbPwd);
+               entry1.setJdbcUrl(dbUrl);
+               entry1.setJdbcUser(dbUser);
+               entry1.setLastUpdated(date);
+               entry1.setNodeType(nodeType);
+               entry1.setPersistenceUnit(persistenceUnit);
+               entry1.setResourceName(resourceName1);
+               entry1.setSite(siteName);
+               
+               entry2.setDesignated(true);
+               entry2.setJdbcDriver(dbDriver);
+               entry2.setJdbcPassword(dbPwd);
+               entry2.setJdbcUrl(dbUrl);
+               entry2.setJdbcUser(dbUser);
+               entry2.setLastUpdated(date);
+               entry2.setNodeType(nodeType);
+               entry2.setPersistenceUnit(persistenceUnit);
+               entry2.setResourceName(resourceName2);
+               entry2.setSite(siteName);
+                               
+               HashMap<Object, Object> myEntries = new HashMap<Object, Object>();
+               HashMap<Object, Object> theirEntries = new HashMap<Object, Object>();
+               
+               myEntries.put("pdp1", entry1);
+               theirEntries.put("pdp1", entry2);
+               
+               HashSet<Object> result = dbAudit.compareEntries(myEntries, theirEntries);
+               
+               /*
+                * Assert that there was one mismatch
+                */
+               assertEquals(1, result.size());
+               
+               logger.info("testComparisonError: Exit");
+       }
+       
+       /*
+        * Tests that a mismatch/miss entry is detected if there are missing entries in 
+        * one or both of the hashsets
+        */
+       //@Ignore
+       @Test
+       public void testCompareMissingEntries() throws Exception {
+               logger.info("testCompareMissingEntries: Entering");
+       
+               dbDAO = new DbDAO(resourceName, persistenceUnit, properties);
+               DbAudit dbAudit = new DbAudit(dbDAO);
+               
+               String resourceName1 = resourceName;
+               String resourceName2 = resourceName;
+               
+               IntegrityAuditEntity entry1 = new IntegrityAuditEntity();
+               IntegrityAuditEntity entry2 = new IntegrityAuditEntity();
+               IntegrityAuditEntity entry3 = new IntegrityAuditEntity();
+               IntegrityAuditEntity entry4 = new IntegrityAuditEntity();
+               
+               Date date = new Date();
+               
+               /*
+                * 4 entries, one mismatch, two miss entries
+                */
+               entry1.setDesignated(false);
+               entry1.setJdbcDriver(dbDriver);
+               entry1.setJdbcPassword(dbPwd);
+               entry1.setJdbcUrl(dbUrl);
+               entry1.setJdbcUser(dbUser);
+               entry1.setLastUpdated(date);
+               entry1.setNodeType(nodeType);
+               entry1.setPersistenceUnit(persistenceUnit);
+               entry1.setResourceName(resourceName1);
+               entry1.setSite(siteName);
+               
+               entry2.setDesignated(true);
+               entry2.setJdbcDriver(dbDriver);
+               entry2.setJdbcPassword(dbPwd);
+               entry2.setJdbcUrl(dbUrl);
+               entry2.setJdbcUser(dbUser);
+               entry2.setLastUpdated(date);
+               entry2.setNodeType(nodeType);
+               entry2.setPersistenceUnit(persistenceUnit);
+               entry2.setResourceName(resourceName2);
+               entry2.setSite(siteName);
+               
+               entry3.setDesignated(false);
+               entry3.setJdbcDriver(dbDriver);
+               entry3.setJdbcPassword(dbPwd);
+               entry3.setJdbcUrl(dbUrl);
+               entry3.setJdbcUser(dbUser);
+               entry3.setLastUpdated(date);
+               entry3.setNodeType(nodeType);
+               entry3.setPersistenceUnit(persistenceUnit);
+               entry3.setResourceName(resourceName2);
+               entry3.setSite("SiteB");
+               
+               entry4.setDesignated(false);
+               entry4.setJdbcDriver(dbDriver);
+               entry4.setJdbcPassword(dbPwd);
+               entry4.setJdbcUrl(dbUrl);
+               entry4.setJdbcUser(dbUser);
+               entry4.setLastUpdated(date);
+               entry4.setNodeType(nodeType);
+               entry4.setPersistenceUnit(persistenceUnit);
+               entry4.setResourceName(resourceName2);
+               entry4.setSite("SiteB");
+
+               HashMap<Object, Object> myEntries = new HashMap<Object, Object>();
+               HashMap<Object, Object> theirEntries = new HashMap<Object, Object>();
+               
+               myEntries.put("0", entry1);
+               myEntries.put("1", entry3);
+               theirEntries.put("0", entry2);
+               theirEntries.put("2", entry4);
+               
+               HashSet<Object> mismatchResult = dbAudit.compareEntries(myEntries, theirEntries);
+               
+               /*
+                * Assert 3 mismatches/missing entries were found
+                */
+               assertEquals(3, mismatchResult.size());
+               
+               logger.info("testCompareMissingEntries: Exit");
+       }
+       
+       /*
+        * Tests that comparison algorithm works for each entity in the hashsets 
+        */
+       //@Ignore
+       @Test
+       public void testCompareAllHashEntities() throws Exception {
+               logger.info("testCompareAllHashEntities: Entering");
+               
+               dbDAO = new DbDAO(resourceName, persistenceUnit, properties);
+               DbAudit dbAudit = new DbAudit(dbDAO);
+               
+               @SuppressWarnings("unused")
+               String className = null;
+               HashSet<String> classNameSet = dbDAO.getPersistenceClassNames();
+               HashSet<Object> mismatchResult = new HashSet<Object>();
+               for(String c : classNameSet) {
+                       className = c;
+                       if (c.equals("org.openecomp.policy.common.ia.jpa.IntegrityAuditEntity")){
+                               String resourceName1 = resourceName;
+                               String resourceName2 = resourceName;
+                               
+                               IntegrityAuditEntity entry1 = new IntegrityAuditEntity();
+                               IntegrityAuditEntity entry2 = new IntegrityAuditEntity();
+                               Date date = new Date();
+                               
+                               /*
+                                * Two entries with the same field values
+                                */
+                               entry1.setDesignated(false);
+                               entry1.setJdbcDriver(dbDriver);
+                               entry1.setJdbcPassword(dbPwd);
+                               entry1.setJdbcUrl(dbUrl);
+                               entry1.setJdbcUser(dbUser);
+                               entry1.setLastUpdated(date);
+                               entry1.setNodeType(nodeType);
+                               entry1.setPersistenceUnit(persistenceUnit);
+                               entry1.setResourceName(resourceName1);
+                               entry1.setSite(siteName);
+                               
+                               entry2.setDesignated(false);
+                               entry2.setJdbcDriver(dbDriver);
+                               entry2.setJdbcPassword(dbPwd);
+                               entry2.setJdbcUrl(dbUrl);
+                               entry2.setJdbcUser(dbUser);
+                               entry2.setLastUpdated(date);
+                               entry2.setNodeType(nodeType);
+                               entry2.setPersistenceUnit(persistenceUnit);
+                               entry2.setResourceName(resourceName2);
+                               entry2.setSite(siteName);
+                               
+                               HashMap<Object, Object> myEntries = new HashMap<Object, Object>();
+                               HashMap<Object, Object> theirEntries = new HashMap<Object, Object>();
+                               
+                               myEntries.put("pdp1", entry1);
+                               theirEntries.put("pdp1", entry2);
+                                               
+                               mismatchResult = dbAudit.compareEntries(myEntries, theirEntries);
+                               
+                               /*
+                                * Assert there was no mismatches
+                                */
+                               assertTrue(mismatchResult.isEmpty());
+                       }
+                       else if (c.equals("org.openecomp.policy.common.ia.test.jpa.IaTestEntity")) {
+                               IaTestEntity iate = new IaTestEntity();
+                               IaTestEntity iate2 = new IaTestEntity();
+                               IaTestEntity iate3 = new IaTestEntity();
+                               IaTestEntity iate4 = new IaTestEntity();
+                               
+                               Date date = new Date();
+                               
+                               /*
+                                * Four entries, 2 mismatches
+                                */
+                               iate.setCreatedBy("Ford");
+                               iate.setModifiedBy("Ford");
+                               iate.setModifiedDate(date);
+                               
+                               iate2.setCreatedBy("Ford");
+                               iate2.setModifiedBy("Zaphod");
+                               iate2.setModifiedDate(date);
+                               
+                               iate3.setCreatedBy("Zaphod");
+                               iate3.setModifiedBy("Ford");
+                               iate3.setModifiedDate(date);
+                               
+                               iate4.setCreatedBy("Ford");
+                               iate4.setModifiedBy("Ford");
+                               iate4.setModifiedDate(date);
+                               
+                               HashMap<Object, Object> myEntries = new HashMap<Object, Object>();
+                               HashMap<Object, Object> theirEntries = new HashMap<Object, Object>();
+                               
+                               myEntries.put("0", iate);
+                               myEntries.put("1", iate2);
+                               theirEntries.put("0", iate3);
+                               theirEntries.put("1", iate4);
+                               
+                               mismatchResult = dbAudit.compareEntries(myEntries, theirEntries);
+                               
+                               /*
+                                * Assert that there is 2 mismatches
+                                */
+                               assertEquals(2, mismatchResult.size());
+                       }
+               }
+               
+               logger.info("testCompareAllHashEntities: Exit");
+       }
+       
+       /*
+        * Tests that comparison algorithm works for each entity in the database 
+        */
+       //@Ignore
+       @Test
+       public void testCompareAllDbEntities() throws Exception {
+               logger.info("testCompareAllDbEntities: Entering");
+
+               logger.info("Setting up DB");
+
+               IntegrityAudit.isUnitTesting = true;
+               
+               properties = new Properties();
+               properties.put(IntegrityAuditProperties.DB_DRIVER, IntegrityAuditProperties.DEFAULT_DB_DRIVER);
+               properties.put(IntegrityAuditProperties.DB_URL, IntegrityAuditProperties.DEFAULT_DB_URL);
+               properties.put(IntegrityAuditProperties.DB_USER, IntegrityAuditProperties.DEFAULT_DB_USER);
+               properties.put(IntegrityAuditProperties.DB_PWD, IntegrityAuditProperties.DEFAULT_DB_PWD);
+               properties.put(IntegrityAuditProperties.SITE_NAME, "SiteA");
+               properties.put(IntegrityAuditProperties.NODE_TYPE, "pdp_xacml");
+
+               Properties properties2 = new Properties();
+               properties2.put(IntegrityAuditProperties.DB_DRIVER, IntegrityAuditProperties.DEFAULT_DB_DRIVER);
+               properties2.put(IntegrityAuditProperties.DB_URL, "jdbc:h2:file:./sql/iaTest2");
+               properties2.put(IntegrityAuditProperties.DB_USER, IntegrityAuditProperties.DEFAULT_DB_USER);
+               properties2.put(IntegrityAuditProperties.DB_PWD, IntegrityAuditProperties.DEFAULT_DB_PWD);
+               properties2.put(IntegrityAuditProperties.SITE_NAME, "SiteA");
+               properties2.put(IntegrityAuditProperties.NODE_TYPE, "pdp_xacml");
+               
+               dbDriver = IntegrityAuditProperties.DEFAULT_DB_DRIVER;
+               dbUrl = IntegrityAuditProperties.DEFAULT_DB_URL;
+               dbUser = IntegrityAuditProperties.DEFAULT_DB_USER;
+               dbPwd = IntegrityAuditProperties.DEFAULT_DB_PWD;
+               siteName = "SiteA";
+               nodeType = "pdp_xacml";
+               persistenceUnit = "testPU";
+               resourceName = "pdp1";
+               
+               //Clean up the two DBs
+               EntityManagerFactory emf = Persistence.createEntityManagerFactory(persistenceUnit, properties);
+               EntityManagerFactory emf2 = Persistence.createEntityManagerFactory(persistenceUnit, properties2);
+               
+               EntityManager em = emf.createEntityManager();
+               EntityManager em2 = emf2.createEntityManager();
+               // Start a transaction
+               EntityTransaction et = em.getTransaction();
+               EntityTransaction et2 = em2.getTransaction();
+
+               /*
+                * Delete entries in first DB
+                */
+               et.begin();
+
+               // Clean the IntegrityAuditEntity table
+               em.createQuery("Delete from IntegrityAuditEntity").executeUpdate();
+
+               // commit transaction
+               et.commit();
+               
+               et.begin();
+
+               // Clean the IaTestEntity table
+               em.createQuery("Delete from IaTestEntity").executeUpdate();
+
+               // commit transaction
+               et.commit();
+               em.close();
+               
+               /*
+                * Delete entries in second DB
+                */
+               et2.begin();
+
+               // Clean the IntegrityAuditEntity table
+               em2.createQuery("Delete from IntegrityAuditEntity").executeUpdate();
+
+               // commit transaction
+               et2.commit();
+               
+               et2.begin();
+
+               // Clean the IaTestEntity table
+               em2.createQuery("Delete from IaTestEntity").executeUpdate();
+
+               // commit transaction
+               et2.commit();
+               em2.close();
+               logger.info("Exiting set up");
+               
+               // Add entries into DB1
+               dbDAO = new DbDAO(resourceName, persistenceUnit, properties);
+               DbDAO dbDAO2 = new DbDAO("pdp2", persistenceUnit, properties);
+               DbAudit dbAudit = new DbAudit(dbDAO);
+               
+               // Add entries into DB2
+               DbDAO dbDAO3 = new DbDAO(resourceName, persistenceUnit, properties2);
+               DbDAO dbDAO4 = new DbDAO("pdp2", persistenceUnit, properties2);
+               
+               // Pull all entries and compare
+               HashSet<String> classNameSet = dbDAO.getPersistenceClassNames();
+               HashMap<Object, Object> myEntries;
+               HashMap<Object, Object> theirEntries;
+               HashSet<Object> mismatchResult = new HashSet<Object>();
+               String className;
+               for(String c : classNameSet) {
+                       className = c;
+                       logger.info("classNameSet entry = " + c);
+                       myEntries = dbDAO.getAllEntries(persistenceUnit, properties, className);
+                       theirEntries = dbDAO3.getAllEntries(persistenceUnit, properties2, className);
+                       mismatchResult = dbAudit.compareEntries(myEntries, theirEntries);
+                       if(className.contains("IntegrityAuditEntity")){
+                               break;
+                       }
+               }
+               
+               // Assert that there is 2 mismatches between IntegrityAuditEntity tables
+               assertEquals(2, mismatchResult.size());
+               
+               logger.info("testCompareAllDbEntities: Exit");
+       }
+       
+       /*
+        * Tests that differences in embedded classes are still caught  
+        */
+       //@Ignore
+       @Test
+       public void testEmbeddedClass() throws Exception {
+               logger.info("testEmbeddedClasses: Entering");
+               
+               dbDAO = new DbDAO(resourceName, persistenceUnit, properties);
+               DbAudit dbAudit = new DbAudit(dbDAO);
+               
+               String className = null;
+               //There is only one entry IntegrityAuditEntity, but we will check anyway
+               HashSet<String> classNameSet = dbDAO.getPersistenceClassNames();
+               for(String c : classNameSet){
+                       if (c.equals("org.openecomp.policy.common.ia.test.jpa.IaTestEntity")){
+                               className = c;
+                       }
+               }
+               
+               IaTestEntity iate = new IaTestEntity();
+               IaTestEntity iate2 = new IaTestEntity();
+               
+               Date date = new Date();
+               
+               PersonTest person = new PersonTest("Ford", "Prefect", 21);
+               PersonTest person2 = new PersonTest("Zaphod", "Beeblebrox", 25);
+               
+               /*
+                * Two entries, 1 mismatch
+                */
+               iate.setCreatedBy("Ford");
+               iate.setModifiedBy("Zaphod");
+               iate.setModifiedDate(date);
+               iate.setPersonTest(person);
+               
+               iate2.setCreatedBy("Ford");
+               iate2.setModifiedBy("Zaphod");
+               iate2.setModifiedDate(date);
+               iate2.setPersonTest(person2);
+               
+               dbAudit.writeAuditDebugLog(className, "resource1", "resource2", iate, iate2);
+               
+               HashMap<Object, Object> myEntries = new HashMap<Object, Object>();
+               HashMap<Object, Object> theirEntries = new HashMap<Object, Object>();
+               
+               myEntries.put("0", iate);
+               theirEntries.put("0", iate2);
+                               
+               HashSet<Object> result = dbAudit.compareEntries(myEntries, theirEntries);
+               
+               /*
+                * Assert that there are no mismatches returned
+                */
+               assertTrue(!result.isEmpty());
+               
+               logger.info("testEmbeddedClasses: Exit");
+       }
+}
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
new file mode 100644 (file)
index 0000000..f94dc21
--- /dev/null
@@ -0,0 +1,749 @@
+/*-
+ * ============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=========================================================
+ */
+
+package org.openecomp.policy.common.ia.test;
+
+import static org.junit.Assert.*;
+
+import java.io.BufferedReader;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.InputStreamReader;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Properties;
+
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.EntityTransaction;
+import javax.persistence.Persistence;
+import javax.persistence.Query;
+
+
+//import org.apache.commons.logging.Log;
+//import org.apache.commons.logging.LogFactory;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+
+import org.openecomp.policy.common.ia.DbAudit;
+import org.openecomp.policy.common.ia.DbAuditException;
+import org.openecomp.policy.common.ia.DbDAO;
+import org.openecomp.policy.common.ia.DbDaoTransactionException;
+import org.openecomp.policy.common.ia.IntegrityAudit;
+import org.openecomp.policy.common.ia.IntegrityAuditProperties;
+import org.openecomp.policy.common.ia.jpa.IntegrityAuditEntity;
+import org.openecomp.policy.common.logging.flexlogger.FlexLogger; 
+import org.openecomp.policy.common.logging.flexlogger.Logger;
+
+public class DbAuditTest {
+       
+       private static Logger logger = FlexLogger.getLogger(DbAuditTest.class);
+       
+       private DbDAO dbDAO;
+       private static String persistenceUnit;
+       private static Properties properties;
+       private static String resourceName;
+       private String dbDriver;
+       private String dbUrl;
+       private String dbUser;
+       private String dbPwd;
+       private String siteName;
+       private String nodeType;
+       private static final String TEST_LOG = "./testingLogs/common-modules/integrity-audit/debug.log";
+       private static final String ERROR_LOG = "./testingLogs/common-modules/integrity-audit/error.log";
+       
+       public void cleanLog() throws Exception{
+               
+               logger.debug("cleanLog: enter");
+               //FileOutputStream fstream = new FileOutputStream("IntegrityAudit.log");
+               FileOutputStream fstream = new FileOutputStream(TEST_LOG);
+               fstream.close();
+               fstream = new FileOutputStream(ERROR_LOG);
+               fstream.close();
+               logger.debug("cleanLog: exit");
+       }
+       
+       public void cleanDb(String persistenceUnit, Properties properties){
+               logger.debug("cleanDb: enter");
+
+               EntityManagerFactory emf = Persistence.createEntityManagerFactory(persistenceUnit, properties);
+               
+               EntityManager em = emf.createEntityManager();
+               // Start a transaction
+               EntityTransaction et = em.getTransaction();
+
+               et.begin();
+
+               // Clean up the DB
+               em.createQuery("Delete from IntegrityAuditEntity").executeUpdate();
+
+               // commit transaction
+               et.commit();
+               em.close();
+               logger.debug("cleanDb: exit");
+       }
+       
+
+       @Before
+       public void setUp() throws Exception {
+
+               logger.info("setUp: Entering");
+
+               IntegrityAudit.isUnitTesting = true;
+               IntegrityAuditEntity.isUnitTesting = true;
+               
+               properties = new Properties();
+               properties.put(IntegrityAuditProperties.DB_DRIVER, IntegrityAuditProperties.DEFAULT_DB_DRIVER);
+               properties.put(IntegrityAuditProperties.DB_URL, IntegrityAuditProperties.DEFAULT_DB_URL);
+               properties.put(IntegrityAuditProperties.DB_USER, IntegrityAuditProperties.DEFAULT_DB_USER);
+               properties.put(IntegrityAuditProperties.DB_PWD, IntegrityAuditProperties.DEFAULT_DB_PWD);
+               properties.put(IntegrityAuditProperties.SITE_NAME, "SiteA");
+               properties.put(IntegrityAuditProperties.NODE_TYPE, "pdp_xacml");
+
+               dbDriver = IntegrityAuditProperties.DEFAULT_DB_DRIVER;
+               dbUrl = IntegrityAuditProperties.DEFAULT_DB_URL;
+               dbUser = IntegrityAuditProperties.DEFAULT_DB_USER;
+               dbPwd = IntegrityAuditProperties.DEFAULT_DB_PWD;
+               siteName = "SiteA";
+               nodeType = "pdp_xacml";
+               persistenceUnit = "testPU";
+               resourceName = "pdp1";
+               
+               logger.info("setUp: Exiting");
+               
+       }
+       
+       @After
+       public void tearDown() throws Exception {
+               
+               logger.info("tearDown: Entering");
+               
+               //cleanDb(persistenceUnit, properties);
+               
+               logger.info("tearDown: Exiting");
+       }
+       
+       //@Ignore
+       @Test
+       public void runAllTests() throws Exception{
+               //The order is important - I haven't figured out why, but it is.
+               mismatchTest();
+               noEntitiesTest();
+               oneEntityTest();
+       }
+
+
+       /*
+        * Tests printing an error to the log in the event where
+        * there are no entities saved in the database
+        */
+       public void noEntitiesTest() throws Exception {
+               cleanLog();
+               cleanDb(persistenceUnit, properties);
+               
+               logger.info("noEntitiesTest: Entering");
+               
+               // Boolean to assert there are no entries found
+               Boolean noEntities = false;
+               
+               dbDAO = new DbDAO(resourceName, persistenceUnit, properties);
+               dbDAO.deleteAllIntegrityAuditEntities();
+               try {
+                       DbAudit dbAudit = new DbAudit(dbDAO);
+                       dbAudit.dbAudit(resourceName, persistenceUnit, nodeType);
+               }
+               catch (DbAuditException e) {
+                       noEntities = true;
+               }
+               
+               dbDAO.deleteAllIntegrityAuditEntities();
+               
+               logger.info("noEntitiesTest: No entities are persisted in the database");
+               
+               // Assert there are no entities retrieved
+               assertTrue(noEntities);
+               
+               logger.info("noEntitiesTest: Exit");
+       }
+       
+       /*
+        * Tests the detection of only one entry in the database
+        */
+       public void oneEntityTest() throws Exception{
+               cleanLog();
+               cleanDb(persistenceUnit, properties);
+               
+               logger.info("oneEntityTest: Entering");
+       
+               // Add one entry in the database
+               dbDAO = new DbDAO(resourceName, persistenceUnit, properties);
+               DbAudit dbAudit = new DbAudit(dbDAO);
+               dbAudit.dbAudit(resourceName, persistenceUnit, nodeType);
+               
+               List<IntegrityAuditEntity> iaeList = dbDAO.getIntegrityAuditEntities(persistenceUnit, nodeType);
+               logger.info("List size: " + iaeList.size());
+               
+               //FileInputStream fstream = new FileInputStream("IntegrityAudit.log");
+               FileInputStream fstream = new FileInputStream(TEST_LOG);
+               BufferedReader br = new BufferedReader(new InputStreamReader(fstream));
+               String strLine;
+               Boolean oneEntity = false;
+               while ((strLine = br.readLine()) != null)   {
+                        //parse strLine to obtain what you want 
+
+                       if (strLine.contains("DbAudit: Found only one IntegrityAuditEntity entry:")) {
+                               oneEntity = true;
+                       }
+
+               }
+               if(oneEntity){
+                       logger.info("oneEntityTest: One entity is persisted in the database");
+               }else{
+                       logger.info("oneEntityTest: No entities are persisted in the database");
+               }
+               
+               
+               // Assert there is only one entry
+               assertTrue(oneEntity);
+               
+               br.close();
+               
+               logger.info("oneEntityTest: Exit");
+       }
+       
+       /*
+        * Tests reporting mismatches and misentries using the error log
+        */
+       @SuppressWarnings("unused")
+       public void mismatchTest() throws Exception{
+               cleanLog();
+               logger.info("mismatchTest: Entering");
+
+               // Properties for DB2
+               Properties properties2 = new Properties();
+               properties2.put(IntegrityAuditProperties.DB_DRIVER, IntegrityAuditProperties.DEFAULT_DB_DRIVER);
+               properties2.put(IntegrityAuditProperties.DB_URL, "jdbc:h2:file:./sql/iaTest2");
+               properties2.put(IntegrityAuditProperties.DB_USER, IntegrityAuditProperties.DEFAULT_DB_USER);
+               properties2.put(IntegrityAuditProperties.DB_PWD, IntegrityAuditProperties.DEFAULT_DB_PWD);
+               properties2.put(IntegrityAuditProperties.SITE_NAME, "SiteA");
+               properties2.put(IntegrityAuditProperties.NODE_TYPE, "pdp_xacml");
+       
+               //Clean the DBs before we begin
+               cleanDb(persistenceUnit, properties);
+               cleanDb(persistenceUnit, properties2);
+               
+               // Entries in DB1
+               dbDAO = new DbDAO(resourceName, persistenceUnit, properties);
+               DbDAO dbDAO2 = new DbDAO("pdp2", persistenceUnit, properties);
+               
+               /*
+                * dbDAO3 is a mismatch entry, dbDAO7 is a misentry
+                */
+               DbDAO dbDAO3 = new DbDAO("pdp3", persistenceUnit, properties);
+               DbDAO dbDAO7 = new DbDAO("pdp4", persistenceUnit, properties);
+               Date date = new Date();
+               
+               EntityManagerFactory emf = Persistence.createEntityManagerFactory(persistenceUnit, properties);
+               
+               /*
+                * Update DB url's in DB1 to point to DB2
+                */
+               try{
+                       EntityManager em = emf.createEntityManager();
+                       // Start a transaction
+                       EntityTransaction et = em.getTransaction();
+
+                       et.begin();
+
+                       // if IntegrityAuditEntity entry exists for resourceName and PU, update it. If not found, create a new entry
+                       Query iaequery = em.createQuery("Select i from IntegrityAuditEntity i where i.resourceName=:rn and i.persistenceUnit=:pu");
+                       iaequery.setParameter("rn", "pdp2");
+                       iaequery.setParameter("pu", persistenceUnit);
+
+                       @SuppressWarnings("rawtypes")
+                       List iaeList = iaequery.getResultList();
+                       IntegrityAuditEntity iae = null;
+
+                       //If it already exists, we just want to update the properties and lastUpdated date
+                       if(!iaeList.isEmpty()){
+                               //ignores multiple results
+                               iae = (IntegrityAuditEntity) iaeList.get(0);
+                               // refresh the object from DB in case cached data was returned
+                               em.refresh(iae);
+                               logger.info("Resource: " + "pdp2" + " with PersistenceUnit: " + persistenceUnit 
+                                               + " exists and entry be updated");
+                       }else{
+                               // If it does not exist, we also must add teh resourceName, persistenceUnit and designated values
+                               logger.info("Adding resource " + "pdp2" + " with PersistenceUnit: " + persistenceUnit
+                                               + " to IntegrityAuditEntity table");    
+                               iae = new IntegrityAuditEntity();
+                               iae.setResourceName("pdp2");
+                               iae.setPersistenceUnit(persistenceUnit);
+                               iae.setDesignated(false);
+                       }
+                       
+                       //update/set properties in entry
+                       iae.setSite(siteName);
+                       iae.setNodeType(nodeType);
+                       iae.setLastUpdated(date);
+                       iae.setCreatedDate(date);
+                       iae.setJdbcDriver(dbDriver);
+                       iae.setJdbcPassword(dbPwd);
+                       iae.setJdbcUrl("jdbc:h2:file:./sql/iaTest2");
+                       iae.setJdbcUser(dbUser);
+
+                       em.persist(iae);
+                       // flush to the DB
+                       em.flush();
+
+                       // commit transaction
+                       et.commit();
+                       
+                       et.begin();
+
+                       // if IntegrityAuditEntity entry exists for resourceName and PU, update it. If not found, create a new entry
+                       iaequery = em.createQuery("Select i from IntegrityAuditEntity i where i.resourceName=:rn and i.persistenceUnit=:pu");
+                       iaequery.setParameter("rn", "pdp1");
+                       iaequery.setParameter("pu", persistenceUnit);
+
+                       @SuppressWarnings("rawtypes")
+                       List iaeList2 = iaequery.getResultList();
+                       iae = null;
+
+                       //If it already exists, we just want to update the properties and lastUpdated date
+                       if(!iaeList2.isEmpty()){
+                               //ignores multiple results
+                               iae = (IntegrityAuditEntity) iaeList2.get(0);
+                               // refresh the object from DB in case cached data was returned
+                               em.refresh(iae);
+                               logger.info("Resource: " + "pdp1" + " with PersistenceUnit: " + persistenceUnit 
+                                               + " exists and entry be updated");
+                       }else{
+                               // If it does not exist, we also must add teh resourceName, persistenceUnit and designated values
+                               logger.info("Adding resource " + "pdp1" + " with PersistenceUnit: " + persistenceUnit
+                                               + " to IntegrityAuditEntity table");    
+                               iae = new IntegrityAuditEntity();
+                               iae.setResourceName("pdp1");
+                               iae.setPersistenceUnit(persistenceUnit);
+                               iae.setDesignated(false);
+                       }
+                       
+                       //update/set properties in entry
+                       iae.setSite(siteName);
+                       iae.setNodeType(nodeType);
+                       iae.setLastUpdated(date);
+                       iae.setCreatedDate(date);
+                       iae.setJdbcDriver(dbDriver);
+                       iae.setJdbcPassword(dbPwd);
+                       iae.setJdbcUrl("jdbc:h2:file:./sql/iaTest2");
+                       iae.setJdbcUser(dbUser);
+                       
+                       em.persist(iae);
+                       // flush to the DB
+                       em.flush();
+
+                       // commit transaction
+                       et.commit();
+                       
+                       et.begin();
+
+                       // if IntegrityAuditEntity entry exists for resourceName and PU, update it. If not found, create a new entry
+                       iaequery = em.createQuery("Select i from IntegrityAuditEntity i where i.resourceName=:rn and i.persistenceUnit=:pu");
+                       iaequery.setParameter("rn", "pdp3");
+                       iaequery.setParameter("pu", persistenceUnit);
+
+                       @SuppressWarnings("rawtypes")
+                       List iaeList3 = iaequery.getResultList();
+                       iae = null;
+
+                       //If it already exists, we just want to update the properties and lastUpdated date
+                       if(!iaeList3.isEmpty()){
+                               //ignores multiple results
+                               iae = (IntegrityAuditEntity) iaeList3.get(0);
+                               // refresh the object from DB in case cached data was returned
+                               em.refresh(iae);
+                               logger.info("Resource: " + "pdp3" + " with PersistenceUnit: " + persistenceUnit 
+                                               + " exists and entry be updated");
+                       }else{
+                               // If it does not exist, we also must add the resourceName, persistenceUnit and designated values
+                               logger.info("Adding resource " + "pdp3" + " with PersistenceUnit: " + persistenceUnit
+                                               + " to IntegrityAuditEntity table");    
+                               iae = new IntegrityAuditEntity();
+                               iae.setResourceName("pdp3");
+                               iae.setPersistenceUnit(persistenceUnit);
+                               iae.setDesignated(false);
+                       }
+                       
+                       //update/set properties in entry
+                       iae.setSite(siteName);
+                       iae.setNodeType(nodeType);
+                       iae.setLastUpdated(date);
+                       iae.setCreatedDate(date);
+                       iae.setJdbcDriver(dbDriver);
+                       iae.setJdbcPassword(dbPwd);
+                       iae.setJdbcUrl(dbUrl);
+                       iae.setJdbcUser(dbUser);
+                       
+                       em.persist(iae);
+                       // flush to the DB
+                       em.flush();
+
+                       // commit transaction
+                       et.commit();
+                       
+                       et.begin();
+
+                       // if IntegrityAuditEntity entry exists for resourceName and PU, update it. If not found, create a new entry
+                       iaequery = em.createQuery("Select i from IntegrityAuditEntity i where i.resourceName=:rn and i.persistenceUnit=:pu");
+                       iaequery.setParameter("rn", "pdp4");
+                       iaequery.setParameter("pu", persistenceUnit);
+
+                       @SuppressWarnings("rawtypes")
+                       List iaeList4 = iaequery.getResultList();
+                       iae = null;
+
+                       //If it already exists, we just want to update the properties and lastUpdated date
+                       if(!iaeList4.isEmpty()){
+                               //ignores multiple results
+                               iae = (IntegrityAuditEntity) iaeList4.get(0);
+                               // refresh the object from DB in case cached data was returned
+                               em.refresh(iae);
+                               logger.info("Resource: " + "pdp4" + " with PersistenceUnit: " + persistenceUnit 
+                                               + " exists and entry be updated");
+                       }else{
+                               // If it does not exist, we also must add the resourceName, persistenceUnit and designated values
+                               logger.info("Adding resource " + "pdp4" + " with PersistenceUnit: " + persistenceUnit
+                                               + " to IntegrityAuditEntity table");    
+                               iae = new IntegrityAuditEntity();
+                               iae.setResourceName("pdp4");
+                               iae.setPersistenceUnit(persistenceUnit);
+                               iae.setDesignated(false);
+                       }
+                       
+                       //update/set properties in entry
+                       iae.setSite(siteName);
+                       iae.setNodeType(nodeType);
+                       iae.setLastUpdated(date);
+                       iae.setCreatedDate(date);
+                       iae.setJdbcDriver(dbDriver);
+                       iae.setJdbcPassword(dbPwd);
+                       iae.setJdbcUrl("jdbc:h2:file:./sql/iaTest2");
+                       iae.setJdbcUser(dbUser);
+                       
+                       em.persist(iae);
+                       // flush to the DB
+                       em.flush();
+
+                       // commit transaction
+                       et.commit();
+                       
+                       em.close();
+               }catch (Exception e){
+                       String msg = "DbDAO: " + "register() " + "ecountered a problem in execution: ";
+                       logger.error(msg + e);
+                       throw new DbDaoTransactionException(e);
+               }
+               
+               /* 
+                * Identical entries in from DB1 in DB2 except for dbDAO6
+                */
+               emf = Persistence.createEntityManagerFactory(persistenceUnit, properties2);
+               DbDAO dbDAO4 = new DbDAO(resourceName, persistenceUnit, properties2);
+               
+               DbDAO dbDAO5 = new DbDAO("pdp2", persistenceUnit, properties2);
+               
+               /*
+                * This is the mismatch entry
+                */
+               DbDAO dbDAO6 = new DbDAO("pdp3", persistenceUnit, properties2);
+               try{
+                       EntityManager em = emf.createEntityManager();
+                       // Start a transaction
+                       EntityTransaction et = em.getTransaction();
+
+                       et.begin();
+
+                       // if IntegrityAuditEntity entry exists for resourceName and PU, update it. If not found, create a new entry
+                       Query iaequery = em.createQuery("Select i from IntegrityAuditEntity i where i.resourceName=:rn and i.persistenceUnit=:pu");
+                       iaequery.setParameter("rn", "pdp2");
+                       iaequery.setParameter("pu", persistenceUnit);
+
+                       @SuppressWarnings("rawtypes")
+                       List iaeList = iaequery.getResultList();
+                       IntegrityAuditEntity iae = null;
+
+                       //If it already exists, we just want to update the properties and lastUpdated date
+                       if(!iaeList.isEmpty()){
+                               //ignores multiple results
+                               iae = (IntegrityAuditEntity) iaeList.get(0);
+                               // refresh the object from DB in case cached data was returned
+                               em.refresh(iae);
+                               logger.info("Resource: " + "pdp2" + " with PersistenceUnit: " + persistenceUnit 
+                                               + " exists and entry be updated");
+                       }else{
+                               // If it does not exist, we also must add teh resourceName, persistenceUnit and designated values
+                               logger.info("Adding resource " + "pdp2" + " with PersistenceUnit: " + persistenceUnit
+                                               + " to IntegrityAuditEntity table");    
+                               iae = new IntegrityAuditEntity();
+                               iae.setResourceName("pdp2");
+                               iae.setPersistenceUnit(persistenceUnit);
+                               iae.setDesignated(false);
+                       }
+                       
+                       //update/set properties in entry
+                       iae.setSite(siteName);
+                       iae.setNodeType(nodeType);
+                       iae.setLastUpdated(date);
+                       iae.setCreatedDate(date);
+                       iae.setJdbcDriver(dbDriver);
+                       iae.setJdbcPassword(dbPwd);
+                       iae.setJdbcUrl("jdbc:h2:file:./sql/iaTest2");
+                       iae.setJdbcUser(dbUser);
+
+                       em.persist(iae);
+                       // flush to the DB
+                       em.flush();
+
+                       // commit transaction
+                       et.commit();
+                       
+                       et.begin();
+
+                       // if IntegrityAuditEntity entry exists for resourceName and PU, update it. If not found, create a new entry
+                       iaequery = em.createQuery("Select i from IntegrityAuditEntity i where i.resourceName=:rn and i.persistenceUnit=:pu");
+                       iaequery.setParameter("rn", "pdp1");
+                       iaequery.setParameter("pu", persistenceUnit);
+
+                       @SuppressWarnings("rawtypes")
+                       List iaeList2 = iaequery.getResultList();
+                       iae = null;
+
+                       //If it already exists, we just want to update the properties and lastUpdated date
+                       if(!iaeList2.isEmpty()){
+                               //ignores multiple results
+                               iae = (IntegrityAuditEntity) iaeList2.get(0);
+                               // refresh the object from DB in case cached data was returned
+                               em.refresh(iae);
+                               logger.info("Resource: " + "pdp1" + " with PersistenceUnit: " + persistenceUnit 
+                                               + " exists and entry be updated");
+                       }else{
+                               // If it does not exist, we also must add teh resourceName, persistenceUnit and designated values
+                               logger.info("Adding resource " + "pdp1" + " with PersistenceUnit: " + persistenceUnit
+                                               + " to IntegrityAuditEntity table");    
+                               iae = new IntegrityAuditEntity();
+                               iae.setResourceName("pdp1");
+                               iae.setPersistenceUnit(persistenceUnit);
+                               iae.setDesignated(false);
+                       }
+                       
+                       //update/set properties in entry
+                       iae.setSite(siteName);
+                       iae.setNodeType(nodeType);
+                       iae.setLastUpdated(date);
+                       iae.setCreatedDate(date);
+                       iae.setJdbcDriver(dbDriver);
+                       iae.setJdbcPassword(dbPwd);
+                       iae.setJdbcUrl("jdbc:h2:file:./sql/iaTest2");
+                       iae.setJdbcUser(dbUser);
+                       
+                       em.persist(iae);
+                       // flush to the DB
+                       em.flush();
+
+                       // commit transaction
+                       et.commit();
+                       
+                       et.begin();
+
+                       // if IntegrityAuditEntity entry exists for resourceName and PU, update it. If not found, create a new entry
+                       iaequery = em.createQuery("Select i from IntegrityAuditEntity i where i.resourceName=:rn and i.persistenceUnit=:pu");
+                       iaequery.setParameter("rn", "pdp3");
+                       iaequery.setParameter("pu", persistenceUnit);
+
+                       @SuppressWarnings("rawtypes")
+                       List iaeList3 = iaequery.getResultList();
+                       iae = null;
+
+                       //If it already exists, we just want to update the properties and lastUpdated date
+                       if(!iaeList3.isEmpty()){
+                               //ignores multiple results
+                               iae = (IntegrityAuditEntity) iaeList3.get(0);
+                               // refresh the object from DB in case cached data was returned
+                               em.refresh(iae);
+                               logger.info("Resource: " + "pdp3" + " with PersistenceUnit: " + persistenceUnit 
+                                               + " exists and entry be updated");
+                       }else{
+                               // If it does not exist, we also must add teh resourceName, persistenceUnit and designated values
+                               logger.info("Adding resource " + "pdp3" + " with PersistenceUnit: " + persistenceUnit
+                                               + " to IntegrityAuditEntity table");    
+                               iae = new IntegrityAuditEntity();
+                               iae.setResourceName("pdp3");
+                               iae.setPersistenceUnit(persistenceUnit);
+                               iae.setDesignated(false);
+                       }
+                       
+                       //update/set properties in entry
+                       iae.setSite(siteName);
+                       iae.setNodeType(nodeType);
+                       iae.setLastUpdated(date);
+                       iae.setCreatedDate(date);
+                       iae.setJdbcDriver(dbDriver);
+                       iae.setJdbcPassword(dbPwd);
+                       iae.setJdbcUrl("jdbc:h2:file:./sql/iaTest2");
+                       iae.setJdbcUser(dbUser);
+                       
+                       em.persist(iae);
+                       // flush to the DB
+                       em.flush();
+
+                       // commit transaction
+                       et.commit();
+                       
+                       em.close();
+               }catch (Exception e){
+                       String msg = "DbDAO: " + "register() " + "ecountered a problem in execution: ";
+                       logger.error(msg + e);
+                       throw new DbDaoTransactionException(e);
+
+               }
+               
+               /*
+                * Run the DB Audit, once it finds a mismatch and sleeps, update DB1
+                * to have the same entry as DB2 it can be confirmed that the mismatch
+                * is resolved
+                */
+               DbAudit dbAudit = new DbAudit(dbDAO);
+               dbAudit.dbAudit(resourceName, persistenceUnit, nodeType);
+               emf = Persistence.createEntityManagerFactory(persistenceUnit, properties);
+               try{
+                       EntityManager em = emf.createEntityManager();
+                       // Start a transaction
+                       EntityTransaction et = em.getTransaction();
+
+                       et.begin();
+
+                       // if IntegrityAuditEntity entry exists for resourceName and PU, update it. If not found, create a new entry
+                       Query iaequery = em.createQuery("Select i from IntegrityAuditEntity i where i.resourceName=:rn and i.persistenceUnit=:pu");
+                       iaequery.setParameter("rn", "pdp3");
+                       iaequery.setParameter("pu", persistenceUnit);
+
+                       @SuppressWarnings("rawtypes")
+                       List iaeList = iaequery.getResultList();
+                       IntegrityAuditEntity iae = null;
+
+                       //If it already exists, we just want to update the properties and lastUpdated date
+                       if(!iaeList.isEmpty()){
+                               //ignores multiple results
+                               iae = (IntegrityAuditEntity) iaeList.get(0);
+                               // refresh the object from DB in case cached data was returned
+                               em.refresh(iae);
+                               logger.info("Resource: " + "pdp3" + " with PersistenceUnit: " + persistenceUnit 
+                                               + " exists and entry be updated");
+                       }else{
+                               // If it does not exist, we also must add the resourceName, persistenceUnit and designated values
+                               logger.info("Adding resource " + "pdp3" + " with PersistenceUnit: " + persistenceUnit
+                                               + " to IntegrityAuditEntity table");    
+                               iae = new IntegrityAuditEntity();
+                               iae.setResourceName("pdp3");
+                               iae.setPersistenceUnit(persistenceUnit);
+                               iae.setDesignated(false);
+                       }
+                       
+                       //update/set properties in entry
+                       iae.setSite(siteName);
+                       iae.setNodeType(nodeType);
+                       iae.setLastUpdated(date);
+                       iae.setCreatedDate(date);
+                       iae.setJdbcDriver(dbDriver);
+                       iae.setJdbcPassword(dbPwd);
+                       iae.setJdbcUrl("jdbc:h2:file:./sql/iaTest2");
+                       iae.setJdbcUser(dbUser);
+
+                       em.persist(iae);
+                       // flush to the DB
+                       em.flush();
+
+                       // commit transaction
+                       et.commit();
+                       em.close();
+               }catch (Exception e){
+                       String msg = "DbDAO: " + "register() " + "ecountered a problem in execution: ";
+                       logger.error(msg + e);
+                       throw new DbDaoTransactionException(e);
+               }
+               
+               /*
+                * Run the audit again and correct the mismatch, the result should be one
+                * entry in the mismatchKeySet because of the misentry from the beginning
+                * of the test
+                */
+               dbAudit.dbAudit(resourceName, persistenceUnit, nodeType);
+               
+               //Cleanup DB2
+               cleanDb(persistenceUnit, properties2);
+               
+               FileInputStream fstream = new FileInputStream(TEST_LOG);
+               BufferedReader br = new BufferedReader(new InputStreamReader(fstream));
+               String strLine;
+               int startIndex;
+               String mismatchIndex = "";
+               while ((strLine = br.readLine()) != null)   {
+                        //parse strLine to obtain what you want...retrieve the last entry
+
+                       if (strLine.contains("Mismatched entries (keys):")) {
+                               startIndex = strLine.indexOf("(keys):") + 8;
+                               mismatchIndex = strLine.substring(startIndex);
+                       }
+               }
+               int mismatchEntries = mismatchIndex.trim().split(",").length;
+               logger.info("mismatchTest: mismatchIndex found: '" + mismatchIndex + "'" 
+                               + " mismatachEntries = " + mismatchEntries);
+               
+               // Assert there is only one entry index
+               assertEquals(1, mismatchEntries);
+               
+               br.close();
+               
+               //Now check the entry in the error.log
+               fstream = new FileInputStream(ERROR_LOG);
+               br = new BufferedReader(new InputStreamReader(fstream));
+               String mismatchNum = "";
+               while ((strLine = br.readLine()) != null)   {
+                        //parse strLine to obtain what you want...retrieve the last entry
+
+                       if (strLine.contains("DB Audit:")) {
+                               startIndex = strLine.indexOf("DB Audit:") + 10;
+                               mismatchNum = strLine.substring(startIndex, startIndex+1);
+                       }
+               }
+               logger.info("mismatchTest: mismatchNum found: '" + mismatchNum + "'");
+               
+               // Assert that there are a total of 3 mismatches - 1 between each comparison node.
+               assertEquals("3", mismatchNum);
+               
+               br.close();
+               
+               logger.info("mismatchTest: Exit");
+       }
+       
+}
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
new file mode 100644 (file)
index 0000000..1c59b01
--- /dev/null
@@ -0,0 +1,713 @@
+/*-
+ * ============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=========================================================
+ */
+
+package org.openecomp.policy.common.ia.test;
+
+import static org.junit.Assert.*;
+
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Properties;
+
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.EntityTransaction;
+import javax.persistence.Persistence;
+import javax.persistence.PersistenceUnitUtil;
+import javax.persistence.Query;
+import javax.persistence.TypedQuery;
+import javax.persistence.criteria.CriteriaBuilder;
+import javax.persistence.criteria.CriteriaQuery;
+import javax.persistence.criteria.Root;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+
+import org.openecomp.policy.common.ia.DbDAO;
+import org.openecomp.policy.common.ia.DbDaoTransactionException;
+import org.openecomp.policy.common.ia.IntegrityAuditProperties;
+import org.openecomp.policy.common.ia.jpa.IntegrityAuditEntity;
+
+public class DbDAOTest {
+       private static String persistenceUnit;
+       private static Properties properties;
+       private static String resourceName;
+       
+       DbDAO d;
+       
+       @Before
+       public void setUp() throws Exception {
+               properties = new Properties();
+               properties.put(IntegrityAuditProperties.DB_DRIVER, IntegrityAuditProperties.DEFAULT_DB_DRIVER);
+               properties.put(IntegrityAuditProperties.DB_URL, IntegrityAuditProperties.DEFAULT_DB_URL);
+               properties.put(IntegrityAuditProperties.DB_USER, IntegrityAuditProperties.DEFAULT_DB_USER);
+               properties.put(IntegrityAuditProperties.DB_PWD, IntegrityAuditProperties.DEFAULT_DB_PWD);
+               properties.put(IntegrityAuditProperties.SITE_NAME, "SiteA");
+               properties.put(IntegrityAuditProperties.NODE_TYPE, "pdp_xacml");
+                               
+               persistenceUnit = "integrityAuditPU";
+               resourceName = "pdp0";          
+       }
+
+       @After
+       public void tearDown() throws Exception {
+       }
+       
+       /* Tests registering a new IntegrityAuditEntity object in the DB */
+       @Test
+       public void testNewRegistration() {
+               try {
+                       EntityManagerFactory emf = Persistence.createEntityManagerFactory(persistenceUnit, properties);
+                       EntityManager em = emf.createEntityManager();
+                       
+                       // Start a transaction
+                       EntityTransaction et = em.getTransaction();
+                       
+                       // Begin Transaction
+                       et.begin();
+                       
+                       // Clean the DB
+                       em.createQuery("DELETE FROM IntegrityAuditEntity").executeUpdate();
+                       
+                       // flush to the DB
+                       em.flush();
+                       et.commit();
+               
+                       et.begin();
+                       d = new DbDAO(resourceName, persistenceUnit, properties);
+                       
+               // Find the proper entry in the database
+               Query iaequery = em.createQuery("Select i from IntegrityAuditEntity i where i.resourceName=:rn and i.persistenceUnit=:pu");
+               iaequery.setParameter("rn", DbDAOTest.resourceName);
+               iaequery.setParameter("pu", DbDAOTest.persistenceUnit);
+               
+               @SuppressWarnings("rawtypes")
+               List iaeList = iaequery.getResultList();
+               
+               // Assert that the IntegrityAuditEntity object was found
+               assertNotNull(iaeList);
+               
+                       // flush to the DB
+                       em.flush();
+                       et.commit();
+                       em.close();
+                       
+               } catch (Exception e) {
+                       // TODO Auto-generated catch block
+                       e.printStackTrace();
+               }
+       }
+       
+       /* Tests updating an IntegrityAuditEntity if it has already been registered */
+       @Test
+       public void testUpdateRegistration() {
+               EntityManagerFactory emf = Persistence.createEntityManagerFactory(persistenceUnit, properties);
+               EntityManager em = emf.createEntityManager();
+
+               // Start a transaction
+               EntityTransaction et = em.getTransaction();
+
+               // Begin transaction
+               et.begin();
+               
+               // Clean the DB
+               em.createQuery("DELETE FROM IntegrityAuditEntity").executeUpdate();
+               
+               // flush to the DB
+               em.flush();
+               et.commit();
+                                       
+               // close the EntityManager
+               em.close();
+               
+               try {
+                       d = new DbDAO(resourceName, persistenceUnit, properties);
+                       
+                       // Change site_name in properties to test that an update was made to an existing entry in the table
+                       properties.put(IntegrityAuditProperties.SITE_NAME, "SiteB");
+                       d = new DbDAO(resourceName, persistenceUnit, properties);
+                       
+                       em = emf.createEntityManager();
+                       
+                       // Start a transaction
+                       et = em.getTransaction();
+                       
+                       // Begin Transaction
+                       et.begin();
+               
+               // Find the proper entry in the database
+               Query iaequery = em.createQuery("Select i from IntegrityAuditEntity i where i.resourceName=:rn and i.persistenceUnit=:pu");
+               iaequery.setParameter("rn", DbDAOTest.resourceName);
+               iaequery.setParameter("pu", DbDAOTest.persistenceUnit);
+               
+               @SuppressWarnings("rawtypes")
+               List iaeList = iaequery.getResultList();
+               IntegrityAuditEntity iae = null;
+               if(!iaeList.isEmpty()) {
+                       //ignores multiple results
+                       iae = (IntegrityAuditEntity) iaeList.get(0);
+                       
+                       em.refresh(iae);
+                       em.persist(iae);
+                       
+                       // flush to the DB
+                       em.flush();
+                       
+                       // commit transaction
+                       et.commit();
+                       
+                       // close the EntityManager
+                       em.close();
+                       
+                       // Assert that the site_name for the existing entry was updated
+                       assertEquals("SiteB", iae.getSite());
+               }
+               } catch (Exception e) {
+                       // TODO Auto-generated catch block
+                       e.printStackTrace();
+               }
+       }
+       
+       /* Tests obtaining all Integrity Audit Entities from a table */
+       @Test
+       public void testGetIntegrityAuditEntities() {
+               EntityManagerFactory emf = Persistence.createEntityManagerFactory(persistenceUnit, properties);
+               EntityManager em = emf.createEntityManager();
+               
+               // Start a transaction
+               EntityTransaction et = em.getTransaction();
+               
+               et.begin();
+               
+               // Clean the DB
+               em.createQuery("DELETE FROM IntegrityAuditEntity").executeUpdate();
+               
+               // flush to the DB
+               em.flush();
+               
+               // close the transaction
+               et.commit();
+               
+               // close the EntityManager
+               em.close();
+               
+               try {
+                       // Add some entries to the DB
+                       d = new DbDAO(resourceName, persistenceUnit, properties);
+                       DbDAO d2 = new DbDAO("pdp1", persistenceUnit, properties);
+                       properties.put(IntegrityAuditProperties.NODE_TYPE, "pdp_drools");
+                       DbDAO d3 = new DbDAO("pdp2", persistenceUnit, properties);
+               } catch (Exception e) {
+                       // TODO Auto-generated catch block
+                       e.printStackTrace();
+               }
+               List<IntegrityAuditEntity> entities;
+               try {
+                       // Obtain entries based on persistenceUnit and nodeType
+                       entities = d.getIntegrityAuditEntities(persistenceUnit, "pdp_xacml");
+                       assertEquals(2, entities.size());
+               } catch (DbDaoTransactionException e) {
+                       // TODO Auto-generated catch block
+                       e.printStackTrace();
+               }               
+       }
+
+       /* Tests retrieving a DbDAO instance's IntegrityAuditEntity */
+       @Test
+       public void testGetMyIntegrityAuditEntity() {
+               try {
+                       d = new DbDAO(resourceName, persistenceUnit, properties);
+                       IntegrityAuditEntity iae = d.getMyIntegrityAuditEntity();
+                       assertEquals("integrityAuditPU", iae.getPersistenceUnit());
+               } catch (Exception e) {
+                       // TODO Auto-generated catch block
+                       e.printStackTrace();
+               }
+       }
+       
+       /* Tests obtaining an IntegrityAuditEntity by ID */
+       @Test
+       public void testGetIntegrityAuditEntity() {
+               EntityManagerFactory emf = Persistence.createEntityManagerFactory(persistenceUnit, properties);
+               EntityManager em = emf.createEntityManager();
+               
+               // Start a transaction
+               EntityTransaction et = em.getTransaction();
+               
+               // Begin transaction
+               et.begin();
+               
+               // Clean the DB
+               em.createQuery("DELETE FROM IntegrityAuditEntity").executeUpdate();
+               
+               // flush to the DB
+               em.flush();
+               
+               // close the transaction
+               et.commit();
+               
+               try {
+                       // Obtain an entry from the database based on ID
+                       d = new DbDAO(resourceName, persistenceUnit, properties);
+                       
+                       et.begin();
+
+                       // Find the proper database entry
+                       Query iaequery = em.createQuery("Select i from IntegrityAuditEntity i where i.resourceName=:rn and i.persistenceUnit=:pu");
+                       iaequery.setParameter("rn", DbDAOTest.resourceName);
+                       iaequery.setParameter("pu", DbDAOTest.persistenceUnit);
+
+                       @SuppressWarnings("rawtypes")
+                       List iaeList = iaequery.getResultList();
+                       IntegrityAuditEntity iae = null;
+                       if(!iaeList.isEmpty()){
+                               //ignores multiple results
+                               iae = (IntegrityAuditEntity) iaeList.get(0);
+                               
+                               // refresh the object from DB in case cached data was returned
+                               em.refresh(iae);
+                       
+                               // Obtain ID for an IntegrityAuditEntity
+                               PersistenceUnitUtil util = emf.getPersistenceUnitUtil(); 
+                               Object iaeId = util.getIdentifier(iae);
+
+                               // Obtain the same IntegrityAuditEntity based on ID
+                               IntegrityAuditEntity iaeDuplicate = d.getIntegrityAuditEntity((long) iaeId);
+                               Object duplicateId = util.getIdentifier(iaeDuplicate);
+                               
+                               // Assert that the proper entry was retrieved based on ID
+                               assertEquals((long) iaeId, (long) duplicateId);
+                       }
+               } catch (Exception e) {
+                       // TODO Auto-generated catch block
+                       e.printStackTrace();
+               }
+               // close the EntityManager
+               em.close();
+       }
+
+       /* Tests setting an IntegrityAuditEntity as the designated node */
+       @Test
+       public void testSetDesignated() {
+               try {
+                       EntityManagerFactory emf = Persistence.createEntityManagerFactory(persistenceUnit, properties);
+                       EntityManager em = emf.createEntityManager();
+
+                       // Start a transaction
+                       EntityTransaction et = em.getTransaction();
+
+                       // Begin transaction
+                       et.begin();
+
+                       // Clean the DB
+                       em.createQuery("DELETE FROM IntegrityAuditEntity").executeUpdate();
+                       
+                       // flush to the DB
+                       em.flush();
+                       et.commit();
+                       
+                       et.begin();
+                       
+                       // Create an entry and set it's designated field to true
+                       d = new DbDAO(resourceName, persistenceUnit, properties);
+                       d.setDesignated(resourceName, persistenceUnit, true);
+                       
+                       // Find the proper entry in the database
+                       Query iaequery = em.createQuery("Select i from IntegrityAuditEntity i where i.resourceName=:rn and i.persistenceUnit=:pu");
+                       iaequery.setParameter("rn", resourceName);
+                       iaequery.setParameter("pu", persistenceUnit);
+
+                       @SuppressWarnings("rawtypes")
+                       List iaeList = iaequery.getResultList();
+                       IntegrityAuditEntity iae = null;
+
+                       if(!iaeList.isEmpty()){
+                               //ignores multiple results
+                               iae = (IntegrityAuditEntity) iaeList.get(0);
+                               em.refresh(iae);
+                               
+                               // Check if the node is designated
+                               boolean result = iae.isDesignated();
+
+                               // Assert that it is designated
+                               assertTrue(result);
+                       }
+                       
+                       // flush to the DB
+                       em.flush();
+                       
+                       // close the transaction
+                       et.commit();
+                       
+                       // close the EntityManager
+                       em.close();
+               } catch (Exception e) {
+                       // TODO Auto-generated catch block
+                       e.printStackTrace();
+               }
+       }
+
+       /* Tests that the lastUpdated column in the database is updated properly */
+       @Test
+       public void testSetLastUpdated() {
+               try {
+                       EntityManagerFactory emf = Persistence.createEntityManagerFactory(persistenceUnit, properties);
+                       EntityManager em = emf.createEntityManager();
+
+                       // Start a transaction
+                       EntityTransaction et = em.getTransaction();
+
+                       // Begin transaction
+                       et.begin();
+                       
+                       // Clean the DB
+                       em.createQuery("DELETE FROM IntegrityAuditEntity").executeUpdate();
+                       
+                       // flush to the DB
+                       em.flush();
+                       et.commit();
+                       
+                       et.begin();
+
+                       // Create an entry
+                       d = new DbDAO(resourceName, persistenceUnit, properties);
+                       
+                       // Find the proper entry in the database
+                       Query iaequery = em.createQuery("Select i from IntegrityAuditEntity i where i.resourceName=:rn and i.persistenceUnit=:pu");
+                       iaequery.setParameter("rn", resourceName);
+                       iaequery.setParameter("pu", persistenceUnit);
+
+                       @SuppressWarnings("rawtypes")
+                       List iaeList = iaequery.getResultList();
+                       IntegrityAuditEntity iae = null;
+
+                       if(!iaeList.isEmpty()){
+                               // ignores multiple results
+                               iae = (IntegrityAuditEntity) iaeList.get(0);
+                               // refresh the object from DB in case cached data was returned
+                               em.refresh(iae);
+                               
+                               // Obtain old update value and set new update value
+                               Date oldDate = iae.getLastUpdated();
+                               iae.setSite("SiteB");
+                               iae.setLastUpdated(new Date());
+                               Date newDate = iae.getLastUpdated();
+                               
+                               em.persist(iae);
+                               // flush to the DB
+                               em.flush();
+                               // close the transaction
+                               et.commit();
+                               // close the EntityManager
+                               em.close();
+                               
+                               // Assert that the old and new update times are different
+                               assertNotEquals(oldDate, newDate);
+                       }
+               } catch (Exception e) {
+                       // TODO Auto-generated catch block
+                       e.printStackTrace();
+               }
+       }
+       
+       /* Tests that all the entries from a class can be retrieved */
+       @Test
+       public void testGetAllMyEntriesString() {
+               EntityManagerFactory emf = Persistence.createEntityManagerFactory(persistenceUnit, properties);
+               EntityManager em = emf.createEntityManager();
+
+               // Start a transaction
+               EntityTransaction et = em.getTransaction();
+
+               // Begin transaction
+               et.begin();
+               
+               // Clean the DB
+               em.createQuery("DELETE FROM IntegrityAuditEntity").executeUpdate();
+               
+               // flush to the DB
+               em.flush();
+               et.commit();
+                                       
+               // close the EntityManager
+               em.close();
+               
+               try {
+                       // create entries for the IntegrityAuditEntity table
+                       d = new DbDAO(resourceName, persistenceUnit, properties);
+                       DbDAO d2 = new DbDAO("pdp1", persistenceUnit, properties);
+                       DbDAO d3 = new DbDAO("pdp2", persistenceUnit, properties);
+               } catch (Exception e) {
+                       // TODO Auto-generated catch block
+                       e.printStackTrace();
+               }
+               
+               try {
+                       // Obtain a hash with the persisted objects
+                       HashMap<Object, Object> entries = d.getAllMyEntries("org.openecomp.policy.common.ia.jpa.IntegrityAuditEntity");
+                       
+                       // Assert there were 3 entries for that class
+                       assertEquals(3, entries.size());
+               } catch (Exception e) {
+                       // TODO Auto-generated catch block
+                       e.printStackTrace();
+               }
+       }
+       
+       /* Tests retrieving all entities in a Persistence Unit using the class name and a hashset of IDs */
+       @Test
+       public void testGetAllMyEntriesStringHashSet() {
+               EntityManagerFactory emf = Persistence.createEntityManagerFactory(persistenceUnit, properties);
+               EntityManager em = emf.createEntityManager();
+
+               // Start a transaction
+               EntityTransaction et = em.getTransaction();
+
+               // Begin transaction
+               et.begin();
+               
+               // Clean the DB
+               em.createQuery("DELETE FROM IntegrityAuditEntity").executeUpdate();
+               
+               // flush to the DB
+               em.flush();
+               et.commit();
+               
+               try {
+                       // create entries for the IntegrityAuditEntity table
+                       d = new DbDAO(resourceName, persistenceUnit, properties);
+                       DbDAO d2 = new DbDAO("pdp1", persistenceUnit, properties);
+                       DbDAO d3 = new DbDAO("pdp2", persistenceUnit, properties);
+               } catch (Exception e) {
+                       // TODO Auto-generated catch block
+                       e.printStackTrace();
+               }
+               
+               try {
+                       // Obtain all entity keys
+                       CriteriaBuilder cb = em.getCriteriaBuilder();
+                       CriteriaQuery<Object> cq = cb.createQuery();
+                       Root<?> rootEntry = cq.from(Class.forName("org.openecomp.policy.common.ia.jpa.IntegrityAuditEntity"));
+                       CriteriaQuery<Object> all = cq.select(rootEntry);
+                       TypedQuery<Object> allQuery = em.createQuery(all);
+                       List<Object> objectList = allQuery.getResultList();
+                       HashSet<Object> resultSet = new HashSet<Object>();
+                       PersistenceUnitUtil util = emf.getPersistenceUnitUtil();
+                       for (Object o: objectList){
+                               Object key = util.getIdentifier(o);
+                               resultSet.add(key);
+                       }
+                       
+                       // Obtain a hash with the persisted objects
+                       HashMap<Object, Object> entries = d.getAllMyEntries("org.openecomp.policy.common.ia.jpa.IntegrityAuditEntity", resultSet);
+                       
+                       // Assert there were 3 entries for that class
+                       assertEquals(3, entries.size());
+               } catch (Exception e) {
+                       // TODO Auto-generated catch block
+                       e.printStackTrace();
+               }
+               
+               // close the EntityManager
+               em.close();
+       }
+       
+       /* Tests retrieving all entities in a Persistence Unit using the persistence unit, properties, and class name */
+       @Test
+       public void testGetAllEntriesStringPropertiesString() {
+               EntityManagerFactory emf = Persistence.createEntityManagerFactory(persistenceUnit, properties);
+               EntityManager em = emf.createEntityManager();
+
+               // Start a transaction
+               EntityTransaction et = em.getTransaction();
+
+               // Begin transaction
+               et.begin();
+               
+               // Clean the DB
+               em.createQuery("DELETE FROM IntegrityAuditEntity").executeUpdate();
+               
+               // flush to the DB
+               em.flush();
+               et.commit();
+                                       
+               // close the EntityManager
+               em.close();
+               
+               try {
+                       // create entries for the IntegrityAuditEntity table
+                       d = new DbDAO(resourceName, persistenceUnit, properties);
+                       DbDAO d2 = new DbDAO("pdp1", persistenceUnit, properties);
+                       DbDAO d3 = new DbDAO("pdp2", persistenceUnit, properties);
+               } catch (Exception e) {
+                       // TODO Auto-generated catch block
+                       e.printStackTrace();
+               }
+               
+               try {
+                       // Obtain a hash with the persisted objects
+                       HashMap<Object, Object> entries = d.getAllEntries("integrityAuditPU", properties, "org.openecomp.policy.common.ia.jpa.IntegrityAuditEntity");
+                       
+                       // Assert there were 3 entries for that class
+                       assertEquals(3, entries.size());
+               } catch (Exception e) {
+                       // TODO Auto-generated catch block
+                       e.printStackTrace();
+               }
+       }
+       
+       /* Tests retrieving all entities in a Persistence Unit using the persistence unit, properties, class name, and a hashset of IDs */
+       @Test
+       public void testGetAllEntriesStringPropertiesStringHashSet() {
+               EntityManagerFactory emf = Persistence.createEntityManagerFactory(persistenceUnit, properties);
+               EntityManager em = emf.createEntityManager();
+
+               // Start a transaction
+               EntityTransaction et = em.getTransaction();
+
+               // Begin transaction
+               et.begin();
+               
+               // Clean the DB
+               em.createQuery("DELETE FROM IntegrityAuditEntity").executeUpdate();
+               
+               // flush to the DB
+               em.flush();
+               et.commit();
+               
+               try {
+                       // create entries for the IntegrityAuditEntity table
+                       d = new DbDAO(resourceName, persistenceUnit, properties);
+                       DbDAO d2 = new DbDAO("pdp1", persistenceUnit, properties);
+                       DbDAO d3 = new DbDAO("pdp2", persistenceUnit, properties);
+               } catch (Exception e) {
+                       // TODO Auto-generated catch block
+                       e.printStackTrace();
+               }
+               
+               try {
+                       // Obtain all entity keys
+                       CriteriaBuilder cb = em.getCriteriaBuilder();
+                       CriteriaQuery<Object> cq = cb.createQuery();
+                       Root<?> rootEntry = cq.from(Class.forName("org.openecomp.policy.common.ia.jpa.IntegrityAuditEntity"));
+                       CriteriaQuery<Object> all = cq.select(rootEntry);
+                       TypedQuery<Object> allQuery = em.createQuery(all);
+                       List<Object> objectList = allQuery.getResultList();
+                       HashSet<Object> resultSet = new HashSet<Object>();
+                       PersistenceUnitUtil util = emf.getPersistenceUnitUtil();
+                       for (Object o: objectList){
+                               Object key = util.getIdentifier(o);
+                               resultSet.add(key);
+                       }
+                       
+                       // Obtain a hash with the persisted objects
+                       HashMap<Object, Object> entries = d.getAllEntries("integrityAuditPU", properties, "org.openecomp.policy.common.ia.jpa.IntegrityAuditEntity", resultSet);
+                       
+                       // Assert there were 3 entries for that class
+                       assertEquals(3, entries.size());
+               } catch (Exception e) {
+                       // TODO Auto-generated catch block
+                       e.printStackTrace();
+               }
+               
+               // close the EntityManager
+               em.close();
+       }
+       
+       /* Tests getting all the entries from a class based on persistenceUnit, properties, and className */
+       @Test
+       public void testGetAllEntries() {
+               EntityManagerFactory emf = Persistence.createEntityManagerFactory(persistenceUnit, properties);
+               EntityManager em = emf.createEntityManager();
+
+               // Start a transaction
+               EntityTransaction et = em.getTransaction();
+
+               // Begin transaction
+               et.begin();
+               
+               // Clean the DB
+               em.createQuery("DELETE FROM IntegrityAuditEntity").executeUpdate();
+               
+               // flush to the DB
+               em.flush();
+               et.commit();
+                                       
+               // close the EntityManager
+               em.close();
+               
+               try {
+                       // create entries for the IntegrityAuditEntity table
+                       d = new DbDAO(resourceName, persistenceUnit, properties);
+                       DbDAO d2 = new DbDAO("pdp1", persistenceUnit, properties);
+                       DbDAO d3 = new DbDAO("pdp2", persistenceUnit, properties);
+               } catch (Exception e) {
+                       // TODO Auto-generated catch block
+                       e.printStackTrace();
+               }
+               
+               try {
+                       // Obtain a hash with the persisted objects
+                       HashMap<Object, Object> entries = d.getAllEntries(persistenceUnit, properties, "org.openecomp.policy.common.ia.jpa.IntegrityAuditEntity");
+                       
+                       // Assert there were 3 entries for that class
+                       assertEquals(3, entries.size());
+               } catch (Exception e) {
+                       // TODO Auto-generated catch block
+                       e.printStackTrace();
+               }
+       }
+       
+       /* Tests obtaining all class names of persisted classes */
+       public void testGetPersistenceClassNames() {
+               EntityManagerFactory emf = Persistence.createEntityManagerFactory(persistenceUnit, properties);
+               EntityManager em = emf.createEntityManager();
+
+               // Start a transaction
+               EntityTransaction et = em.getTransaction();
+
+               // Begin transaction
+               et.begin();
+               
+               // Clean the DB
+               em.createQuery("DELETE FROM IntegrityAuditEntity").executeUpdate();
+               
+               // flush to the DB
+               em.flush();
+               et.commit();
+                                       
+               // close the EntityManager
+               em.close();
+               
+               try {
+                       d = new DbDAO(resourceName, persistenceUnit, properties);
+               } catch (Exception e) {
+                       // TODO Auto-generated catch block
+                       e.printStackTrace();
+               }
+               // Retrieve persistence class names
+               HashSet<String> result = d.getPersistenceClassNames();
+               assertEquals(1, result.size());
+       }
+}
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
new file mode 100644 (file)
index 0000000..6eb5fa4
--- /dev/null
@@ -0,0 +1,1101 @@
+/*-
+ * ============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=========================================================
+ */
+
+package org.openecomp.policy.common.ia.test;
+
+import static org.junit.Assert.*;
+
+import java.io.BufferedReader;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Properties;
+
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.EntityTransaction;
+import javax.persistence.Persistence;
+
+
+
+//import org.apache.commons.logging.Log;
+//import org.apache.commons.logging.LogFactory;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+
+import org.openecomp.policy.common.ia.AuditThread;
+import org.openecomp.policy.common.ia.DbDAO;
+import org.openecomp.policy.common.ia.IntegrityAudit;
+import org.openecomp.policy.common.ia.IntegrityAuditProperties;
+import org.openecomp.policy.common.logging.flexlogger.FlexLogger; 
+import org.openecomp.policy.common.logging.flexlogger.Logger;
+
+public class IntegrityAuditDesignationTest {
+       
+       private static Logger logger = FlexLogger.getLogger(IntegrityAuditDesignationTest.class);
+       
+       /*
+        * Provides a little cushion for timing events.
+        */
+       private static int FUDGE_FACTOR = 5000;
+       
+       private static String persistenceUnit;
+       private static Properties properties;
+       private static String resourceName;
+       private static final String TEST_LOG = "./testingLogs/common-modules/integrity-audit/debug.log";
+       @Before
+       public void setUp() throws Exception {
+
+               
+               System.out.println("setUp: Clearing debug.log");
+               FileOutputStream fstream = new FileOutputStream(TEST_LOG);
+               fstream.close();
+
+               logger.info("setUp: Entering");
+
+               IntegrityAudit.isUnitTesting = true;
+               
+               properties = new Properties();
+               properties.put(IntegrityAuditProperties.DB_DRIVER, IntegrityAuditProperties.DEFAULT_DB_DRIVER);
+               properties.put(IntegrityAuditProperties.DB_URL, IntegrityAuditProperties.DEFAULT_DB_URL);
+               properties.put(IntegrityAuditProperties.DB_USER, IntegrityAuditProperties.DEFAULT_DB_USER);
+               properties.put(IntegrityAuditProperties.DB_PWD, IntegrityAuditProperties.DEFAULT_DB_PWD);
+               properties.put(IntegrityAuditProperties.SITE_NAME, "SiteA");
+               properties.put(IntegrityAuditProperties.NODE_TYPE, "pdp_xacml");
+               
+               /*
+                * AuditThread.AUDIT_THREAD_SLEEP_INTERVAL is also five seconds, so
+                * setting AUDIT_PERIOD_SECONDS to 5 ensures that whether or not audit
+                * has already been run on a node, it will sleep the same amount of
+                * time.
+                */
+               properties.put(IntegrityAuditProperties.AUDIT_PERIOD_SECONDS, "5");
+                               
+               persistenceUnit = "testPU";
+               resourceName = "pdp1";
+               
+               
+               //Clean up the DB               
+               EntityManagerFactory emf = Persistence.createEntityManagerFactory(persistenceUnit, properties);
+               
+               EntityManager em = emf.createEntityManager();
+               // Start a transaction
+               EntityTransaction et = em.getTransaction();
+
+               et.begin();
+
+               // if IntegrityAuditEntity entry exists for resourceName and PU, update it. If not found, create a new entry
+               em.createQuery("Delete from IntegrityAuditEntity").executeUpdate();
+
+               // commit transaction
+               et.commit();
+               em.close();
+               logger.info("setUp: Exiting");
+               
+       }
+       
+
+       @After
+       public void tearDown() throws Exception {
+               
+               logger.info("tearDown: Entering");
+                               
+               logger.info("tearDown: Exiting");
+
+       }
+
+       /*
+        * Tests designation logic when only one functioning resource is in play.  Designation
+        * should stay with single resource.
+        * 
+        * Note: console.log must be examined to ascertain whether or not this test was successful.
+        */
+       @Ignore
+       @Test
+       public void testOneResource() throws Exception {
+               
+               logger.info("testOneResource: Entering");
+               
+               IntegrityAudit integrityAudit = new IntegrityAudit(resourceName, persistenceUnit, properties);
+               integrityAudit.startAuditThread();
+               
+               /*
+                * Sleep long enough to allow
+                * 
+                * 1) pdp1 to run audit (15 seconds)
+                * 
+                * 2) Logic to detect that no other node is available for designation (60 seconds)
+                * 
+                * 3) pdp1 to run audit again (15 seconds)
+                */
+               logger.info("testOneResource: Sleeping 100 seconds");
+               Thread.sleep(100000);
+               
+               logger.info("testOneResource: Stopping audit thread");
+               integrityAudit.stopAuditThread();
+               
+               FileInputStream fstream = new FileInputStream(TEST_LOG);
+               BufferedReader br = new BufferedReader(new InputStreamReader(fstream));
+               String strLine;
+               int startIndex;
+               int endIndex;
+               
+               String rName = "";
+               while ((strLine = br.readLine()) != null)   {
+                       // parse strLine to obtain what you want 
+                       if (strLine.contains("Starting audit simulation for resourceName=")) {
+                               startIndex = strLine.indexOf("resourceName=") + 13;
+                               endIndex = strLine.indexOf(",");
+                               rName = strLine.substring(startIndex, endIndex);
+                               logger.info("testOneResource: rName: " + rName);
+                               assertEquals("pdp1", rName);
+                       }
+               }       
+               fstream.close();
+               
+               /*
+                * Test fix for ECOMPD2TD-783: Audit fails to run when application is restarted.
+                */
+               integrityAudit.startAuditThread();
+               
+               /*
+                * Sleep long enough to allow
+                * 
+                * 1) pdp1 to run audit (15 seconds)
+                * 
+                * 2) Logic to detect that no other node is available for designation (60 seconds)
+                * 
+                * 3) pdp1 to run audit again (15 seconds)
+                */
+               logger.info("testOneResource: Sleeping 100 seconds for second time");
+               Thread.sleep(100000);
+               
+               logger.info("testOneResource: Stopping audit thread for second time");
+               integrityAudit.stopAuditThread();
+               
+               fstream = new FileInputStream(TEST_LOG);
+               br = new BufferedReader(new InputStreamReader(fstream));
+               
+               rName = "";
+               while ((strLine = br.readLine()) != null)   {
+                       // parse strLine to obtain what you want 
+                       if (strLine.contains("Starting audit simulation for resourceName=")) {
+                               startIndex = strLine.indexOf("resourceName=") + 13;
+                               endIndex = strLine.indexOf(",");
+                               rName = strLine.substring(startIndex, endIndex);
+                               logger.info("testOneResource: rName: " + rName);
+                               assertEquals("pdp1", rName);
+                       }
+               }       
+               fstream.close();
+               
+               logger.info("testOneResource: Exiting");
+
+       }
+       
+       /*
+        * Tests designation logic when two functioning resources are in play.
+        * Designation should alternate between resources.
+        * 
+        * Note: console.log must be examined to ascertain whether or not this test
+        * was successful. A quick way of examining the log is to search for the
+        * string "audit simulation":
+        * 
+        * As you can see from the "dbAuditSimulate" method, when it executes, it
+        * logs the "Starting audit simulation..." message and when it finishes, it
+        * logs the "Finished audit simulation..." message. By looking for these
+        * messages, you can verify that the audits are run by the proper resource.
+        * For example, when testFourResourcesOneDead is run, you should see a
+        * Starting.../Finished... sequence for pdp1, followed by a
+        * Starting.../Finished... sequence for pdp2, followed by a
+        * Starting.../Finished... sequence for pdp4 (pdp3 is skipped as it's
+        * dead/hung), followed by a Starting.../Finished... sequence for pdp1, etc.
+        */
+       @Ignore
+       @Test
+       public void testTwoResources() throws Exception {
+               
+               logger.info("testTwoResources: Entering");
+               
+               /*
+                * Start audit for pdp1.
+                */
+               IntegrityAudit integrityAudit = new IntegrityAudit(resourceName, persistenceUnit, properties);
+               integrityAudit.startAuditThread();
+               
+               /*
+                * Start audit for pdp2.
+                */
+               Properties properties2 = new Properties();
+               properties2.put(IntegrityAuditProperties.DB_DRIVER, IntegrityAuditProperties.DEFAULT_DB_DRIVER);
+               properties2.put(IntegrityAuditProperties.DB_URL, IntegrityAuditProperties.DEFAULT_DB_URL);
+               properties2.put(IntegrityAuditProperties.DB_USER, IntegrityAuditProperties.DEFAULT_DB_USER);
+               properties2.put(IntegrityAuditProperties.DB_PWD, IntegrityAuditProperties.DEFAULT_DB_PWD);
+               properties2.put(IntegrityAuditProperties.SITE_NAME, "SiteA");
+               properties2.put(IntegrityAuditProperties.NODE_TYPE, "pdp_xacml");
+               properties2.put(IntegrityAuditProperties.AUDIT_PERIOD_SECONDS, "5");
+               String persistenceUnit2 = "testPU";
+               String resourceName2 = "pdp2";
+               IntegrityAudit integrityAudit2 = new IntegrityAudit(resourceName2, persistenceUnit2, properties2);
+               integrityAudit2.startAuditThread();
+               
+               /*
+                * Sleep long enough to allow
+                * 
+                * 1) pdp1 to run audit (15 seconds)
+                * 
+                * 2) Logic to detect that pdp1 is stale and designate pdp2 (30 seconds)
+                * 
+                * 3) pdp2 to run audit (15 seconds)
+                * 
+                * 4) Logic to detect that pdp2 is stale and designate pdp1 (30 seconds)
+                * 
+                * 5) pdp1 to run audit (15 seconds)
+                */
+               Thread.sleep(120000);
+               
+               logger.info("testTwoResources: Stopping audit threads");
+               integrityAudit.stopAuditThread();
+               integrityAudit2.stopAuditThread();
+               
+               FileInputStream fstream = new FileInputStream(TEST_LOG);
+               BufferedReader br = new BufferedReader(new InputStreamReader(fstream));
+               String strLine;
+               int startIndex;
+               int endIndex;
+               ArrayList<String> expectedResult = new ArrayList<String>(Arrays.asList("pdp1", "pdp2", "pdp1"));
+               ArrayList<String> delegates = new ArrayList<String>();
+               while ((strLine = br.readLine()) != null)   {
+                       /* parse strLine to obtain what you want */
+                       if (strLine.contains("Starting audit simulation for resourceName=")) {
+                               startIndex = strLine.indexOf("resourceName=") + 13;
+                               endIndex = strLine.indexOf(",");
+                               
+                               String rName = strLine.substring(startIndex, endIndex);
+                               
+                               delegates.add(rName);
+                       }
+               }
+                               
+               for (String delegate: delegates) {
+                       logger.info("testTwoResources: delegate: " + delegate);
+               }
+               
+               fstream.close();
+                               
+               assertTrue(expectedResult.equals(delegates));
+               
+               assertTrue("delegate count only " + delegates.size(), delegates.size() >= 3);
+               assertTrue("delegate 0 is " + expectedResult.get(0), expectedResult.get(0).equals(delegates.get(0)));
+               assertTrue("delegate 1 is " + expectedResult.get(1), expectedResult.get(1).equals(delegates.get(1)));
+               assertTrue("delegate 2 is " + expectedResult.get(2), expectedResult.get(2).equals(delegates.get(2)));
+       
+               logger.info("testTwoResources: Exiting");
+
+       }
+       
+       /*
+        * Tests designation logic when two functioning resources are in play, each
+        * with different PUs. Audits for "testPU" and "integrityAuditPU" should run
+        * simultaneously. Designation should not alternate.
+        * 
+        * Note: console.log must be examined to ascertain whether or not this test
+        * was successful.
+        */
+       @Ignore
+       @Test
+       public void testTwoResourcesDifferentPus() throws Exception {
+               
+               logger.info("testTwoResourcesDifferentPus: Entering");
+               
+               /*
+                * Start audit for pdp1.
+                */
+               IntegrityAudit integrityAudit = new IntegrityAudit(resourceName, persistenceUnit, properties);
+               integrityAudit.startAuditThread();
+               
+               /*
+                * Start audit for pdp2.
+                */
+               Properties properties2 = new Properties();
+               properties2.put(IntegrityAuditProperties.DB_DRIVER, IntegrityAuditProperties.DEFAULT_DB_DRIVER);
+               properties2.put(IntegrityAuditProperties.DB_URL, IntegrityAuditProperties.DEFAULT_DB_URL);
+               properties2.put(IntegrityAuditProperties.DB_USER, IntegrityAuditProperties.DEFAULT_DB_USER);
+               properties2.put(IntegrityAuditProperties.DB_PWD, IntegrityAuditProperties.DEFAULT_DB_PWD);
+               properties2.put(IntegrityAuditProperties.SITE_NAME, "SiteA");
+               properties2.put(IntegrityAuditProperties.NODE_TYPE, "pdp_xacml");
+               properties2.put(IntegrityAuditProperties.AUDIT_PERIOD_SECONDS, "5");
+               String persistenceUnit2 = "integrityAuditPU";
+               String resourceName2 = "pdp2";
+               IntegrityAudit integrityAudit2 = new IntegrityAudit(resourceName2, persistenceUnit2, properties2);
+               integrityAudit2.startAuditThread();
+               
+               /*
+                * Sleep long enough to allow
+                * 
+                * 1) pdp1 and pdp2 to run audit simultaneously (15 seconds)
+                * 
+                * 2) Logic to detect that no other node is available for designation for either pdp1 or pdp2 (60 seconds)
+                * 
+                * 3) pdp1 and pdp2 to again run audit simultaneously (15 seconds)
+                * 
+                * NOTE: Based on the above, you would think a 100000ms sleep would be appropriate,
+                * but for some reason, when all tests are run this test errors.   
+                */
+               logger.info("testTwoResourcesDifferentPus: Sleeping 80 seconds");
+               Thread.sleep(100000);
+               
+               logger.info("testTwoResourcesDifferentPus: Stopping audit threads");
+               integrityAudit.stopAuditThread();
+               integrityAudit2.stopAuditThread();
+               
+               FileInputStream fstream = new FileInputStream(TEST_LOG);
+               BufferedReader br = new BufferedReader(new InputStreamReader(fstream));
+               String strLine;
+               int startIndex;
+               int endIndex;
+               ArrayList<String> expectedResult = new ArrayList<String>(Arrays.asList("pdp1", "pdp2", "pdp1", "pdp2"));
+               ArrayList<String> delegates = new ArrayList<String>();
+               while ((strLine = br.readLine()) != null)   {
+                       /* parse strLine to obtain what you want */
+                       if (strLine.contains("Starting audit simulation for resourceName=")) {
+                               startIndex = strLine.indexOf("resourceName=") + 13;
+                               endIndex = strLine.indexOf(",");
+                               
+                               String rName = strLine.substring(startIndex, endIndex);
+                               
+                               delegates.add(rName);
+                       }
+               }
+                               
+               for (String delegate: delegates) {
+                       logger.info("testTwoResourcesDifferentPus: delegate: " + delegate);
+               }
+               
+               fstream.close();
+               
+               assertTrue("delegate count only " + delegates.size(), delegates.size() >= 4);
+               assertTrue("delegate 0 is " + expectedResult.get(0), expectedResult.get(0).equals(delegates.get(0)));
+               assertTrue("delegate 1 is " + expectedResult.get(1), expectedResult.get(1).equals(delegates.get(1)));
+               assertTrue("delegate 2 is " + expectedResult.get(2), expectedResult.get(2).equals(delegates.get(2)));
+               assertTrue("delegate 3 is " + expectedResult.get(3), expectedResult.get(3).equals(delegates.get(3)));
+               
+               assertTrue(expectedResult.equals(delegates));
+                               
+               logger.info("testTwoResourcesDifferentPus: Exiting");
+
+       }
+
+       
+       /*
+        * Tests designation logic when two resources are in play but one of them is
+        * dead/hung. Designation should move to second resource but then get
+        * restored back to original resource when it's discovered that second
+        * resource is dead.
+        * 
+        * Note: console.log must be examined to ascertain whether or not this test
+        * was successful.
+        */
+       @Ignore
+       @Test
+       public void testTwoResourcesOneDead() throws Exception {
+               
+               logger.info("testTwoResourcesOneDead: Entering");
+               
+               /*
+                * Start audit for pdp1.
+                */
+               IntegrityAudit integrityAudit = new IntegrityAudit(resourceName, persistenceUnit, properties);
+               integrityAudit.startAuditThread();
+               
+               /*
+                * Populate DB for pdp2, which will simulate it having registered but then having died.
+                */
+               Properties properties2 = new Properties();
+               properties2.put(IntegrityAuditProperties.DB_DRIVER, IntegrityAuditProperties.DEFAULT_DB_DRIVER);
+               properties2.put(IntegrityAuditProperties.DB_URL, IntegrityAuditProperties.DEFAULT_DB_URL);
+               properties2.put(IntegrityAuditProperties.DB_USER, IntegrityAuditProperties.DEFAULT_DB_USER);
+               properties2.put(IntegrityAuditProperties.DB_PWD, IntegrityAuditProperties.DEFAULT_DB_PWD);
+               properties2.put(IntegrityAuditProperties.SITE_NAME, "SiteA");
+               properties2.put(IntegrityAuditProperties.NODE_TYPE, "pdp_xacml");
+               properties2.put(IntegrityAuditProperties.AUDIT_PERIOD_SECONDS, "5");
+               String persistenceUnit2 = "testPU";
+               String resourceName2 = "pdp2";
+               new DbDAO(resourceName2, persistenceUnit2, properties2);
+               
+               /*
+                * Sleep long enough to allow
+                * 
+                * 1) pdp1 to run audit (15 seconds)
+                * 
+                * 2) Logic to detect that other node, pdp2, is not available for designation (60 seconds)
+                * 
+                * 3) pdp1 to run audit again (15 seconds)
+                */
+               logger.info("testTwoResourcesOneDead: Sleeping 100 seconds");
+               Thread.sleep(100000);
+               
+               logger.info("testTwoResourcesOneDead: Stopping audit thread");
+               integrityAudit.stopAuditThread();
+               
+               FileInputStream fstream = new FileInputStream(TEST_LOG);
+               BufferedReader br = new BufferedReader(new InputStreamReader(fstream));
+               String strLine;
+               int startIndex;
+               int endIndex;
+               ArrayList<String> expectedResult = new ArrayList<String>(Arrays.asList("pdp1", "pdp1"));
+               ArrayList<String> delegates = new ArrayList<String>();
+               while ((strLine = br.readLine()) != null)   {
+                       /* parse strLine to obtain what you want */
+                       if (strLine.contains("Starting audit simulation for resourceName=")) {
+                               startIndex = strLine.indexOf("resourceName=") + 13;
+                               endIndex = strLine.indexOf(",");
+                               
+                               String rName = strLine.substring(startIndex, endIndex);
+                               
+                               delegates.add(rName);
+                       }
+               }
+                               
+               for (String delegate: delegates) {
+                       logger.info("testTwoResourcesOneDead: delegate: " + delegate);
+               }
+               
+               fstream.close();
+               
+               assertTrue("delegate count only " + delegates.size(), delegates.size() >= 2);
+               assertTrue("delegate 0 is " + expectedResult.get(0), expectedResult.get(0).equals(delegates.get(0)));
+               assertTrue("delegate 1 is " + expectedResult.get(1), expectedResult.get(1).equals(delegates.get(1)));
+                               
+               logger.info("testTwoResourcesOneDead: Exiting");
+
+       }
+       
+       
+       /*
+        * Tests designation logic when three functioning resources are in play.  Designation should
+        * round robin among resources.
+        * 
+        * Note: console.log must be examined to ascertain whether or not this test was successful.
+        */
+       @Ignore
+       @Test
+       public void testThreeResources() throws Exception {
+               
+               logger.info("testThreeResources: Entering");
+               
+               /*
+                * Start audit for pdp1.
+                */
+               IntegrityAudit integrityAudit = new IntegrityAudit(resourceName, persistenceUnit, properties);
+               integrityAudit.startAuditThread();
+               
+               /*
+                * Start audit for pdp2.
+                */
+               Properties properties2 = new Properties();
+               properties2.put(IntegrityAuditProperties.DB_DRIVER, IntegrityAuditProperties.DEFAULT_DB_DRIVER);
+               properties2.put(IntegrityAuditProperties.DB_URL, IntegrityAuditProperties.DEFAULT_DB_URL);
+               properties2.put(IntegrityAuditProperties.DB_USER, IntegrityAuditProperties.DEFAULT_DB_USER);
+               properties2.put(IntegrityAuditProperties.DB_PWD, IntegrityAuditProperties.DEFAULT_DB_PWD);
+               properties2.put(IntegrityAuditProperties.SITE_NAME, "SiteA");
+               properties2.put(IntegrityAuditProperties.NODE_TYPE, "pdp_xacml");
+               properties2.put(IntegrityAuditProperties.AUDIT_PERIOD_SECONDS, "5");
+               String persistenceUnit2 = "testPU";
+               String resourceName2 = "pdp2";
+               IntegrityAudit integrityAudit2 = new IntegrityAudit(resourceName2, persistenceUnit2, properties2);
+               integrityAudit2.startAuditThread();
+               
+               /*
+                * Start audit for pdp3.
+                */
+               Properties properties3 = new Properties();
+               properties3.put(IntegrityAuditProperties.DB_DRIVER, IntegrityAuditProperties.DEFAULT_DB_DRIVER);
+               properties3.put(IntegrityAuditProperties.DB_URL, IntegrityAuditProperties.DEFAULT_DB_URL);
+               properties3.put(IntegrityAuditProperties.DB_USER, IntegrityAuditProperties.DEFAULT_DB_USER);
+               properties3.put(IntegrityAuditProperties.DB_PWD, IntegrityAuditProperties.DEFAULT_DB_PWD);
+               properties3.put(IntegrityAuditProperties.SITE_NAME, "SiteA");
+               properties3.put(IntegrityAuditProperties.NODE_TYPE, "pdp_xacml");
+               properties3.put(IntegrityAuditProperties.AUDIT_PERIOD_SECONDS, "5");
+               String persistenceUnit3 = "testPU";
+               String resourceName3 = "pdp3";
+               IntegrityAudit integrityAudit3 = new IntegrityAudit(resourceName3, persistenceUnit3, properties3);
+               integrityAudit3.startAuditThread();
+               
+               /*
+                * Sleep long enough to allow
+                * 
+                * 1) pdp1 to run audit (15 seconds)
+                * 
+                * 2) Logic to detect that pdp1 is stale and designate pdp2 (30 seconds)
+                * 
+                * 3) pdp2 to run audit (15 seconds)
+                * 
+                * 4) Logic to detect that pdp2 is stale and designate pdp3 (30 seconds)
+                * 
+                * 5) pdp3 to run audit (15 seconds)
+                * 
+                * 6) Logic to detect that pdp3 is stale and designate pdp1 (30 seconds)
+                * 
+                * 7) pdp1 to run audit (15 seconds)
+                */
+               logger.info("testThreeResources: Sleeping 160 seconds");
+               Thread.sleep(160000);
+               
+               logger.info("testThreeResources: Stopping threads");
+               integrityAudit.stopAuditThread();
+               integrityAudit2.stopAuditThread();
+               integrityAudit3.stopAuditThread();
+               
+               FileInputStream fstream = new FileInputStream(TEST_LOG);
+               BufferedReader br = new BufferedReader(new InputStreamReader(fstream));
+               String strLine;
+               int startIndex;
+               int endIndex;
+               ArrayList<String> expectedResult = new ArrayList<String>(Arrays.asList("pdp1", "pdp2", "pdp3", "pdp1"));
+               ArrayList<String> delegates = new ArrayList<String>();
+               while ((strLine = br.readLine()) != null)   {
+                       /* parse strLine to obtain what you want */
+                       if (strLine.contains("Starting audit simulation for resourceName=")) {
+                               startIndex = strLine.indexOf("resourceName=") + 13;
+                               endIndex = strLine.indexOf(",");
+                               
+                               String rName = strLine.substring(startIndex, endIndex);
+                               
+                               delegates.add(rName);
+                       }
+               }
+               
+               for (String delegate: delegates) {
+                       logger.info("testThreeResources: delegate: " + delegate);
+               }
+               
+               fstream.close();
+               
+               assertTrue("delegate count only " + delegates.size(), delegates.size() >= 3);
+               assertTrue("delegate 0 is " + expectedResult.get(0), expectedResult.get(0).equals(delegates.get(0)));
+               assertTrue("delegate 1 is " + expectedResult.get(1), expectedResult.get(1).equals(delegates.get(1)));
+               assertTrue("delegate 2 is " + expectedResult.get(2), expectedResult.get(2).equals(delegates.get(2)));
+               assertTrue("delegate 3 is " + expectedResult.get(3), expectedResult.get(3).equals(delegates.get(3)));
+                               
+               logger.info("testThreeResources: Exiting");
+
+       }
+       
+       /*
+        * Tests designation logic when four functioning resources are in play, two
+        * with one PU, two with another. Audits for "testPU" and "integrityAuditPU" should run
+        * simultaneously. Designation should alternate between resources for each of the two
+        * persistence units.
+        * 
+        * Note: console.log must be examined to ascertain whether or not this test
+        * was successful.
+        */
+       @Ignore
+       @Test
+       public void testFourResourcesDifferentPus() throws Exception {
+               
+               logger.info("testFourResourcesDifferentPus: Entering");
+               
+               /*
+                * Start audit for pdp1, testPU.
+                */
+               IntegrityAudit integrityAudit = new IntegrityAudit(resourceName, persistenceUnit, properties);
+               integrityAudit.startAuditThread();
+               
+               /*
+                * Start audit for pdp2, integrityAuditPU.
+                */
+               Properties properties2 = new Properties();
+               properties2.put(IntegrityAuditProperties.DB_DRIVER, IntegrityAuditProperties.DEFAULT_DB_DRIVER);
+               properties2.put(IntegrityAuditProperties.DB_URL, IntegrityAuditProperties.DEFAULT_DB_URL);
+               properties2.put(IntegrityAuditProperties.DB_USER, IntegrityAuditProperties.DEFAULT_DB_USER);
+               properties2.put(IntegrityAuditProperties.DB_PWD, IntegrityAuditProperties.DEFAULT_DB_PWD);
+               properties2.put(IntegrityAuditProperties.SITE_NAME, "SiteA");
+               properties2.put(IntegrityAuditProperties.NODE_TYPE, "pdp_xacml");
+               properties2.put(IntegrityAuditProperties.AUDIT_PERIOD_SECONDS, "5");
+               String persistenceUnit2 = "integrityAuditPU";
+               String resourceName2 = "pdp2";
+               IntegrityAudit integrityAudit2 = new IntegrityAudit(resourceName2, persistenceUnit2, properties2);
+               integrityAudit2.startAuditThread();
+               
+               /*
+                * Start audit for pdp3, testPU.
+                */
+               Properties properties3 = new Properties();
+               properties3.put(IntegrityAuditProperties.DB_DRIVER, IntegrityAuditProperties.DEFAULT_DB_DRIVER);
+               properties3.put(IntegrityAuditProperties.DB_URL, IntegrityAuditProperties.DEFAULT_DB_URL);
+               properties3.put(IntegrityAuditProperties.DB_USER, IntegrityAuditProperties.DEFAULT_DB_USER);
+               properties3.put(IntegrityAuditProperties.DB_PWD, IntegrityAuditProperties.DEFAULT_DB_PWD);
+               properties3.put(IntegrityAuditProperties.SITE_NAME, "SiteA");
+               properties3.put(IntegrityAuditProperties.NODE_TYPE, "pdp_xacml");
+               properties3.put(IntegrityAuditProperties.AUDIT_PERIOD_SECONDS, "5");
+               String persistenceUnit3 = "testPU";
+               String resourceName3 = "pdp3";
+               IntegrityAudit integrityAudit3 = new IntegrityAudit(resourceName3, persistenceUnit3, properties3);
+               integrityAudit3.startAuditThread();
+               
+               /*
+                * Start audit for pdp4, integrityAuditPU.
+                */
+               Properties properties4 = new Properties();
+               properties4.put(IntegrityAuditProperties.DB_DRIVER, IntegrityAuditProperties.DEFAULT_DB_DRIVER);
+               properties4.put(IntegrityAuditProperties.DB_URL, IntegrityAuditProperties.DEFAULT_DB_URL);
+               properties4.put(IntegrityAuditProperties.DB_USER, IntegrityAuditProperties.DEFAULT_DB_USER);
+               properties4.put(IntegrityAuditProperties.DB_PWD, IntegrityAuditProperties.DEFAULT_DB_PWD);
+               properties4.put(IntegrityAuditProperties.SITE_NAME, "SiteA");
+               properties4.put(IntegrityAuditProperties.NODE_TYPE, "pdp_xacml");
+               properties4.put(IntegrityAuditProperties.AUDIT_PERIOD_SECONDS, "5");
+               String persistenceUnit4 = "integrityAuditPU";
+               String resourceName4 = "pdp4";
+               IntegrityAudit integrityAudit4 = new IntegrityAudit(resourceName4, persistenceUnit4, properties4);
+               integrityAudit4.startAuditThread();
+               
+               /*
+                * Sleep long enough to allow
+                * 
+                * 1) pdp1 and pdp2 to run audit simultaneously (15 seconds)
+                * 
+                * 2) Logic to detect that pdp1 and pdp2 are stale and designate pdp3 (one's counterpart) and pdp4 (two's counterpart) (30 seconds)
+                * 
+                * 3) pdp3 and pdp4 to run audit simultaneously (15 seconds)
+                * 
+                * 4) Logic to detect that pdp3 and pdp4 are stale and designate pdp1 (three's counterpart) and pdp2 (four's counterpart) (30 seconds)
+                * 
+                * 5) pdp1 and pdp2 to run audit simultaneously (15 seconds)
+                */
+               logger.info("testFourResourcesDifferentPus: Sleeping 120 seconds");
+               Thread.sleep(120000);
+               
+               logger.info("testFourResourcesDifferentPus: Stopping threads");
+               integrityAudit.stopAuditThread();
+               integrityAudit2.stopAuditThread();
+               integrityAudit3.stopAuditThread();
+               integrityAudit4.stopAuditThread();
+               
+               FileInputStream fstream = new FileInputStream(TEST_LOG);
+               BufferedReader br = new BufferedReader(new InputStreamReader(fstream));
+               String strLine;
+               int startIndex;
+               int endIndex;
+               ArrayList<String> expectedResult = new ArrayList<String>(Arrays.asList("pdp1", "pdp2", "pdp3", "pdp4", "pdp1", "pdp2"));
+               ArrayList<String> delegates = new ArrayList<String>();
+               while ((strLine = br.readLine()) != null)   {
+                       /* parse strLine to obtain what you want */
+                       if (strLine.contains("Starting audit simulation for resourceName=")) {
+                               startIndex = strLine.indexOf("resourceName=") + 13;
+                               endIndex = strLine.indexOf(",");
+                               
+                               String rName = strLine.substring(startIndex, endIndex);
+                               
+                               delegates.add(rName);
+                       }
+               }
+                               
+               for (String delegate: delegates) {
+                       logger.info("testFourResourcesDifferentPus: delegate: " + delegate);
+               }
+               
+               fstream.close();
+               
+               assertTrue("delegate count only " + delegates.size(), delegates.size() >= 6);
+               assertTrue("delegate 0 is " + expectedResult.get(0), expectedResult.get(0).equals(delegates.get(0)));
+               assertTrue("delegate 1 is " + expectedResult.get(1), expectedResult.get(1).equals(delegates.get(1)));
+               assertTrue("delegate 2 is " + expectedResult.get(2), expectedResult.get(2).equals(delegates.get(2)));
+               assertTrue("delegate 3 is " + expectedResult.get(3), expectedResult.get(3).equals(delegates.get(3)));
+               assertTrue("delegate 4 is " + expectedResult.get(4), expectedResult.get(4).equals(delegates.get(4)));
+               assertTrue("delegate 5 is " + expectedResult.get(5), expectedResult.get(5).equals(delegates.get(5)));
+                               
+               logger.info("testFourResourcesDifferentPus: Exiting");
+
+       }
+       
+       /*
+        * Tests designation logic when four resources are in play but one is not
+        * functioning. Designation should round robin among functioning resources
+        * only.
+        * 
+        * Note: console.log must be examined to ascertain whether or not this test
+        * was successful.
+        */
+       @Ignore
+       @Test
+       public void testFourResourcesOneDead() throws Exception {
+               
+               logger.info("testFourResourcesOneDead: Entering");
+               
+               /*
+                * Start audit for pdp1.
+                */
+               IntegrityAudit integrityAudit = new IntegrityAudit(resourceName, persistenceUnit, properties);
+               integrityAudit.startAuditThread();
+               
+               /*
+                * Start audit for pdp2.
+                */
+               Properties properties2 = new Properties();
+               properties2.put(IntegrityAuditProperties.DB_DRIVER, IntegrityAuditProperties.DEFAULT_DB_DRIVER);
+               properties2.put(IntegrityAuditProperties.DB_URL, IntegrityAuditProperties.DEFAULT_DB_URL);
+               properties2.put(IntegrityAuditProperties.DB_USER, IntegrityAuditProperties.DEFAULT_DB_USER);
+               properties2.put(IntegrityAuditProperties.DB_PWD, IntegrityAuditProperties.DEFAULT_DB_PWD);
+               properties2.put(IntegrityAuditProperties.SITE_NAME, "SiteA");
+               properties2.put(IntegrityAuditProperties.NODE_TYPE, "pdp_xacml");
+               properties2.put(IntegrityAuditProperties.AUDIT_PERIOD_SECONDS, "5");
+               String persistenceUnit2 = "testPU";
+               String resourceName2 = "pdp2";
+               IntegrityAudit integrityAudit2 = new IntegrityAudit(resourceName2, persistenceUnit2, properties2);
+               integrityAudit2.startAuditThread();
+               
+               /*
+                * Populate DB for pdp3, which will simulate it having registered but then having died.
+                */
+               Properties properties3 = new Properties();
+               properties3.put(IntegrityAuditProperties.DB_DRIVER, IntegrityAuditProperties.DEFAULT_DB_DRIVER);
+               properties3.put(IntegrityAuditProperties.DB_URL, IntegrityAuditProperties.DEFAULT_DB_URL);
+               properties3.put(IntegrityAuditProperties.DB_USER, IntegrityAuditProperties.DEFAULT_DB_USER);
+               properties3.put(IntegrityAuditProperties.DB_PWD, IntegrityAuditProperties.DEFAULT_DB_PWD);
+               properties3.put(IntegrityAuditProperties.SITE_NAME, "SiteA");
+               properties3.put(IntegrityAuditProperties.NODE_TYPE, "pdp_xacml");
+               properties3.put(IntegrityAuditProperties.AUDIT_PERIOD_SECONDS, "5");
+               String persistenceUnit3 = "testPU";
+               String resourceName3 = "pdp3";
+               new DbDAO(resourceName3, persistenceUnit3, properties3);
+               
+               /*
+                * Start audit for pdp4.
+                */
+               Properties properties4 = new Properties();
+               properties4.put(IntegrityAuditProperties.DB_DRIVER, IntegrityAuditProperties.DEFAULT_DB_DRIVER);
+               properties4.put(IntegrityAuditProperties.DB_URL, IntegrityAuditProperties.DEFAULT_DB_URL);
+               properties4.put(IntegrityAuditProperties.DB_USER, IntegrityAuditProperties.DEFAULT_DB_USER);
+               properties4.put(IntegrityAuditProperties.DB_PWD, IntegrityAuditProperties.DEFAULT_DB_PWD);
+               properties4.put(IntegrityAuditProperties.SITE_NAME, "SiteA");
+               properties4.put(IntegrityAuditProperties.NODE_TYPE, "pdp_xacml");
+               properties4.put(IntegrityAuditProperties.AUDIT_PERIOD_SECONDS, "5");
+               String persistenceUnit4 = "testPU";
+               String resourceName4 = "pdp4";
+               IntegrityAudit integrityAudit4 = new IntegrityAudit(resourceName4, persistenceUnit4, properties4);
+               integrityAudit4.startAuditThread();
+               
+               /*
+                * Sleep long enough to allow
+                * 
+                * 1) pdp1 to run audit (15 seconds)
+                * 
+                * 2) Logic to detect that pdp1 is stale and designate pdp2 (30 seconds)
+                * 
+                * 3) pdp2 to run audit (15 seconds)
+                * 
+                * 4) Logic to detect that pdp2 is stale and designate pdp4 (30 seconds)
+                * 
+                * 5) pdp4 to run audit (15 seconds)
+                * 
+                * 6) Logic to detect that pdp4 is stale and designate pdp1 (30 seconds)
+                * 
+                * 7) pdp1 to run audit (15 seconds)
+                * 
+                * 8) Logic to detect that pdp1 is stale and designate pdp2 (30 seconds)
+                * 
+                * 7) pdp2 to run audit (15 seconds)
+                */
+               logger.info("testFourResourcesOneDead: Sleeping 210 seconds");
+               Thread.sleep(210000);
+               
+               logger.info("testFourResourcesOneDead: Stopping threads");              
+               integrityAudit.stopAuditThread();
+               integrityAudit2.stopAuditThread();
+               integrityAudit4.stopAuditThread();
+               
+               FileInputStream fstream = new FileInputStream(TEST_LOG);
+               BufferedReader br = new BufferedReader(new InputStreamReader(fstream));
+               String strLine;
+               int startIndex;
+               int endIndex;
+               ArrayList<String> expectedResult = new ArrayList<String>(Arrays.asList("pdp1", "pdp2", "pdp4", "pdp1", "pdp2", "pdp4"));
+               ArrayList<String> delegates = new ArrayList<String>();
+               while ((strLine = br.readLine()) != null)   {
+                       /* parse strLine to obtain what you want */
+                       if (strLine.contains("Starting audit simulation for resourceName=")) {
+                               startIndex = strLine.indexOf("resourceName=") + 13;
+                               endIndex = strLine.indexOf(",");
+                               
+                               String rName = strLine.substring(startIndex, endIndex);
+
+                               delegates.add(rName);
+                       }
+               }
+               
+               for (String delegate : delegates) {
+                       logger.info("testFourResourcesOneDead: delegate: " + delegate);
+               }
+
+               fstream.close();
+               
+               assertTrue("delegate count only " + delegates.size(), delegates.size() >= 6);
+               assertTrue("delegate 0 is " + expectedResult.get(0), expectedResult.get(0).equals(delegates.get(0)));
+               assertTrue("delegate 1 is " + expectedResult.get(1), expectedResult.get(1).equals(delegates.get(1)));
+               assertTrue("delegate 2 is " + expectedResult.get(2), expectedResult.get(2).equals(delegates.get(2)));
+               assertTrue("delegate 3 is " + expectedResult.get(3), expectedResult.get(3).equals(delegates.get(3)));
+               assertTrue("delegate 4 is " + expectedResult.get(4), expectedResult.get(4).equals(delegates.get(4)));
+               assertTrue("delegate 5 is " + expectedResult.get(5), expectedResult.get(5).equals(delegates.get(5)));
+                               
+               logger.info("testFourResourcesOneDead: Exiting");
+
+       }
+       
+       /*
+        * Tests designation logic when four resources are in play but only one is
+        * functioning. Designation should remain with sole functioning resource.
+        * 
+        * Note: console.log must be examined to ascertain whether or not this test
+        * was successful.
+        */
+       @Ignore
+       @Test
+       public void testFourResourcesThreeDead() throws Exception {
+                               
+               logger.info("testFourResourcesThreeDead: Entering");
+               
+               /*
+                * Populate DB for pdp1, which will simulate it having registered but then having died.
+                */
+               new DbDAO(resourceName, persistenceUnit, properties);
+
+               
+               /*
+                * Populate DB for pdp2, which will simulate it having registered but then having died.
+                */
+               Properties properties2 = new Properties();
+               properties2.put(IntegrityAuditProperties.DB_DRIVER, IntegrityAuditProperties.DEFAULT_DB_DRIVER);
+               properties2.put(IntegrityAuditProperties.DB_URL, IntegrityAuditProperties.DEFAULT_DB_URL);
+               properties2.put(IntegrityAuditProperties.DB_USER, IntegrityAuditProperties.DEFAULT_DB_USER);
+               properties2.put(IntegrityAuditProperties.DB_PWD, IntegrityAuditProperties.DEFAULT_DB_PWD);
+               properties2.put(IntegrityAuditProperties.SITE_NAME, "SiteA");
+               properties2.put(IntegrityAuditProperties.NODE_TYPE, "pdp_xacml");
+               properties2.put(IntegrityAuditProperties.AUDIT_PERIOD_SECONDS, "5");
+               String persistenceUnit2 = "testPU";
+               String resourceName2 = "pdp2";
+               new DbDAO(resourceName2, persistenceUnit2, properties2);
+
+               /*
+                * Start audit for pdp3.
+                */
+               Properties properties3 = new Properties();
+               properties3.put(IntegrityAuditProperties.DB_DRIVER, IntegrityAuditProperties.DEFAULT_DB_DRIVER);
+               properties3.put(IntegrityAuditProperties.DB_URL, IntegrityAuditProperties.DEFAULT_DB_URL);
+               properties3.put(IntegrityAuditProperties.DB_USER, IntegrityAuditProperties.DEFAULT_DB_USER);
+               properties3.put(IntegrityAuditProperties.DB_PWD, IntegrityAuditProperties.DEFAULT_DB_PWD);
+               properties3.put(IntegrityAuditProperties.SITE_NAME, "SiteA");
+               properties3.put(IntegrityAuditProperties.NODE_TYPE, "pdp_xacml");
+               properties3.put(IntegrityAuditProperties.AUDIT_PERIOD_SECONDS, "5");
+               String persistenceUnit3 = "testPU";
+               String resourceName3 = "pdp3";
+               IntegrityAudit integrityAudit3 = new IntegrityAudit(resourceName3, persistenceUnit3, properties3);
+               integrityAudit3.startAuditThread();
+               
+               /*
+                * Populate DB for pdp4, which will simulate it having registered but then having died.
+                */
+               Properties properties4 = new Properties();
+               properties4.put(IntegrityAuditProperties.DB_DRIVER, IntegrityAuditProperties.DEFAULT_DB_DRIVER);
+               properties4.put(IntegrityAuditProperties.DB_URL, IntegrityAuditProperties.DEFAULT_DB_URL);
+               properties4.put(IntegrityAuditProperties.DB_USER, IntegrityAuditProperties.DEFAULT_DB_USER);
+               properties4.put(IntegrityAuditProperties.DB_PWD, IntegrityAuditProperties.DEFAULT_DB_PWD);
+               properties4.put(IntegrityAuditProperties.SITE_NAME, "SiteA");
+               properties4.put(IntegrityAuditProperties.NODE_TYPE, "pdp_xacml");
+               properties4.put(IntegrityAuditProperties.AUDIT_PERIOD_SECONDS, "5");
+               String persistenceUnit4 = "testPU";
+               String resourceName4 = "pdp4";
+               new DbDAO(resourceName4, persistenceUnit4, properties4);
+                               
+               /*
+                * Sleep long enough to allow
+                * 
+                * 1) pdp3 to discover that all other designation candidates are stale (30 seconds)
+                * 
+                * 1) pdp3 to run audit (15 seconds)
+                * 
+                * 2) Logic to detect that no other nodes are available for designation (60 seconds)
+                * 
+                * 3) pdp3 to run audit again (15 seconds)
+                */
+               logger.info("testFourResourcesThreeDead: Sleeping 130 seconds");
+               Thread.sleep(130000);
+               
+               logger.info("testFourResourcesThreeDead: Stopping thread");
+               integrityAudit3.stopAuditThread();
+               
+               FileInputStream fstream = new FileInputStream(TEST_LOG);
+               BufferedReader br = new BufferedReader(new InputStreamReader(fstream));
+               String strLine;
+               int startIndex;
+               int endIndex;
+               ArrayList<String> expectedResult = new ArrayList<String>(Arrays.asList("pdp3", "pdp3"));
+               ArrayList<String> delegates = new ArrayList<String>();
+               while ((strLine = br.readLine()) != null)   {
+                       /* parse strLine to obtain what you want */
+                       if (strLine.contains("Starting audit simulation for resourceName=")) {
+                               startIndex = strLine.indexOf("resourceName=") + 13;
+                               endIndex = strLine.indexOf(",");
+                               
+                               String rName = strLine.substring(startIndex, endIndex);
+
+                               delegates.add(rName);
+                       }
+               }
+               
+               for (String delegate : delegates) {
+                       logger.info("testFourResourcesThreeDead: delegate: " + delegate);
+               }
+
+               fstream.close();
+               
+               assertTrue("delegate count only " + delegates.size(), delegates.size() >= 2);
+               assertTrue("delegate 0 is " + expectedResult.get(0), expectedResult.get(0).equals(delegates.get(0)));
+               assertTrue("delegate 1 is " + expectedResult.get(1), expectedResult.get(1).equals(delegates.get(1)));
+               
+               logger.info("testFourResourcesThreeDead: Exiting");
+
+       }
+
+
+       /*
+        * Tests designation logic when the designated node dies and is no longer
+        * current
+        * 
+        * Note: console.log must be examined to ascertain whether or not this test
+        * was successful.
+        */
+       @Ignore
+       @Test
+       public void testDesignatedNodeDead() throws Exception {
+               logger.info("testDesignatedNodeDead: Entering");
+               
+               /*
+                * Instantiate audit object for pdp1.
+                */
+               IntegrityAudit integrityAudit = new IntegrityAudit(resourceName, persistenceUnit, properties);
+               
+               /*
+                * Start audit for pdp2.
+                */
+               Properties properties2 = new Properties();
+               properties2.put(IntegrityAuditProperties.DB_DRIVER, IntegrityAuditProperties.DEFAULT_DB_DRIVER);
+               properties2.put(IntegrityAuditProperties.DB_URL, IntegrityAuditProperties.DEFAULT_DB_URL);
+               properties2.put(IntegrityAuditProperties.DB_USER, IntegrityAuditProperties.DEFAULT_DB_USER);
+               properties2.put(IntegrityAuditProperties.DB_PWD, IntegrityAuditProperties.DEFAULT_DB_PWD);
+               properties2.put(IntegrityAuditProperties.SITE_NAME, "SiteA");
+               properties2.put(IntegrityAuditProperties.NODE_TYPE, "pdp_xacml");
+               properties2.put(IntegrityAuditProperties.AUDIT_PERIOD_SECONDS, "5");
+               String persistenceUnit2 = "testPU";
+               String resourceName2 = "pdp2";
+               IntegrityAudit integrityAudit2 = new IntegrityAudit(resourceName2, persistenceUnit2, properties2);
+
+               /*
+                * Instantiate audit object for pdp3.
+                */
+               Properties properties3 = new Properties();
+               properties3.put(IntegrityAuditProperties.DB_DRIVER, IntegrityAuditProperties.DEFAULT_DB_DRIVER);
+               properties3.put(IntegrityAuditProperties.DB_URL, IntegrityAuditProperties.DEFAULT_DB_URL);
+               properties3.put(IntegrityAuditProperties.DB_USER, IntegrityAuditProperties.DEFAULT_DB_USER);
+               properties3.put(IntegrityAuditProperties.DB_PWD, IntegrityAuditProperties.DEFAULT_DB_PWD);
+               properties3.put(IntegrityAuditProperties.SITE_NAME, "SiteA");
+               properties3.put(IntegrityAuditProperties.NODE_TYPE, "pdp_xacml");
+               properties3.put(IntegrityAuditProperties.AUDIT_PERIOD_SECONDS, "5");
+               String persistenceUnit3 = "testPU";
+               String resourceName3 = "pdp3";
+               IntegrityAudit integrityAudit3 = new IntegrityAudit(resourceName3, persistenceUnit3, properties3);
+                               
+               // 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.
+               integrityAudit2.startAuditThread();     
+               integrityAudit3.startAuditThread();             
+               
+               // Sleep long enough to ensure the other two audits have registered. 
+               Thread.sleep(500); 
+               
+               // Kill audit on pdp1
+               integrityAudit.stopAuditThread();
+               
+               // 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.
+               integrityAudit.startAuditThread(); 
+               
+               // 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);
+               
+               // Kill audit on pdp3
+               logger.info("testDesignatedNodeDead: Killing audit on pdp3");
+               integrityAudit3.stopAuditThread();
+               
+               // 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);
+               BufferedReader br = new BufferedReader(new InputStreamReader(fstream));
+               String strLine;
+               int startIndex;
+               int endIndex;
+               ArrayList<String> expectedResult = new ArrayList<String>(Arrays.asList("pdp1", "pdp2", "pdp3", "pdp1"));
+               ArrayList<String> delegates = new ArrayList<String>();
+               while ((strLine = br.readLine()) != null)   {
+                       /* parse strLine to obtain what you want */
+                       if (strLine.contains("Starting audit simulation for resourceName=")) {
+                               startIndex = strLine.indexOf("resourceName=") + 13;
+                               endIndex = strLine.indexOf(",");
+                               
+                               String rName = strLine.substring(startIndex, endIndex);
+                               
+                               delegates.add(rName);
+                       }
+               }
+               fstream.close();
+               
+               // Stop remaining threads.
+               logger.info("testDesignatedNodeDead: Stopping remaining threads");
+               integrityAudit.stopAuditThread();
+               integrityAudit2.stopAuditThread();
+               
+               for (String delegate: delegates) {
+                       logger.info("testDesignatedNodeDead: delegate: " + delegate);
+               }
+               
+               assertTrue("delegate count only " + delegates.size(), delegates.size() >= 4);
+               assertTrue("delegate 0 is " + expectedResult.get(0), expectedResult.get(0).equals(delegates.get(0)));
+               assertTrue("delegate 1 is " + expectedResult.get(1), expectedResult.get(1).equals(delegates.get(1)));
+               assertTrue("delegate 2 is " + expectedResult.get(2), expectedResult.get(2).equals(delegates.get(2)));
+               assertTrue("delegate 3 is " + expectedResult.get(3), expectedResult.get(3).equals(delegates.get(3)));
+               
+               logger.info("testDesignatedNodeDead: Exiting");
+       }
+}
diff --git a/integrity-audit/src/test/java/org/openecomp/policy/common/ia/test/jpa/IaTestEntity.java b/integrity-audit/src/test/java/org/openecomp/policy/common/ia/test/jpa/IaTestEntity.java
new file mode 100644 (file)
index 0000000..e875fa3
--- /dev/null
@@ -0,0 +1,163 @@
+/*-
+ * ============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=========================================================
+ */
+
+package org.openecomp.policy.common.ia.test.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="IaTestEntity")
+@NamedQueries({
+       @NamedQuery(name=" IaTestEntity.findAll", query="SELECT e FROM IaTestEntity e "),
+       @NamedQuery(name="IaTestEntity.deleteAll", query="DELETE FROM IaTestEntity WHERE 1=1")
+})
+//@SequenceGenerator(name="seqImTest", initialValue=1, allocationSize=1)
+
+public class IaTestEntity 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";
+       
+       @Column(name="person", nullable=false, length=255)
+       private PersonTest person;
+
+       @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 IaTestEntity() {
+       }
+
+       @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;
+       }
+       
+       /**
+        * @param the person to set
+        */
+       public void setPersonTest(PersonTest p) {
+               this.person = p;
+       }
+       
+       /**
+        * @return the person
+        */
+       public PersonTest getPersonTest() {
+               return person;
+       }
+}
diff --git a/integrity-audit/src/test/java/org/openecomp/policy/common/ia/test/jpa/PersonTest.java b/integrity-audit/src/test/java/org/openecomp/policy/common/ia/test/jpa/PersonTest.java
new file mode 100644 (file)
index 0000000..7ec5e29
--- /dev/null
@@ -0,0 +1,64 @@
+/*-
+ * ============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=========================================================
+ */
+
+package org.openecomp.policy.common.ia.test.jpa;
+
+import java.io.Serializable;
+
+public class PersonTest implements Serializable {
+       /**
+        * 
+        */
+       private static final long serialVersionUID = 1L;
+       private String firstName;
+       private String lastName;
+       private int age;
+       
+       public PersonTest(String first, String last, int age) {
+               this.firstName = first;
+               this.lastName = last;
+               this.age = age;
+       }
+       
+       public String getFirstName() {
+               return this.firstName;
+       }
+       
+       public void setFirstName(String name) {
+               this.firstName = name;
+       }
+       
+       public String getLasttName() {
+               return this.lastName;
+       }
+       
+       public void setLastName(String name) {
+               this.lastName = name;
+       }
+       
+       public int getAge() {
+               return this.age;
+       }
+       
+       public void setAge(int age) {
+               this.age = age;
+       }
+       
+}
diff --git a/integrity-audit/src/test/resources/log4j.properties b/integrity-audit/src/test/resources/log4j.properties
new file mode 100644 (file)
index 0000000..3defb16
--- /dev/null
@@ -0,0 +1,54 @@
+###
+# ============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=========================================================
+###
+
+#
+# Use this properties for debugging and development.
+#
+#
+# For debug output, set root logger level to DEBUG and output to FILE and CONSOLE
+log4j.rootLogger=DEBUG, FILE, CONSOLE
+#log4j.rootLogger=INFO, FILE, CONSOLE
+
+# A1 is set to be a DailyRollingFileAppender.
+log4j.appender.FILE=org.apache.log4j.DailyRollingFileAppender
+
+# Set the name of the file
+log4j.appender.FILE.File=IntegrityAudit.log
+
+# Set the immediate flush to true (default)
+log4j.appender.FILE.ImmediateFlush=true
+
+# Set the threshold to debug mode
+log4j.appender.FILE.Threshold=debug
+
+# Set the append to false, should not overwrite
+log4j.appender.FILE.Append=true
+
+# Set the DatePattern
+log4j.appender.FILE.DatePattern='.'yyyy-MM-dd
+
+# A1 uses PatternLayout.
+log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
+log4j.appender.FILE.layout.ConversionPattern=%d{yyyy_MM_dd_HH_mm_ss_SSS} [%t] %-5p %l- %m%n
+
+# for Developments and Debugging
+log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
+log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
+log4j.appender.CONSOLE.layout.ConversionPattern=%d{yyyy_MM_dd_HH_mm_ss_SSS} [%t] %-5p %l- %m%n
diff --git a/integrity-audit/src/test/resources/logback.xml b/integrity-audit/src/test/resources/logback.xml
new file mode 100644 (file)
index 0000000..78de63a
--- /dev/null
@@ -0,0 +1,209 @@
+<!--
+  ============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=========================================================
+  -->
+
+<!-- Controls the output of logs for JUnit tests -->
+
+<configuration scan="true" scanPeriod="3 seconds" debug="true">
+  <!--<jmxConfigurator /> -->
+  <!-- directory path for all other type logs -->
+  <property name="logDir" value="testingLogs" />
+  
+  <!-- directory path for debugging type logs -->
+  <property name="debugDir" value="testingLogs" />
+  
+  <!--  specify the component name 
+    <ECOMP-component-name>::= "MSO" | "DCAE" | "ASDC " | "AAI" |"Policy" | "SDNC" | "AC"  -->
+  <property name="componentName" value="common-modules"></property>
+  <property name="subComponentName" value="integrity-audit"></property>
+  
+  <!--  log file names -->
+  <property name="errorLogName" value="error" />
+  <property name="metricsLogName" value="metrics" />
+  <property name="auditLogName" value="audit" />
+  <property name="debugLogName" value="debug" />
+  
+   <property name="defaultPattern" value="%d{&quot;yyyy-MM-dd'T'HH:mm:ss.SSSXXX&quot;, UTC}|%X{requestId}|%X{serviceInstanceId}|%t|%X{serverName}|%X{serviceName}|%X{instanceUuid}|%p|%X{severity}|%X{serverIpAddress}|%X{server}|%X{clientIpAddress}|%c||%msg%n" />
+   <!--  <property name="defaultPattern" value="%d{&quot;yyyy-MM-dd'T'HH:mm:ss.SSSXXX&quot;, UTC}|%X{RequestId}|%X{ServiceInstanceId}|%thread||%X{ServiceName}|%X{InstanceUUID}|%.-5level|%X{AlertSeverity}|%X{ServerIPAddress}|%X{ServerFQDN}|%X{RemoteHost}||%X{Timer}|%msg%n" />  -->
+  <property name="logDirectory" value="${logDir}/${componentName}/${subComponentName}" />
+  <property name="debugLogDirectory" value="${debugDir}/${componentName}/${subComponentName}" />
+   <!--
+  <property name="logDirectory" value="${logDir}/${componentName}/${subComponentName}" />
+  <property name="debugLogDirectory" value="${debugDir}/${componentName}/${subComponentName}" />
+  -->
+  <!-- example from old log4j.properties:  ${catalina.base}/logs/pdp-rest.log  -->  
+  <!-- Example evaluator filter applied against console appender -->
+  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+    <encoder>
+      <pattern>${defaultPattern}</pattern>
+    </encoder>
+  </appender>
+
+  <!-- ============================================================================ -->
+  <!-- EELF Appenders -->
+  <!-- ============================================================================ -->
+
+  <!-- The EELFAppender is used to record events to the general application 
+    log -->
+    
+    
+
+  
+  <!-- EELF Audit Appender. This appender is used to record audit engine 
+    related logging events. The audit logger and appender are specializations 
+    of the EELF application root logger and appender. This can be used to segregate 
+    Policy engine events from other components, or it can be eliminated to record 
+    these events as part of the application root log. -->
+    
+  <appender name="EELFAudit"
+    class="ch.qos.logback.core.rolling.RollingFileAppender">
+    <file>${logDirectory}/${auditLogName}.log</file>
+    <rollingPolicy
+      class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
+      <fileNamePattern>${logDirectory}/${auditLogName}.%i.log.zip
+      </fileNamePattern>
+      <minIndex>1</minIndex>
+      <maxIndex>9</maxIndex>
+    </rollingPolicy>
+    <triggeringPolicy
+      class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
+      <maxFileSize>5MB</maxFileSize>
+    </triggeringPolicy>
+    <encoder>
+         <pattern>${defaultPattern}</pattern>
+    </encoder>
+  </appender>
+  <appender name="asyncEELFAudit" class="ch.qos.logback.classic.AsyncAppender">
+    <queueSize>256</queueSize>
+    <appender-ref ref="EELFAudit" />
+  </appender>
+
+<appender name="EELFMetrics"
+    class="ch.qos.logback.core.rolling.RollingFileAppender">
+    <file>${logDirectory}/${metricsLogName}.log</file>
+    <rollingPolicy
+      class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
+      <fileNamePattern>${logDirectory}/${metricsLogName}.%i.log.zip
+      </fileNamePattern>
+      <minIndex>1</minIndex>
+      <maxIndex>9</maxIndex>
+    </rollingPolicy>
+    <triggeringPolicy
+      class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
+      <maxFileSize>5MB</maxFileSize>
+    </triggeringPolicy>
+    <encoder>
+      <!-- <pattern>"%d{HH:mm:ss.SSS} [%thread] %-5level %logger{1024} - 
+        %msg%n"</pattern> -->
+      <pattern>${defaultPattern}</pattern>
+    </encoder>
+  </appender>
+  
+  
+  <appender name="asyncEELFMetrics" class="ch.qos.logback.classic.AsyncAppender">
+    <queueSize>256</queueSize>
+    <appender-ref ref="EELFMetrics"/>
+  </appender>
+   
+  <appender name="EELFError"
+    class="ch.qos.logback.core.rolling.RollingFileAppender">
+    <file>${logDirectory}/${errorLogName}.log</file>
+    <rollingPolicy
+      class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
+      <fileNamePattern>${logDirectory}/${errorLogName}.%i.log.zip
+      </fileNamePattern>
+      <minIndex>1</minIndex>
+      <maxIndex>9</maxIndex>
+    </rollingPolicy>
+    <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
+     <level>ERROR</level>
+     </filter>
+    <triggeringPolicy
+      class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
+      <maxFileSize>5MB</maxFileSize>
+    </triggeringPolicy>
+    <encoder>
+      <pattern>${defaultPattern}</pattern>
+    </encoder>
+  </appender>
+  
+  <appender name="asyncEELFError" class="ch.qos.logback.classic.AsyncAppender">
+    <queueSize>256</queueSize>
+    <appender-ref ref="EELFError"/>
+  </appender>
+  
+   <appender name="EELFDebug"
+    class="ch.qos.logback.core.rolling.RollingFileAppender">
+    <file>${debugLogDirectory}/${debugLogName}.log</file>
+    <rollingPolicy
+      class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
+      <fileNamePattern>${debugLogDirectory}/${debugLogName}.%i.log.zip
+      </fileNamePattern>
+      <minIndex>1</minIndex>
+      <maxIndex>9</maxIndex>
+    </rollingPolicy>
+    <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
+     <!-- <level>INFO</level> -->
+     <level>DEBUG</level>
+     </filter>
+    <triggeringPolicy
+      class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
+      <maxFileSize>5MB</maxFileSize>
+    </triggeringPolicy>
+    <encoder>
+      <pattern>${defaultPattern}</pattern>
+    </encoder>
+  </appender>
+  
+  <appender name="asyncEELFDebug" class="ch.qos.logback.classic.AsyncAppender">
+    <queueSize>256</queueSize>
+    <appender-ref ref="EELFDebug" />
+    <includeCallerData>true</includeCallerData>
+  </appender>
+  
+  <!-- ============================================================================ -->
+  <!--  EELF loggers -->
+  <!-- ============================================================================ -->
+  <logger name="com.att.eelf.audit" level="info" additivity="false">
+    <appender-ref ref="asyncEELFAudit" />
+  </logger>
+  
+  <logger name="com.att.eelf.metrics" level="info" additivity="false">
+        <appender-ref ref="asyncEELFMetrics" />
+  </logger>
+    <logger name="com.att.eelf.error" level="error" additivity="false">
+  <appender-ref ref="asyncEELFError" />
+  </logger>
+  
+   <!-- <logger name="com.att.eelf.debug" level="info" additivity="false"> -->
+   <logger name="com.att.eelf.debug" level="debug" additivity="false">
+        <appender-ref ref="asyncEELFDebug" />
+  </logger>
+  
+  
+  <!-- <root level="INFO"> -->
+  <root level="DEBUG">
+        <appender-ref ref="asyncEELFDebug" />
+        <appender-ref ref="asyncEELFError" />
+  </root>
+
+</configuration>
diff --git a/integrity-audit/src/test/resources/policyLogger.properties b/integrity-audit/src/test/resources/policyLogger.properties
new file mode 100644 (file)
index 0000000..cb5ef8d
--- /dev/null
@@ -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=DEBUG
+# 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/policyLogger.properties b/integrity-monitor/policyLogger.properties
new file mode 100644 (file)
index 0000000..6a4c2d1
--- /dev/null
@@ -0,0 +1,44 @@
+###
+# ============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=========================================================
+###
+
+################################### 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/pom.xml b/integrity-monitor/pom.xml
new file mode 100644 (file)
index 0000000..9265df5
--- /dev/null
@@ -0,0 +1,115 @@
+<!--
+  ============LICENSE_START=======================================================
+  ECOMP Policy Engine - Common Modules
+  ================================================================================
+  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=========================================================
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+       <modelVersion>4.0.0</modelVersion>
+
+       <groupId>org.openecomp.policy.common</groupId>
+       <artifactId>integrity-monitor</artifactId>
+
+       <packaging>jar</packaging>
+
+       <parent>
+               <groupId>org.openecomp.policy.common</groupId>
+               <artifactId>common-modules</artifactId>
+               <version>1.0.0-SNAPSHOT</version>
+       </parent>
+
+       <name>Integrity Monitor</name>
+
+       <dependencies>
+               <dependency>
+                       <groupId>log4j</groupId>
+                       <artifactId>log4j</artifactId>
+                       <version>1.2.17</version>
+               </dependency>
+               <dependency>
+                       <groupId>junit</groupId>
+                       <artifactId>junit</artifactId>
+                       <version>4.11</version>
+                       <scope>test</scope>
+               </dependency>   
+               <dependency>
+                       <groupId>commons-logging</groupId>
+                       <artifactId>commons-logging</artifactId>
+                       <version>1.1.3</version>
+                       <scope>test</scope>
+               </dependency>   
+               <dependency>
+                       <groupId>org.eclipse.persistence</groupId>
+                       <artifactId>javax.persistence</artifactId>
+                       <version>2.1.0</version>
+               </dependency>
+               <dependency>
+                       <groupId>org.eclipse.persistence</groupId>
+                       <artifactId>eclipselink</artifactId>
+                       <version>2.6.0</version>
+               </dependency>
+               <dependency>
+                       <groupId>com.h2database</groupId>
+                       <artifactId>h2</artifactId>
+                       <version>[1.4.186,)</version>
+               </dependency>
+               <dependency>
+                        <groupId>org.openecomp.policy.common</groupId>
+                        <artifactId>ECOMP-Logging</artifactId>
+                        <version>${project.version}</version>
+               </dependency>
+       </dependencies>
+
+       <build>
+               <pluginManagement>
+                       <plugins>
+                               <!--This plugin's configuration is used to store Eclipse m2e settings 
+                                       only. It has no influence on the Maven build itself. -->
+                               <plugin>
+                                       <groupId>org.eclipse.m2e</groupId>
+                                       <artifactId>lifecycle-mapping</artifactId>
+                                       <version>1.0.0</version>
+                                       <configuration>
+                                               <lifecycleMappingMetadata>
+                                                       <pluginExecutions>
+                                                               <pluginExecution>
+                                                                       <pluginExecutionFilter>
+                                                                               <groupId>org.jacoco</groupId>
+                                                                               <artifactId>
+                                                                                       jacoco-maven-plugin
+                                                                               </artifactId>
+                                                                               <versionRange>
+                                                                                       [0.7.1.201405082137,)
+                                                                               </versionRange>
+                                                                               <goals>
+                                                                                       <goal>prepare-agent</goal>
+                                                                               </goals>
+                                                                       </pluginExecutionFilter>
+                                                                       <action>
+                                                                               <ignore></ignore>
+                                                                       </action>
+                                                               </pluginExecution>
+                                                       </pluginExecutions>
+                                               </lifecycleMappingMetadata>
+                                       </configuration>
+                               </plugin>
+                       </plugins>
+               </pluginManagement>
+       </build>
+</project>
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 (file)
index 0000000..1115c17
--- /dev/null
@@ -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 (file)
index 0000000..982f71a
--- /dev/null
@@ -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 (file)
index 0000000..6c575ab
--- /dev/null
@@ -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<String, IntegrityMonitor> imInstances = new HashMap<String, IntegrityMonitor>();
+       
+       // 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 (file)
index 0000000..8c3d7e6
--- /dev/null
@@ -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 (file)
index 0000000..07737e1
--- /dev/null
@@ -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 (file)
index 0000000..3167dde
--- /dev/null
@@ -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 (file)
index 0000000..8906bb7
--- /dev/null
@@ -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 (file)
index 0000000..6c6ce59
--- /dev/null
@@ -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 (file)
index 0000000..14d35e1
--- /dev/null
@@ -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<StateManagementEntity> 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 (file)
index 0000000..3bc5bbc
--- /dev/null
@@ -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<String, String> StateTable = new HashMap<String, String>(); 
+    
+  /**
+   * 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 (file)
index 0000000..4d8399a
--- /dev/null
@@ -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<MBeanServer> mbeanServers =
+                       MBeanServerFactory.findMBeanServer(null);
+
+               Iterator<MBeanServer> 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 (file)
index 0000000..5cf24b6
--- /dev/null
@@ -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 (file)
index 0000000..4940c4d
--- /dev/null
@@ -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<String, Object> env = new HashMap<String, Object>();
+               
+               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 (file)
index 0000000..4662f58
--- /dev/null
@@ -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 (file)
index 0000000..0eee38b
--- /dev/null
@@ -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 (file)
index 0000000..c7eec08
--- /dev/null
@@ -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 (file)
index 0000000..b747c8f
--- /dev/null
@@ -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; 
+       }
+}
diff --git a/integrity-monitor/src/main/resources/META-INF/persistence.xml b/integrity-monitor/src/main/resources/META-INF/persistence.xml
new file mode 100644 (file)
index 0000000..9436010
--- /dev/null
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ============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=========================================================
+  -->
+
+<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
+       <persistence-unit name="schemaPU" transaction-type="RESOURCE_LOCAL">
+       <!-- Limited use for generating the DB and schema files for imtest DB - uses eclipselink -->
+               <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
+               <class>org.openecomp.policy.common.im.jpa.ImTestEntity</class>
+               <class>org.openecomp.policy.common.im.jpa.StateManagementEntity</class>
+               <class>org.openecomp.policy.common.im.jpa.ForwardProgressEntity</class>
+               <class>org.openecomp.policy.common.im.jpa.ResourceRegistrationEntity</class>
+               <shared-cache-mode>NONE</shared-cache-mode>
+               <properties>
+                       <property name="javax.persistence.schema-generation.database.action" value="drop-and-create"/>
+                       <property name="javax.persistence.schema-generation.scripts.action" value="drop-and-create"/> 
+            <property name="javax.persistence.schema-generation.scripts.create-target" value="./sql/generatedCreateNcomp.ddl"/>
+            <property name="javax.persistence.schema-generation.scripts.drop-target" value="./sql/generatedDropNcomp.ddl"/>
+        </properties>
+       </persistence-unit>
+
+       <persistence-unit name="operationalPU" transaction-type="RESOURCE_LOCAL">
+       <!-- For operational use -->
+               <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
+               <class>org.openecomp.policy.common.im.jpa.ImTestEntity</class>
+               <class>org.openecomp.policy.common.im.jpa.StateManagementEntity</class>
+               <class>org.openecomp.policy.common.im.jpa.ForwardProgressEntity</class>
+               <class>org.openecomp.policy.common.im.jpa.ResourceRegistrationEntity</class>
+               <shared-cache-mode>NONE</shared-cache-mode>     
+               <properties>
+                       <!-- none -->
+        </properties>
+       </persistence-unit>
+</persistence>
diff --git a/integrity-monitor/src/main/resources/log4j.properties b/integrity-monitor/src/main/resources/log4j.properties
new file mode 100644 (file)
index 0000000..fde133d
--- /dev/null
@@ -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=========================================================
+###
+
+#
+# Use this properties for debugging and development.
+#
+#
+# Set root logger level to DEBUG and its only appender to A1.
+log4j.rootLogger=INFO, FILE
+
+# A1 is set to be a DailyRollingFileAppender.
+log4j.appender.FILE=org.apache.log4j.DailyRollingFileAppender
+
+# Set the name of the file
+log4j.appender.FILE.File=IntegrityMonitor.log
+
+# Set the immediate flush to true (default)
+log4j.appender.FILE.ImmediateFlush=true
+
+# Set the threshold to debug mode
+log4j.appender.FILE.Threshold=debug
+
+# Set the append to false, should not overwrite
+log4j.appender.FILE.Append=true
+
+# Set the DatePattern
+log4j.appender.FILE.DatePattern='.'yyyy-MM-dd
+
+# A1 uses PatternLayout.
+log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
+log4j.appender.FILE.layout.ConversionPattern=%d{yyyy_MM_dd_HH_mm_ss_SSS} [%t] %-5p %l- %m%n
diff --git a/integrity-monitor/src/main/resources/logback.xml b/integrity-monitor/src/main/resources/logback.xml
new file mode 100644 (file)
index 0000000..1c88809
--- /dev/null
@@ -0,0 +1,205 @@
+<!--
+  ============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=========================================================
+  -->
+
+<configuration scan="true" scanPeriod="3 seconds" debug="true">
+  <!--<jmxConfigurator /> -->
+  <!-- directory path for all other type logs -->
+  <property name="logDir" value="logs" />
+  
+  <!-- directory path for debugging type logs -->
+  <property name="debugDir" value="logs" />
+  
+  <!--  specify the component name 
+    <ECOMP-component-name>::= "MSO" | "DCAE" | "ASDC " | "AAI" |"Policy" | "SDNC" | "AC"  -->
+  <property name="componentName" value="common-modules"></property>
+  <property name="subComponentName" value="integrity-monitor"></property>
+  
+  <!--  log file names -->
+  <property name="errorLogName" value="error" />
+  <property name="metricsLogName" value="metrics" />
+  <property name="auditLogName" value="audit" />
+  <property name="debugLogName" value="debug" />
+  
+   <property name="defaultPattern" value="%d{&quot;yyyy-MM-dd'T'HH:mm:ss.SSSXXX&quot;, UTC}|%X{requestId}|%X{serviceInstanceId}|%t|%X{serverName}|%X{serviceName}|%X{instanceUuid}|%p|%X{severity}|%X{serverIpAddress}|%X{server}|%X{clientIpAddress}|%c||%msg%n" />
+   <!--  <property name="defaultPattern" value="%d{&quot;yyyy-MM-dd'T'HH:mm:ss.SSSXXX&quot;, UTC}|%X{RequestId}|%X{ServiceInstanceId}|%thread||%X{ServiceName}|%X{InstanceUUID}|%.-5level|%X{AlertSeverity}|%X{ServerIPAddress}|%X{ServerFQDN}|%X{RemoteHost}||%X{Timer}|%msg%n" />  -->
+  <property name="logDirectory" value="${logDir}/${componentName}/${subComponentName}" />
+  <property name="debugLogDirectory" value="${debugDir}/${componentName}/${subComponentName}" />
+   <!--
+  <property name="logDirectory" value="${logDir}/${componentName}/${subComponentName}" />
+  <property name="debugLogDirectory" value="${debugDir}/${componentName}/${subComponentName}" />
+  -->
+  <!-- example from old log4j.properties:  ${catalina.base}/logs/pdp-rest.log  -->  
+  <!-- Example evaluator filter applied against console appender -->
+  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+    <encoder>
+      <pattern>${defaultPattern}</pattern>
+    </encoder>
+  </appender>
+
+  <!-- ============================================================================ -->
+  <!-- EELF Appenders -->
+  <!-- ============================================================================ -->
+
+  <!-- The EELFAppender is used to record events to the general application 
+    log -->
+    
+    
+
+  
+  <!-- EELF Audit Appender. This appender is used to record audit engine 
+    related logging events. The audit logger and appender are specializations 
+    of the EELF application root logger and appender. This can be used to segregate 
+    Policy engine events from other components, or it can be eliminated to record 
+    these events as part of the application root log. -->
+    
+  <appender name="EELFAudit"
+    class="ch.qos.logback.core.rolling.RollingFileAppender">
+    <file>${logDirectory}/${auditLogName}.log</file>
+    <rollingPolicy
+      class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
+      <fileNamePattern>${logDirectory}/${auditLogName}.%i.log.zip
+      </fileNamePattern>
+      <minIndex>1</minIndex>
+      <maxIndex>9</maxIndex>
+    </rollingPolicy>
+    <triggeringPolicy
+      class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
+      <maxFileSize>5MB</maxFileSize>
+    </triggeringPolicy>
+    <encoder>
+         <pattern>${defaultPattern}</pattern>
+    </encoder>
+  </appender>
+  <appender name="asyncEELFAudit" class="ch.qos.logback.classic.AsyncAppender">
+    <queueSize>256</queueSize>
+    <appender-ref ref="EELFAudit" />
+  </appender>
+
+<appender name="EELFMetrics"
+    class="ch.qos.logback.core.rolling.RollingFileAppender">
+    <file>${logDirectory}/${metricsLogName}.log</file>
+    <rollingPolicy
+      class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
+      <fileNamePattern>${logDirectory}/${metricsLogName}.%i.log.zip
+      </fileNamePattern>
+      <minIndex>1</minIndex>
+      <maxIndex>9</maxIndex>
+    </rollingPolicy>
+    <triggeringPolicy
+      class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
+      <maxFileSize>5MB</maxFileSize>
+    </triggeringPolicy>
+    <encoder>
+      <!-- <pattern>"%d{HH:mm:ss.SSS} [%thread] %-5level %logger{1024} - 
+        %msg%n"</pattern> -->
+      <pattern>${defaultPattern}</pattern>
+    </encoder>
+  </appender>
+  
+  
+  <appender name="asyncEELFMetrics" class="ch.qos.logback.classic.AsyncAppender">
+    <queueSize>256</queueSize>
+    <appender-ref ref="EELFMetrics"/>
+  </appender>
+   
+  <appender name="EELFError"
+    class="ch.qos.logback.core.rolling.RollingFileAppender">
+    <file>${logDirectory}/${errorLogName}.log</file>
+    <rollingPolicy
+      class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
+      <fileNamePattern>${logDirectory}/${errorLogName}.%i.log.zip
+      </fileNamePattern>
+      <minIndex>1</minIndex>
+      <maxIndex>9</maxIndex>
+    </rollingPolicy>
+    <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
+     <level>ERROR</level>
+     </filter>
+    <triggeringPolicy
+      class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
+      <maxFileSize>5MB</maxFileSize>
+    </triggeringPolicy>
+    <encoder>
+      <pattern>${defaultPattern}</pattern>
+    </encoder>
+  </appender>
+  
+  <appender name="asyncEELFError" class="ch.qos.logback.classic.AsyncAppender">
+    <queueSize>256</queueSize>
+    <appender-ref ref="EELFError"/>
+  </appender>
+  
+   <appender name="EELFDebug"
+    class="ch.qos.logback.core.rolling.RollingFileAppender">
+    <file>${debugLogDirectory}/${debugLogName}.log</file>
+    <rollingPolicy
+      class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
+      <fileNamePattern>${debugLogDirectory}/${debugLogName}.%i.log.zip
+      </fileNamePattern>
+      <minIndex>1</minIndex>
+      <maxIndex>9</maxIndex>
+    </rollingPolicy>
+    <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
+     <level>INFO</level>
+     </filter>
+    <triggeringPolicy
+      class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
+      <maxFileSize>5MB</maxFileSize>
+    </triggeringPolicy>
+    <encoder>
+      <pattern>${defaultPattern}</pattern>
+    </encoder>
+  </appender>
+  
+  <appender name="asyncEELFDebug" class="ch.qos.logback.classic.AsyncAppender">
+    <queueSize>256</queueSize>
+    <appender-ref ref="EELFDebug" />
+    <includeCallerData>true</includeCallerData>
+  </appender>
+  
+  <!-- ============================================================================ -->
+  <!--  EELF loggers -->
+  <!-- ============================================================================ -->
+  <logger name="com.att.eelf.audit" level="info" additivity="false">
+    <appender-ref ref="asyncEELFAudit" />
+  </logger>
+  
+  <logger name="com.att.eelf.metrics" level="info" additivity="false">
+        <appender-ref ref="asyncEELFMetrics" />
+  </logger>
+    <logger name="com.att.eelf.error" level="error" additivity="false">
+  <appender-ref ref="asyncEELFError" />
+  </logger>
+  
+   <logger name="com.att.eelf.debug" level="info" additivity="false">
+        <appender-ref ref="asyncEELFDebug" />
+  </logger>
+  
+  
+  <!-- <root level="INFO"> -->
+  <root level="INFO">
+        <appender-ref ref="asyncEELFDebug" />
+        <appender-ref ref="asyncEELFError" />
+  </root>
+
+</configuration>
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
new file mode 100644 (file)
index 0000000..68a6cf2
--- /dev/null
@@ -0,0 +1,734 @@
+/*-
+ * ============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.test;
+
+import static org.junit.Assert.*;
+
+import java.util.Date;
+import java.util.List;
+import java.util.Properties;
+
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.EntityTransaction;
+import javax.persistence.Persistence;
+import javax.persistence.Query;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Ignore;
+import org.junit.Test;
+//import org.apache.commons.logging.Log;
+//import org.apache.commons.logging.LogFactory;
+
+
+
+import org.openecomp.policy.common.im.IntegrityMonitor;
+import org.openecomp.policy.common.im.IntegrityMonitorProperties;
+import org.openecomp.policy.common.im.StateManagement;
+import org.openecomp.policy.common.im.jpa.ForwardProgressEntity;
+import org.openecomp.policy.common.im.jpa.ImTestEntity;
+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;
+
+public class IntegrityMonitorTest {
+       private static Logger logger = FlexLogger.getLogger(IntegrityMonitorTest.class);
+       private static Properties myProp;
+       private static EntityManagerFactory emf;
+       private static EntityManager em;
+       private static EntityTransaction et;
+       private static String resourceName;
+       private static Properties systemProps;
+       
+       @BeforeClass
+       public static void setUpClass() throws Exception {
+
+       }
+
+       @AfterClass
+       public static void tearDownClass() throws Exception {
+       }
+
+       @Before
+       public void setUp() throws Exception {
+               IntegrityMonitor.isUnitTesting = true;
+               
+               myProp = new Properties();
+               myProp.put(IntegrityMonitorProperties.DB_DRIVER, IntegrityMonitorProperties.DEFAULT_DB_DRIVER);
+               myProp.put(IntegrityMonitorProperties.DB_URL, IntegrityMonitorProperties.DEFAULT_DB_URL);
+               myProp.put(IntegrityMonitorProperties.DB_USER, IntegrityMonitorProperties.DEFAULT_DB_USER);
+               myProp.put(IntegrityMonitorProperties.DB_PWD, IntegrityMonitorProperties.DEFAULT_DB_PWD);
+               myProp.put(IntegrityMonitorProperties.SITE_NAME, "SiteA");
+               myProp.put(IntegrityMonitorProperties.NODE_TYPE, "pap");
+               
+               // set JMX remote port in system properties
+               systemProps = System.getProperties();
+               systemProps.put("com.sun.management.jmxremote.port", "9797");
+               
+               resourceName = "siteA.pap1";
+               
+               //Create the data schema and entity manager factory
+               emf = Persistence.createEntityManagerFactory("schemaPU", myProp);
+
+               // Create an entity manager to use the DB
+               em = emf.createEntityManager();
+
+       }
+       
+
+       @After
+       public void tearDown() throws Exception {
+               // clear jmx remote port setting
+               systemProps.remove("com.sun.management.jmxremote.port");
+       }
+
+       /*
+        * The following test verifies the following test cases:
+        * New Install
+        * New Install - Bad Dependency data
+        * Recovery from bad dependency data
+        * Lock
+        * Lock restart
+        * Unlock
+        * Unlock restart
+        */
+       @Ignore // Test passed 10/18/16 
+       @Test
+       public void testSanityJmx() throws Exception {
+               System.out.println("\nIntegrityMonitorTest: Entering testSanityJmx\n\n");
+               
+               String dependent = "group1_logparser";
+               
+               // parameters are passed via a properties file
+               myProp.put(IntegrityMonitorProperties.DEPENDENCY_GROUPS, dependent);
+               myProp.put(IntegrityMonitorProperties.TEST_VIA_JMX, "true");
+               IntegrityMonitor.updateProperties(myProp);
+               
+               IntegrityMonitor im = IntegrityMonitor.getInstance(resourceName, myProp);
+               System.out.println("\n\ntestSanityJmx starting im state"
+                               + "\nAdminState = " + im.getStateManager().getAdminState()
+                               + "\nOpState() = " + im.getStateManager().getOpState()
+                               + "\nAvailStatus = " + im.getStateManager().getAvailStatus()
+                               + "\nStandbyStatus = " + im.getStateManager().getStandbyStatus()
+                               + "\n");
+               // add an entry to Resource registration table in the DB for the dependent resource
+               
+               
+               et = em.getTransaction();
+               et.begin();
+       Query rquery = em.createQuery("Select r from ResourceRegistrationEntity r where r.resourceName=:rn");
+       rquery.setParameter("rn", dependent);
+
+       @SuppressWarnings("rawtypes")
+       List rrList = rquery.getResultList();
+       ResourceRegistrationEntity rrx = null;
+       if(rrList.isEmpty()){
+               // register resource by adding entry to table in DB
+               System.out.println("Adding resource " + dependent + " to ResourceRegistration table");          
+               rrx = new ResourceRegistrationEntity();
+               // set columns in entry
+               rrx.setResourceName(dependent);
+               rrx.setResourceUrl("service:jmx:somewhere:9999");
+               rrx.setNodeType("logparser");
+               rrx.setSite("siteA");
+       }
+       em.persist(rrx);
+       // flush to the DB
+       em.flush();
+       
+       // commit transaction
+       et.commit();
+       
+       Thread.sleep(15000); //sleep 15 sec so the FPManager has time to call evaluateSanty()
+               
+               boolean sanityPass = true;
+               try {
+                       im.evaluateSanity();
+               } catch (Exception e) {
+                       System.out.println("evaluateSanity exception: " + e);
+                       sanityPass = false;
+               }
+               assertFalse(sanityPass);  // expect sanity test to fail
+
+               // undo dependency groups and jmx test properties settings
+               myProp.put(IntegrityMonitorProperties.DEPENDENCY_GROUPS, "");
+               myProp.put(IntegrityMonitorProperties.TEST_VIA_JMX, "false");
+               IntegrityMonitor.updateProperties(myProp);
+
+               System.out.println("\ntestSantityJmx ending properties: " + myProp);
+               
+               //We know at this point that the IM is disable-dependency.  We want to be
+               //sure it will recover from this condition since the properties were
+               //updated.
+               
+               
+               System.out.println("\n\ntestSanityJmx ending im state"
+                               + "\nAdminState = " + im.getStateManager().getAdminState()
+                               + "\nOpState() = " + im.getStateManager().getOpState()
+                               + "\nAvailStatus = " + im.getStateManager().getAvailStatus()
+                               + "\nStandbyStatus = " + im.getStateManager().getStandbyStatus()
+                               + "\n");
+               
+               //Destroy the instance
+               System.out.println("\ntestSanityJmx restarting the IntegrityMonitor");
+               IntegrityMonitor.deleteInstance();
+               //Create a new instance.  It should recover from the disabled-dependency condition
+               im = IntegrityMonitor.getInstance(resourceName, myProp);
+               
+               System.out.println("\n\ntestSanityJmx state after creating new im"
+                               + "\nAdminState = " + im.getStateManager().getAdminState()
+                               + "\nOpState() = " + im.getStateManager().getOpState()
+                               + "\nAvailStatus = " + im.getStateManager().getAvailStatus()
+                               + "\nStandbyStatus = " + im.getStateManager().getStandbyStatus()
+                               + "\n");
+
+               //Verify the state
+               assertEquals(im.getStateManager().getAdminState(), StateManagement.UNLOCKED);
+               assertEquals(im.getStateManager().getOpState(), StateManagement.ENABLED);
+               assertEquals(im.getStateManager().getAvailStatus(), StateManagement.NULL_VALUE);
+               assertEquals(im.getStateManager().getStandbyStatus(), StateManagement.NULL_VALUE);
+               
+               //Test state manager via the IntegrityMonitor
+               StateManagement sm = im.getStateManager();
+               
+               // Verify lock state
+               sm.lock();
+               System.out.println("\n\nsm.lock()"
+                       + "\nAdminState = " + sm.getAdminState()
+                       + "\nOpState() = " + sm.getOpState()
+                       + "\nAvailStatus = " + sm.getAvailStatus()
+                       + "\nStandbyStatus = " + sm.getStandbyStatus()
+                       + "\n");
+               assert(sm.getAdminState().equals(StateManagement.LOCKED));
+               
+               //Verify lock persists across a restart
+               //Destroy the instance
+               System.out.println("\ntestSanityJmx restarting the IntegrityMonitor");
+               IntegrityMonitor.deleteInstance();
+               //Create a new instance.  It should come up with the admin state locked
+               im = IntegrityMonitor.getInstance(resourceName, myProp);
+               sm = im.getStateManager();
+               System.out.println("\n\ntestSanityJmx restart with AdminState=locked"
+                               + "\nAdminState = " + sm.getAdminState()
+                               + "\nOpState() = " + sm.getOpState()
+                               + "\nAvailStatus = " + sm.getAvailStatus()
+                               + "\nStandbyStatus = " + sm.getStandbyStatus()
+                               + "\n");
+               assert(sm.getAdminState().equals(StateManagement.LOCKED));
+               
+               // Verify unlock
+               sm.unlock();
+               System.out.println("\n\ntestSanityJmx sm.unlock"
+                               + "\nAdminState = " + sm.getAdminState()
+                               + "\nOpState() = " + sm.getOpState()
+                               + "\nAvailStatus = " + sm.getAvailStatus()
+                               + "\nStandbyStatus = " + sm.getStandbyStatus()
+                               + "\n");
+               assert(sm.getAdminState().equals(StateManagement.UNLOCKED));            
+               
+               // Verify unlock restart
+               //Destroy the instance
+               System.out.println("\ntestSanityJmx restarting the IntegrityMonitor");
+               IntegrityMonitor.deleteInstance();
+               //Create a new instance.  It should come up with the admin state locked
+               im = IntegrityMonitor.getInstance(resourceName, myProp);
+               sm = im.getStateManager();
+               System.out.println("\n\ntestSanityJmx restart with AdminState=unlocked"
+                               + "\nAdminState = " + sm.getAdminState()
+                               + "\nOpState() = " + sm.getOpState()
+                               + "\nAvailStatus = " + sm.getAvailStatus()
+                               + "\nStandbyStatus = " + sm.getStandbyStatus()
+                               + "\n");
+               assert(sm.getAdminState().equals(StateManagement.UNLOCKED));
+               
+               System.out.println("\n\ntestSanityJmx: Exit\n\n");
+       }
+       
+
+       @Ignore  // Test passed 10/18/16 
+       @Test
+       public void testIM() throws Exception {
+               System.out.println("\nIntegrityMonitorTest: Entering testIM\n\n");
+               
+               // parameters are passed via a properties file
+               
+               /*
+                * Create an IntegrityMonitor
+                * NOTE: This uses the database that was created above.  So, this MUST follow the creation
+                * of the DB
+                */
+               IntegrityMonitor im = IntegrityMonitor.getInstance(resourceName, myProp);
+               
+               System.out.println("\n\nim before sleep"
+                               + "\nAdminState = " + im.getStateManager().getAdminState()
+                               + "\nOpState() = " + im.getStateManager().getOpState()
+                               + "\nAvailStatus = " + im.getStateManager().getAvailStatus()
+                               + "\nStandbyStatus = " + im.getStateManager().getStandbyStatus()
+                               + "\n");
+               
+               // wait for test transactions to fire and increment fpc
+               Thread.sleep(20000);
+               
+               System.out.println("\n\nim after sleep"
+                               + "\nAdminState = " + im.getStateManager().getAdminState()
+                               + "\nOpState() = " + im.getStateManager().getOpState()
+                               + "\nAvailStatus = " + im.getStateManager().getAvailStatus()
+                               + "\nStandbyStatus = " + im.getStateManager().getStandbyStatus()
+                               + "\n");
+               
+               // test evaluate sanity
+               boolean sanityPass = true;
+               try {
+                       im.evaluateSanity();
+               } catch (Exception e) {
+                       System.out.println("evaluateSanity exception: " + e);
+                       sanityPass = false;
+               }
+               assertTrue(sanityPass);  // expect sanity test to pass
+               
+               //Test startTransaction - should works since it is unlocked
+               boolean transPass = true;
+               try{
+                       im.startTransaction();
+               } catch (Exception e){
+                       System.out.println("startTransaction exception: " + e);
+                       transPass = false;
+               }
+               assertTrue(transPass);
+               
+               //Test state manager via the IntegrityMonitor
+               StateManagement sm = im.getStateManager();
+               
+               sm.lock();
+               System.out.println("\n\nsm.lock()"
+                               + "\nAdminState = " + sm.getAdminState()
+                               + "\nOpState() = " + sm.getOpState()
+                               + "\nAvailStatus = " + sm.getAvailStatus()
+                               + "\nStandbyStatus = " + sm.getStandbyStatus()
+                               + "\n");
+               assert(sm.getAdminState().equals(StateManagement.LOCKED));
+               
+               //test startTransaction.  It should fail since it is locked
+               transPass = true;
+               try{
+                       im.startTransaction();
+               } catch (Exception e){
+                       System.out.println("startTransaction exception: " + e);
+                       transPass = false;
+               }
+               assertTrue(!transPass); //expect it to fail
+               
+               sm.unlock();
+               System.out.println("\n\nsm.unlock()"
+                               + "\nAdminState = " + sm.getAdminState()
+                               + "\nOpState() = " + sm.getOpState()
+                               + "\nAvailStatus = " + sm.getAvailStatus()
+                               + "\nStandbyStatus = " + sm.getStandbyStatus()
+                               + "\n");
+               assert(sm.getAdminState().equals(StateManagement.UNLOCKED));
+               
+               //test startTransaction.  It should succeed
+               transPass = true;
+               try{
+                       im.startTransaction();
+               } catch (Exception e){
+                       System.out.println("startTransaction exception: " + e);
+                       transPass = false;
+               }
+               assertTrue(transPass); //expect it to succeed
+               
+               sm.disableDependency();
+               System.out.println("\n\nsm.disableDependency()"
+                               + "\nAdminState = " + sm.getAdminState()
+                               + "\nOpState() = " + sm.getOpState()
+                               + "\nAvailStatus = " + sm.getAvailStatus()
+                               + "\nStandbyStatus = " + sm.getStandbyStatus()
+                               + "\n");
+               assert(sm.getOpState().equals(StateManagement.DISABLED));
+               assert(sm.getAvailStatus().equals(StateManagement.DEPENDENCY));
+               
+               //test startTransaction.  It should succeed since standby status is null and unlocked
+               transPass = true;
+               try{
+                       im.startTransaction();
+               } catch (Exception e){
+                       System.out.println("startTransaction exception: " + e);
+                       transPass = false;
+               }
+               assertTrue(transPass); //expect it to succeed
+       
+               sm.enableNoDependency();
+               System.out.println("\n\nsm.enableNoDependency()"
+                               + "\nAdminState = " + sm.getAdminState()
+                               + "\nOpState() = " + sm.getOpState()
+                               + "\nAvailStatus = " + sm.getAvailStatus()
+                               + "\nStandbyStatus = " + sm.getStandbyStatus()
+                               + "\n");
+               assert(sm.getOpState().equals(StateManagement.ENABLED));
+               //test startTransaction.  It should succeed since standby status is null and unlocked
+               transPass = true;
+               try{
+                       im.startTransaction();
+               } catch (Exception e){
+                       System.out.println("startTransaction exception: " + e);
+                       transPass = false;
+               }
+               assertTrue(transPass); //expect it to succeed
+       
+               
+               sm.disableFailed();
+               System.out.println("\n\nsm.disableFailed()"
+                               + "\nAdminState = " + sm.getAdminState()
+                               + "\nOpState() = " + sm.getOpState()
+                               + "\nAvailStatus = " + sm.getAvailStatus()
+                               + "\nStandbyStatus = " + sm.getStandbyStatus()
+                               + "\n");
+               assert(sm.getOpState().equals(StateManagement.DISABLED));
+               assert(sm.getAvailStatus().equals(StateManagement.FAILED));
+               //test startTransaction.  It should succeed since standby status is null and unlocked
+               transPass = true;
+               try{
+                       im.startTransaction();
+               } catch (Exception e){
+                       System.out.println("startTransaction exception: " + e);
+                       transPass = false;
+               }
+               assertTrue(transPass); //expect it to succeed
+       
+               sm.enableNotFailed();
+               System.out.println("\n\nsm.enabledNotFailed()"
+                                                       + "\nAdminState = " + sm.getAdminState()
+                                                       + "\nOpState() = " + sm.getOpState()
+                                                       + "\nAvailStatus = " + sm.getAvailStatus()
+                                                       + "\nStandbyStatus = " + sm.getStandbyStatus()
+                                                       + "\n");
+               assert(sm.getOpState().equals(StateManagement.ENABLED));
+               //test startTransaction.  It should succeed since standby status is null and unlocked
+               transPass = true;
+               try{
+                       im.startTransaction();
+               } catch (Exception e){
+                       System.out.println("startTransaction exception: " + e);
+                       transPass = false;
+               }
+               assertTrue(transPass); //expect it to succeed
+       
+               sm.demote();
+               System.out.println("\n\nsm.demote()"
+                               + "\nAdminState = " + sm.getAdminState()
+                               + "\nOpState() = " + sm.getOpState()
+                               + "\nAvailStatus = " + sm.getAvailStatus()
+                               + "\nStandbyStatus = " + sm.getStandbyStatus()
+                               + "\n");
+               assert(sm.getStandbyStatus().equals(StateManagement.HOT_STANDBY));
+
+               //test startTransaction.  It should fail since it is standby
+               transPass = true;
+               try{
+                       im.startTransaction();
+               } catch (Exception e){
+                       System.out.println("startTransaction exception: " + e);
+                       transPass = false;
+               }
+               assertTrue(!transPass); //expect it to fail
+               
+               sm.promote();
+               System.out.println("\n\nsm.promote()"
+                               + "\nAdminState = " + sm.getAdminState()
+                               + "\nOpState() = " + sm.getOpState()
+                               + "\nAvailStatus = " + sm.getAvailStatus()
+                               + "\nStandbyStatus = " + sm.getStandbyStatus()
+                               + "\n");
+               assert(sm.getStandbyStatus().equals(StateManagement.PROVIDING_SERVICE));
+
+               //test startTransaction.  It should succeed since it is providing service
+               transPass = true;
+               try{
+                       im.startTransaction();
+               } catch (Exception e){
+                       System.out.println("startTransaction exception: " + e);
+                       transPass = false;
+               }
+               assertTrue(transPass); //expect it to succeed
+               
+               
+               //Test the multi-valued availability status
+               sm.disableDependency();
+               sm.disableFailed();
+               System.out.println("\n\nsm.disableDependency(), sm.disableFailed"
+                               + "\nAdminState = " + sm.getAdminState()
+                               + "\nOpState() = " + sm.getOpState()
+                               + "\nAvailStatus = " + sm.getAvailStatus()
+                               + "\nStandbyStatus = " + sm.getStandbyStatus()
+                               + "\n");
+               assert(sm.getAvailStatus().equals(StateManagement.DEPENDENCY_FAILED));
+               
+               //Test startTransaction.  Should fail since standby status is cold standby
+               transPass = true;
+               try{
+                       im.startTransaction();
+               } catch (Exception e){
+                       System.out.println("startTransaction exception: " + e);
+                       transPass = false;
+               }
+               assertTrue(!transPass); //expect it to fail
+               
+               sm.enableNoDependency();
+               System.out.println("\n\nsm.enableNoDependency()"
+                               + "\nAdminState = " + sm.getAdminState()
+                               + "\nOpState() = " + sm.getOpState()
+                               + "\nAvailStatus = " + sm.getAvailStatus()
+                               + "\nStandbyStatus = " + sm.getStandbyStatus()
+                               + "\n");
+               assert(sm.getAvailStatus().equals(StateManagement.FAILED));
+               //Test startTransaction.  Should fail since standby status is cold standby
+               transPass = true;
+               try{
+                       im.startTransaction();
+               } catch (Exception e){
+                       System.out.println("startTransaction exception: " + e);
+                       transPass = false;
+               }
+               assertTrue(!transPass); //expect it to fail
+       
+               sm.disableDependency();
+               sm.enableNotFailed();
+               System.out.println("\n\nsm.disableDependency(),sm.enableNotFailed()"
+                               + "\nAdminState = " + sm.getAdminState()
+                               + "\nOpState() = " + sm.getOpState()
+                               + "\nAvailStatus = " + sm.getAvailStatus()
+                               + "\nStandbyStatus = " + sm.getStandbyStatus()
+                               + "\n");
+               assert(sm.getAvailStatus().equals(StateManagement.DEPENDENCY));
+               //Test startTransaction.  Should fail since standby status is cold standby
+               transPass = true;
+               try{
+                       im.startTransaction();
+               } catch (Exception e){
+                       System.out.println("startTransaction exception: " + e);
+                       transPass = false;
+               }
+               assertTrue(!transPass); //expect it to fail
+       
+               sm.enableNoDependency();
+               System.out.println("\n\nsm.enableNoDependency()"
+                               + "\nAdminState = " + sm.getAdminState()
+                               + "\nOpState() = " + sm.getOpState()
+                               + "\nAvailStatus = " + sm.getAvailStatus()
+                               + "\nStandbyStatus = " + sm.getStandbyStatus()
+                               + "\n");
+               assert(sm.getOpState().equals(StateManagement.ENABLED));
+               //test startTransaction.  It should fail since standby status is hot standby
+               transPass = true;
+               try{
+                       im.startTransaction();
+               } catch (Exception e){
+                       System.out.println("startTransaction exception: " + e);
+                       transPass = false;
+               }
+               assertTrue(!transPass); //expect it to fail
+       
+               System.out.println("\n\ntestIM: Exit\n\n");
+       }
+       
+
+       @Ignore  // Test passed 10/18/16 
+       @Test
+       public void testSanityState() throws Exception {
+               System.out.println("\nIntegrityMonitorTest: Entering testSanityState\n\n");
+               
+               // parameters are passed via a properties file
+               myProp.put(IntegrityMonitorProperties.DEPENDENCY_GROUPS, "group1_dep1,group1_dep2; group2_dep1");
+               IntegrityMonitor.updateProperties(myProp);
+               
+               IntegrityMonitor im = IntegrityMonitor.getInstance(resourceName, myProp);
+               
+               // Add a group1 dependent resources to put an entry in the forward progress table
+               ForwardProgressEntity fpe = new ForwardProgressEntity();
+               ForwardProgressEntity fpe2 = new ForwardProgressEntity();
+               fpe.setFpcCount(0);
+               fpe.setResourceName("group1_dep1");
+               fpe2.setFpcCount(0);
+               fpe2.setResourceName("group1_dep2");
+               et = em.getTransaction();
+               et.begin();
+               em.persist(fpe);
+               em.persist(fpe2);
+               em.flush();
+               et.commit();
+
+               
+               // Add a group2 dependent resource to the StateManagementEntity DB table and set its admin state to locked
+               // Expect sanity test to fail.
+               StateManagement stateManager = new StateManagement(emf, "group2_dep1");
+               stateManager.lock();
+               
+               //Now add new group1 stateManager instances
+               StateManagement sm2 = new StateManagement(emf, "group1_dep1");
+               StateManagement sm3 = new StateManagement(emf, "group1_dep2");
+               
+               boolean sanityPass = true;
+               Thread.sleep(15000);
+               try {
+                       im.evaluateSanity();
+               } catch (Exception e) {
+                       System.out.println("evaluateSanity exception: " + e);
+                       sanityPass = false;
+               }
+               assertFalse(sanityPass);  // expect sanity test to fail
+               
+               // undo dependency groups and jmx test properties settings
+               myProp.put(IntegrityMonitorProperties.DEPENDENCY_GROUPS, "");
+               myProp.put(IntegrityMonitorProperties.TEST_VIA_JMX, "false");
+               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\ntestSanityState: Exit\n\n");
+       }
+       
+       @Ignore  // Test passed 10/18/16 
+       @Test
+       public void testRefreshStateAudit() throws Exception {
+               logger.debug("\nIntegrityMonitorTest: testRefreshStateAudit Enter\n\n");
+
+               // parameters are passed via a properties file
+               myProp.put(IntegrityMonitorProperties.DEPENDENCY_GROUPS, "");
+               myProp.put(IntegrityMonitorProperties.TEST_VIA_JMX, "false");
+               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();
+
+               IntegrityMonitor.deleteInstance();
+
+               IntegrityMonitor im = IntegrityMonitor.getInstance(resourceName, myProp);
+
+               //the state here is unlocked, enabled, null, null
+               StateManagementEntity sme = null;
+
+               Query query = em.createQuery("Select p from StateManagementEntity p where p.resourceName=:resource");
+
+               query.setParameter("resource", resourceName);
+
+               //Just test that we are retrieving the right object
+               @SuppressWarnings("rawtypes")
+               List resourceList = query.getResultList();
+               if (!resourceList.isEmpty()) {
+                       // exist 
+                       sme = (StateManagementEntity) resourceList.get(0);
+                       em.refresh(sme);
+
+                       logger.debug("??? -- Retrieve StateManagementEntity from database --"
+                                       + "\nsme.getResourceName() = " + sme.getResourceName() 
+                                       + "\nsme.getAdminState() = " + sme.getAdminState()
+                                       + "\nsme.getOpState() = " + sme.getOpState()
+                                       + "\nsme.getAvailStatus() = " + sme.getAvailStatus()
+                                       + "\nsme.getStandbyStatus() = " + sme.getStandbyStatus());
+
+                       assertTrue(sme.getAdminState().equals(StateManagement.UNLOCKED)); 
+                       assertTrue(sme.getOpState().equals(StateManagement.ENABLED)); 
+                       assertTrue(sme.getAvailStatus().equals(StateManagement.NULL_VALUE)); 
+                       assertTrue(sme.getStandbyStatus().equals(StateManagement.NULL_VALUE));
+                       logger.debug("--");
+               } else {
+                       logger.debug("Record not found, resourceName: " + resourceName);
+                       assertTrue(false);
+               }
+
+               et = em.getTransaction();
+               et.begin();
+
+               sme.setStandbyStatus(StateManagement.COLD_STANDBY);
+               em.persist(sme);
+               em.flush();
+               et.commit();
+
+               Thread.sleep(65000);
+
+               //The refreshStateAudit should run and change the state to unlocked,enabled,null,hotstandby
+               StateManagementEntity sme1 = null;
+
+               Query query1 = em.createQuery("Select p from StateManagementEntity p where p.resourceName=:resource");
+
+               query1.setParameter("resource", resourceName);
+
+               //Just test that we are retrieving the right object
+               @SuppressWarnings("rawtypes")
+               List resourceList1 = query1.getResultList();
+               if (!resourceList1.isEmpty()) {
+                       // exist 
+                       sme1 = (StateManagementEntity) resourceList1.get(0);
+                       em.refresh(sme1);
+                       logger.debug("??? -- Retrieve StateManagementEntity from database --"
+                                       + "\nsme1.getResourceName() = " + sme1.getResourceName() 
+                                       + "\nsme1.getAdminState() = " + sme1.getAdminState()
+                                       + "\nsme1.getOpState() = " + sme1.getOpState()
+                                       + "\nsme1.getAvailStatus() = " + sme1.getAvailStatus()
+                                       + "\nsme1.getStandbyStatus() = " + sme1.getStandbyStatus());
+
+                       assertTrue(sme1.getAdminState().equals(StateManagement.UNLOCKED)); 
+                       assertTrue(sme1.getOpState().equals(StateManagement.ENABLED)); 
+                       assertTrue(sme1.getAvailStatus().equals(StateManagement.NULL_VALUE)); 
+                       assertTrue(sme1.getStandbyStatus().equals(StateManagement.HOT_STANDBY)); 
+                       logger.debug("--");
+               } else {
+                       logger.debug("Record not found, resourceName: " + resourceName);
+                       assertTrue(false);
+               }
+
+               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();
+
+               IntegrityMonitor.deleteInstance();
+
+               logger.debug("\nIntegrityMonitorTest: testRefreshStateAudit Exit\n\n");
+       }
+}
diff --git a/integrity-monitor/src/test/java/org/openecomp/policy/common/im/test/StateManagementEntityTest.java b/integrity-monitor/src/test/java/org/openecomp/policy/common/im/test/StateManagementEntityTest.java
new file mode 100644 (file)
index 0000000..9fb6ddf
--- /dev/null
@@ -0,0 +1,195 @@
+/*-
+ * ============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.test;
+
+import static org.junit.Assert.*;
+
+import java.util.Date;
+import java.util.List;
+import java.util.Properties;
+
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.EntityTransaction;
+import javax.persistence.Persistence;
+import javax.persistence.Query;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+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.jpa.StateManagementEntity;
+import org.openecomp.policy.common.logging.flexlogger.FlexLogger; 
+import org.openecomp.policy.common.logging.flexlogger.Logger;
+
+public class StateManagementEntityTest {
+       private static Logger logger = FlexLogger.getLogger(StateManagementEntityTest.class);
+       
+       private static final String DEFAULT_DB_DRIVER = "org.h2.Driver";
+       private static final String DEFAULT_DB_URL = "jdbc:h2:file:./sql/smTest";
+       //private static final String DEFAULT_DB_URL = "jdbc:h2:file:./sql/xacml";
+       private static final String DEFAULT_DB_USER = "sa";
+       private static final String DEFAULT_DB_PWD = "";
+
+       /*
+       private static final String DEFAULT_DB_DRIVER = "org.mariadb.jdbc.Driver";
+       private static final String DEFAULT_DB_URL    = "jdbc:mariadb://localhost:3306/xacml";
+       private static final String DEFAULT_DB_USER   = "policy_user";
+       private static final String DEFAULT_DB_PWD    = "policy_user";
+       */
+
+       private static final String DB_DRIVER         = "javax.persistence.jdbc.driver";
+       private static final String DB_URL            = "javax.persistence.jdbc.url";
+       private static final String DB_USER           = "javax.persistence.jdbc.user";
+       private static final String DB_PWD            = "javax.persistence.jdbc.password";
+         
+       @BeforeClass
+       public static void setUpClass() throws Exception {
+
+       }
+
+       @AfterClass
+       public static void tearDownClass() throws Exception {
+       }
+
+       @Before
+       public void setUp() throws Exception {
+       }
+
+       @After
+       public void tearDown() throws Exception {
+       }
+
+       @Test
+       public void testJPA() throws Exception {
+               System.out.println("\n??? logger.infor StateManagementEntityTest: Entering\n\n");
+               
+               Properties myProp = new Properties();
+               myProp.put(DB_DRIVER, DEFAULT_DB_DRIVER);
+               myProp.put(DB_URL,    DEFAULT_DB_URL);
+               myProp.put(DB_USER,   DEFAULT_DB_USER);
+               myProp.put(DB_PWD,    DEFAULT_DB_PWD);
+               
+               System.out.println("??? " + DB_DRIVER + "=" + DEFAULT_DB_DRIVER); 
+               System.out.println("??? " + DB_URL    + "=" + DEFAULT_DB_URL); 
+               System.out.println("??? " + DB_USER   + "=" + DEFAULT_DB_USER); 
+               System.out.println("??? " + DB_PWD    + "=" + DEFAULT_DB_PWD); 
+               
+               //Create the data schema and entity manager factory
+               System.out.println("??? createEntityManagerFactory for schemaPU"); 
+               EntityManagerFactory emf = Persistence.createEntityManagerFactory("schemaPU", myProp);
+
+               // Create an entity manager to use the DB
+               System.out.println("??? createEntityManager");
+               EntityManager em = emf.createEntityManager();
+               System.out.println("??? getTransaction");
+               EntityTransaction et = em.getTransaction();
+               et.begin();
+               // Make sure the DB is clean
+               System.out.println("??? clean StateManagementEntity");
+               em.createQuery("DELETE FROM StateManagementEntity").executeUpdate();
+
+               //Define the resourceName for the StateManagement constructor
+               String resourceName = "test_resource1";
+               
+               //
+               System.out.println("Create StateManagementEntity, resourceName: " + resourceName);
+               System.out.println("??? instantiate StateManagementEntity object");
+               StateManagementEntity sme = new StateManagementEntity(); 
+               
+               System.out.println("??? setResourceName : " + resourceName);
+               sme.setResourceName(resourceName);
+               System.out.println("??? getResourceName : " + sme.getResourceName());
+
+               System.out.println("??? setAdminState   : " + StateManagement.UNLOCKED);
+               sme.setAdminState(StateManagement.UNLOCKED); 
+               System.out.println("??? getAdminState   : " + sme.getAdminState());
+               
+               System.out.println("??? setOpState      : " + StateManagement.ENABLED);
+               sme.setOpState(StateManagement.ENABLED);
+               System.out.println("??? getOpState      : " + sme.getOpState());
+               
+               System.out.println("??? setAvailStatus   : " + StateManagement.NULL_VALUE);
+               sme.setAvailStatus(StateManagement.NULL_VALUE);
+               System.out.println("??? getAvailStatus   : " + sme.getAvailStatus());
+               
+               System.out.println("??? setStandbyStatus: " + StateManagement.COLD_STANDBY);
+               sme.setStandbyStatus(StateManagement.COLD_STANDBY);
+               System.out.println("??? getStandbyStatus: " + sme.getStandbyStatus());
+               
+               System.out.println("??? before persist");
+               em.persist(sme); 
+               System.out.println("??? after  persist");
+               
+               em.flush(); 
+               System.out.println("??? after flush");
+
+               et.commit(); 
+               System.out.println("??? after commit");
+               
+               try {
+               Query query = em.createQuery("Select p from StateManagementEntity p where p.resourceName=:resource");
+              
+               query.setParameter("resource", resourceName);
+              
+               //Just test that we are retrieving the right object
+               @SuppressWarnings("rawtypes")
+               List resourceList = query.getResultList();
+               String resource = null; 
+               if (!resourceList.isEmpty()) {
+                  // exist 
+                  StateManagementEntity sme2 = (StateManagementEntity) resourceList.get(0);
+                  System.out.println("??? -- Retrieve StateManagementEntity from database --"
+                               + "\n\nsme.getResourceName() = " + sme.getResourceName() 
+                               + "\nsme2getResourceName() = " + sme2.getResourceName() 
+                               + "\n\nsme.getAdminState() = " + sme.getAdminState()
+                               + "\nsme2.getAdminState() = " + sme2.getAdminState()
+                               + "\n\nsme.getOpState() = " + sme.getOpState()
+                               + "\nsme2.getOpState() = " + sme2.getOpState()
+                               + "\n\nsme.getAvailStatus() = " + sme.getAvailStatus()
+                               + "\nsme2.getAvailStatus() = " + sme.getAvailStatus()
+                               + "\n\nsme.getStandbyStatus() = " + sme.getStandbyStatus()
+                               + "\nsme2.getStandbyStatus() = " + sme2.getStandbyStatus());
+                               
+                  
+                  assert(sme2.getResourceName().equals(sme.getResourceName())); 
+                  assert(sme2.getAdminState().equals(sme.getAdminState())); 
+                  assert(sme2.getOpState().equals(sme.getOpState())); 
+                  assert(sme2.getAvailStatus().equals(sme.getAvailStatus())); 
+                  assert(sme2.getStandbyStatus().equals(sme.getStandbyStatus())); 
+                          System.out.println("--");
+               } else {
+                  System.out.println("Record not found, resourceName: " + resourceName);
+               }
+                 } catch(Exception ex) {
+                       logger.error("Exception on select query: " + ex.toString());
+           }
+               
+               em.close(); 
+               System.out.println("\n??? after close");
+               System.out.println("\n\nJpaTest: 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
new file mode 100644 (file)
index 0000000..8b6dbf5
--- /dev/null
@@ -0,0 +1,336 @@
+/*-
+ * ============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.test;
+
+import static org.junit.Assert.*;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Properties;
+import java.util.StringTokenizer;
+import java.io.BufferedReader;
+import java.io.FileReader;
+import java.io.IOException;
+
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.Persistence;
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.LockModeType;
+import javax.persistence.PersistenceException;
+import javax.persistence.Query;
+
+
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+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; 
+import org.openecomp.policy.common.im.StateChangeNotifier; 
+import org.openecomp.policy.common.logging.flexlogger.FlexLogger; 
+import org.openecomp.policy.common.logging.flexlogger.Logger;
+
+public class StateManagementTest {
+       private static Logger logger = FlexLogger.getLogger(StateManagementTest.class);
+       
+       private static final String DEFAULT_DB_DRIVER = "org.h2.Driver";
+       private static final String DEFAULT_DB_URL    = "jdbc:h2:file:./sql/smTest";
+       private static final String DEFAULT_DB_USER   = "sa";
+       private static final String DEFAULT_DB_PWD    = "";
+
+       private static final String DB_DRIVER         = "javax.persistence.jdbc.driver";
+       private static final String DB_URL            = "javax.persistence.jdbc.url";
+       private static final String DB_USER           = "javax.persistence.jdbc.user";
+       private static final String DB_PWD            = "javax.persistence.jdbc.password";
+       // 
+         
+       @BeforeClass
+       public static void setUpClass() throws Exception {
+
+       }
+
+       @AfterClass
+       public static void tearDownClass() throws Exception {
+       }
+
+       @Before
+       public void setUp() throws Exception {
+       }
+
+       @After
+       public void tearDown() throws Exception {
+       }
+
+       @Test
+       public void testJPA() throws Exception {
+               logger.info("\n\nlogger.infor StateManagementTest: Entering\n\n");
+               String resourceName = "test_resource1"; 
+               boolean standbyExceptionThrown = false; 
+               
+               //These parameters are in a properties file
+               EntityManagerFactory emf = null; 
+               try {
+                   Properties myProp = new Properties();
+                   myProp.put(DB_DRIVER, DEFAULT_DB_DRIVER);
+                   myProp.put(DB_URL,    DEFAULT_DB_URL);
+                   myProp.put(DB_USER,   DEFAULT_DB_USER);
+                   myProp.put(DB_PWD,    DEFAULT_DB_PWD);
+               
+                   //Create the data schema and entity manager factory
+                   emf = Persistence.createEntityManagerFactory("schemaPU", myProp);
+
+                   StateManagement sm = new StateManagement(emf, resourceName);
+                   System.out.println("\n\ntest lock()");
+                   displayState(resourceName, sm);
+                   logger.info("\n??? test lock()");
+                   logger.info(resourceName + " before adminState   = " + sm.getAdminState()); 
+                   logger.info(resourceName + " before opState      = " + sm.getOpState()); 
+                       logger.info(resourceName + " before availStatus  = " + sm.getAvailStatus()); 
+                       logger.info(resourceName + " before standbyStatus= " + sm.getStandbyStatus()); 
+                   sm.lock(); 
+                   System.out.println("\n\nafter lock()");
+                   displayState(resourceName, sm);                 
+                   logger.info(resourceName + " after  adminState   = " + sm.getAdminState()); 
+                   logger.info(resourceName + " after  opState      = " + sm.getOpState()); 
+                       logger.info(resourceName + " after  availStatus  = " + sm.getAvailStatus()); 
+                       logger.info(resourceName + " after  standbyStatus= " + sm.getStandbyStatus()); 
+                        
+                   logger.info("\n??? test unlock()");
+                   sm.unlock(); 
+                   System.out.println("\n\nafter unlock()");
+                   displayState(resourceName, sm);             
+                   logger.info(resourceName + " adminState   = " + sm.getAdminState()); 
+                   logger.info(resourceName + " opState      = " + sm.getOpState()); 
+                       logger.info(resourceName + " availStatus  = " + sm.getAvailStatus()); 
+                       logger.info(resourceName + " standbyStatus= " + sm.getStandbyStatus()); 
+                       
+                   logger.info("\n??? test enableNotFailed()");
+                   sm.enableNotFailed(); 
+                   System.out.println("\n\nafter enableNotFailed()");
+                   displayState(resourceName, sm);             
+                   logger.info(resourceName + " adminState   = " + sm.getAdminState()); 
+                   logger.info(resourceName + " opState      = " + sm.getOpState()); 
+                       logger.info(resourceName + " availStatus  = " + sm.getAvailStatus()); 
+                       logger.info(resourceName + " standbyStatus= " + sm.getStandbyStatus()); 
+                   
+                   logger.info("\n??? test disableFailed()");
+                   sm.disableFailed();
+                   System.out.println("\n\nafter disableFailed()");
+                   displayState(resourceName, sm);             
+                   logger.info(resourceName + " adminState   = " + sm.getAdminState()); 
+                   logger.info(resourceName + " opState      = " + sm.getOpState()); 
+                       logger.info(resourceName + " availStatus  = " + sm.getAvailStatus()); 
+                       logger.info(resourceName + " standbyStatus= " + sm.getStandbyStatus()); 
+                       
+                   // P4 If promote() is called while either the opState is disabled or the adminState is locked,  
+                   // the standbystatus shall transition to coldstandby and a StandbyStatusException shall be thrown
+                   logger.info("\n??? promote() test case P4");
+                       try {
+                       sm.disableFailed(); 
+                       sm.lock();
+                           System.out.println("\n\nafter lock() and disableFailed");
+                           displayState(resourceName, sm);             
+                           logger.info(resourceName + " adminState   = " + sm.getAdminState()); 
+                           logger.info(resourceName + " opState      = " + sm.getOpState()); 
+                               logger.info(resourceName + " standbyStatus= " + sm.getStandbyStatus());
+                               sm.promote(); 
+                           System.out.println("\n\nafter promote");
+                           displayState(resourceName, sm);             
+                   } catch(StandbyStatusException ex) {
+                       standbyExceptionThrown = true; 
+                       logger.info("StandbyStatusException thrown and catched");
+                   } catch(Exception ex) {
+                       logger.info("??? Exception: " + ex.toString());
+                   }
+                       assert(standbyExceptionThrown); 
+               assert(sm.getStandbyStatus().equals(StateManagement.COLD_STANDBY)); 
+               standbyExceptionThrown = false; 
+                   
+                       // P3 If promote() is called while standbyStatus is coldstandby, the state shall not transition 
+                   //    and a StandbyStatusException shall be thrown
+                   logger.info("\n??? promote() test case P3");
+                   try {
+                               logger.info(resourceName + " standbyStatus= " + sm.getStandbyStatus());                         
+                       sm.promote(); 
+                   } catch(StandbyStatusException ex) {
+                       standbyExceptionThrown = true; 
+                       logger.info("StandbyStatusException thrown and catched");
+                   } catch(Exception ex) {
+                       logger.info("??? Exception: " + ex.toString());
+                   }   
+                       assert(standbyExceptionThrown); 
+               assert(sm.getStandbyStatus().equals(StateManagement.COLD_STANDBY)); 
+                   System.out.println("\n\nP3 after promote()");
+                   displayState(resourceName, sm);     
+               standbyExceptionThrown = false;                     
+                   
+                   // P2 If promote() is called while the standbyStatus is null and the opState is enabled and adminState is unlocked, 
+                   //    the state shall transition to providingservice
+                   logger.info("\n??? promote() test case P2");
+                   resourceName = "test_resource2"; 
+                   StateManagement sm2 = new StateManagement(emf, resourceName);
+                   sm2.enableNotFailed();
+                   sm2.unlock(); 
+                   System.out.println("\n\nafter sm2.enableNotFailed() and sm2.unlock()");
+                   displayState(resourceName, sm2);    
+                   logger.info(resourceName + " adminState   = " + sm2.getAdminState()); 
+                   logger.info(resourceName + " opState      = " + sm2.getOpState()); 
+                       logger.info(resourceName + " standbyStatus= " + sm2.getStandbyStatus());                    
+                   sm2.promote(); 
+                   System.out.println("\n\nP2 after sm2.promote");
+                   displayState(resourceName, sm2);    
+                   assert(sm2.getAdminState().equals(StateManagement.UNLOCKED)); 
+                   assert(sm2.getOpState().equals(StateManagement.ENABLED)); 
+                   assert(sm2.getStandbyStatus().equals(StateManagement.PROVIDING_SERVICE));
+                   
+                   // P5 If promote() is called while standbyStatus is providingservice, no action is taken
+                   logger.info("\n??? promote() test case P5");
+                       logger.info(resourceName + " standbyStatus= " + sm2.getStandbyStatus()); 
+                   sm2.promote();  
+                   System.out.println("\n\nP5 after sm2.promote()");
+                   displayState(resourceName, sm2);    
+                   assert(sm2.getStandbyStatus().equals(StateManagement.PROVIDING_SERVICE));
+                   
+                   // D1 If demote() is called while standbyStatus is providingservice, the state shall transition to hotstandby
+                   logger.info("\n??? demote() test case D1");
+                   logger.info(resourceName + " standbyStatus= " + sm2.getStandbyStatus()); 
+                   sm2.demote(); 
+                   System.out.println("\n\nD1 after sm2.demote()");
+                   displayState(resourceName, sm2);    
+                   assert(sm2.getStandbyStatus().equals(StateManagement.HOT_STANDBY));
+                   
+                   // D4 If demote() is called while standbyStatus is hotstandby, no action is taken
+                   logger.info("\n??? demote() test case D4");
+                   logger.info(resourceName + " standbyStatus= " + sm2.getStandbyStatus()); 
+                   sm2.demote(); 
+                   System.out.println("\n\nD4 after sm2.demote()");
+                   displayState(resourceName, sm2);    
+                   assert(sm2.getStandbyStatus().equals(StateManagement.HOT_STANDBY));
+                   
+                   // D3 If demote() is called while standbyStatus is null and adminState is locked or opState is disabled, 
+                   //    the state shall transition to coldstandby
+                   logger.info("\n??? demote() test case D3"); 
+                   resourceName = "test_resource3"; 
+                   StateManagement sm3 = new StateManagement(emf, resourceName);
+                   sm3.lock(); 
+                   sm3.disableFailed(); 
+                   System.out.println("\n\nD3 after sm3.lock() and sm3.disableFailed()");
+                   displayState(resourceName, sm3);    
+                   logger.info(resourceName + " adminState   = " + sm3.getAdminState()); 
+                   logger.info(resourceName + " opState      = " + sm3.getOpState()); 
+                       logger.info(resourceName + " standbyStatus= " + sm3.getStandbyStatus());                    
+                   sm3.demote(); 
+                   System.out.println("\n\nD3 after sm3.demote()");
+                   displayState(resourceName, sm3);    
+                   assert(sm3.getStandbyStatus().equals(StateManagement.COLD_STANDBY));
+                   
+                   // D5 If demote() is called while standbyStatus is coldstandby, no action is taken
+                   logger.info("\n??? demote() test case D5"); 
+                   logger.info(resourceName + " standbyStatus= " + sm3.getStandbyStatus()); 
+                   sm3.demote(); 
+                   System.out.println("\n\nD5 after sm3.demote()");
+                   displayState(resourceName, sm3);    
+                   assert(sm3.getStandbyStatus().equals(StateManagement.COLD_STANDBY));                    
+                   
+                   // D2 If demote() is called while standbyStatus is null and adminState is unlocked and opState is enabled, 
+                   //    the state shall transition to hotstandby
+                   logger.info("\n??? demote() test case D2");
+                   resourceName = "test_resource4"; 
+                   StateManagement sm4 = new StateManagement(emf, resourceName);
+                   sm4.unlock(); 
+                   sm4.enableNotFailed(); 
+                   System.out.println("\n\nD2 after sm4.unlock() and sm4.enableNotFailed()");
+                   displayState(resourceName, sm4);    
+                   logger.info(resourceName + " adminState   = " + sm4.getAdminState()); 
+                   logger.info(resourceName + " opState      = " + sm4.getOpState()); 
+                       logger.info(resourceName + " standbyStatus= " + sm4.getStandbyStatus()); 
+                   sm4.demote(); 
+                   assert(sm4.getStandbyStatus().equals(StateManagement.HOT_STANDBY));
+                   
+                   // P1 If promote() is called while standbyStatus is hotstandby, the state shall transition to providingservice.
+                   logger.info("\n??? promote() test case P1");
+                   logger.info(resourceName + " standbyStatus= " + sm4.getStandbyStatus()); 
+                   sm4.promote(); 
+                   System.out.println("\n\nP1 after sm4.promote()");
+                   displayState(resourceName, sm4);    
+                   assert(sm4.getStandbyStatus().equals(StateManagement.PROVIDING_SERVICE));
+                   
+                   // State change notification
+                   logger.info("\n??? State change notification test case 1 - lock()");
+                   StateChangeNotifier stateChangeNotifier = new StateChangeNotifier(); 
+                   sm.addObserver(stateChangeNotifier); 
+                   sm.lock(); 
+                   
+                   logger.info("\n??? State change notification test case 2 - unlock()");
+                   sm.unlock(); 
+                   
+                   logger.info("\n??? State change notification test case 3 - enabled()");
+                   sm.enableNotFailed(); 
+                   
+                   logger.info("\n??? State change notification test case 4 - disableFailed()");
+                   sm.disableFailed(); 
+
+                   logger.info("\n??? State change notification test case 5 - demote()");
+                   sm.demote(); 
+
+               logger.info("\n??? State change notification test case 6 - promote()");
+                   try {
+                     sm.promote(); 
+                   } catch(Exception ex) {
+                       logger.info("Exception from promote(): " + ex.toString());
+                   }
+                       if (emf.isOpen()) {
+                               emf.close(); 
+                       }
+               } catch(Exception ex) {
+                       logger.error("Exception: " + ex.toString());
+               } finally {
+                       if (emf.isOpen()) {
+                           emf.close(); 
+                       }
+               }
+
+           logger.info("\n\nStateManagementTest: Exit\n\n");
+       }
+       
+       private void displayState(String resourceName, StateManagement sm) 
+       {
+               System.out.println("\nAdminState = " + sm.getAdminState()
+                               + "\nOpState() = " + sm.getOpState()
+                               + "\nAvailStatus = " + sm.getAvailStatus()
+                               + "\nStandbyStatus = " + sm.getStandbyStatus()
+                               + "\n");
+           logger.info(resourceName + " adminState   = " + sm.getAdminState()); 
+           logger.info(resourceName + " opState      = " + sm.getOpState()); 
+               logger.info(resourceName + " availStatus  = " + sm.getAvailStatus()); 
+               logger.info(resourceName + " standbyStatus= " + sm.getStandbyStatus()); 
+       }
+}
+
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
new file mode 100644 (file)
index 0000000..a93a4ad
--- /dev/null
@@ -0,0 +1,2186 @@
+/*-
+ * ============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.test;
+
+import static org.junit.Assert.*;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Properties;
+import java.util.StringTokenizer;
+import java.io.BufferedReader;
+import java.io.FileReader;
+import java.io.IOException;
+
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.EntityTransaction;
+import javax.persistence.Persistence;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+//import org.apache.commons.logging.Log;
+//import org.apache.commons.logging.LogFactory;
+
+import org.openecomp.policy.common.im.StateTransition;
+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;
+
+public class StateTransitionTest {
+       private static Logger logger = FlexLogger.getLogger(StateTransitionTest.class);
+       
+       private static final String DEFAULT_DB_DRIVER = "org.h2.Driver";
+       private static final String DEFAULT_DB_URL    = "jdbc:h2:file:./sql/smTest";
+       private static final String DEFAULT_DB_USER   = "sa";
+       private static final String DEFAULT_DB_PWD    = "";
+
+       private static final String DB_DRIVER         = "javax.persistence.jdbc.driver";
+       private static final String DB_URL            = "javax.persistence.jdbc.url";
+       private static final String DB_USER           = "javax.persistence.jdbc.user";
+       private static final String DB_PWD            = "javax.persistence.jdbc.password";
+       // 
+         
+       @BeforeClass
+       public static void setUpClass() throws Exception {
+
+       }
+
+       @AfterClass
+       public static void tearDownClass() throws Exception {
+       }
+
+       @Before
+       public void setUp() throws Exception {
+       }
+
+       @After
+       public void tearDown() throws Exception {
+       }
+
+       @Test
+       public void testJPA() throws Exception {
+               logger.info("\n\nlogger.infor StateTransitionTest: Entering\n\n");
+               boolean standbyExceptionThrown = false; 
+               
+               //These parameters are in a properties file
+               EntityManagerFactory emf = null; 
+               try {
+                   Properties myProp = new Properties();
+                   myProp.put(DB_DRIVER, DEFAULT_DB_DRIVER);
+                   myProp.put(DB_URL,    DEFAULT_DB_URL);
+                   myProp.put(DB_USER,   DEFAULT_DB_USER);
+                   myProp.put(DB_PWD,    DEFAULT_DB_PWD);
+               
+                   logger.info("??? create a new StateTransition"); 
+                   StateTransition st = new StateTransition();
+                   StateElement se = null; 
+                   try {
+                       // bad test case 
+                       se = st.getEndingState("unlocked", "enabled", "null",  "coldstandby", "lock");
+                       //
+                       logger.info("??? StateTransition testcase 1");
+                       se = st.getEndingState("unlocked", "enabled", "null",  "null", "lock");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 2");
+                       se = st.getEndingState("unlocked", "enabled", "null",  "null", "unlock");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 3");
+                       se = st.getEndingState("unlocked", "enabled", "null",  "null", "disableFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 4");
+                       se = st.getEndingState("unlocked", "enabled", "null",  "null", "enableNotFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 5");
+                       se = st.getEndingState("unlocked", "enabled", "null",  "null", "disableDependency");
+                       if (se != null) displayEndingState(se);
+                
+                       logger.info("??? StateTransition testcase 6");
+                       se = st.getEndingState("unlocked", "enabled", "null",  "null", "enableNoDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 7");
+                       se = st.getEndingState("unlocked", "enabled", "null",  "null", "promote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 8");
+                       se = st.getEndingState("unlocked", "enabled", "null",  "null", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 9");
+                       se = st.getEndingState("unlocked", "enabled", "null",  "coldstandby", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 10");
+                       se = st.getEndingState("unlocked", "enabled", "null",  "coldstandby", "unlock");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 11");
+                       se = st.getEndingState("unlocked", "enabled", "null",  "coldstandby", "disableFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 12");
+                       se = st.getEndingState("unlocked", "enabled", "null",  "coldstandby", "enableNotFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 13");
+                       se = st.getEndingState("unlocked", "enabled", "null",  "coldstandby", "disableDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 14");
+                       se = st.getEndingState("unlocked", "enabled", "null",  "coldstandby", "enableNoDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 15");
+                       se = st.getEndingState("unlocked", "enabled", "null",  "coldstandby", "promote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 16");
+                       se = st.getEndingState("unlocked", "enabled", "null",  "coldstandby", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 17");
+                       se = st.getEndingState("unlocked", "enabled", "null",  "hotstandby", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 18");
+                       se = st.getEndingState("unlocked", "enabled", "null",  "hotstandby", "unlock");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 19");
+                       se = st.getEndingState("unlocked", "enabled", "null",  "hotstandby", "disableFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 20");
+                       se = st.getEndingState("unlocked", "enabled", "null",  "hotstandby", "enableNotFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 21");
+                       se = st.getEndingState("unlocked", "enabled", "null",  "hotstandby", "disableDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 22");
+                       se = st.getEndingState("unlocked", "enabled", "null",  "hotstandby", "enableNoDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 23");
+                       se = st.getEndingState("unlocked", "enabled", "null",  "hotstandby", "promote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 24");
+                       se = st.getEndingState("unlocked", "enabled", "null",  "hotstandby", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 25");
+                       se = st.getEndingState("unlocked", "enabled", "null",  "providingservice", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 26");
+                       se = st.getEndingState("unlocked", "enabled", "null",  "providingservice", "unlock");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 27");
+                       se = st.getEndingState("unlocked", "enabled", "null",  "providingservice", "disableFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 28");
+                       se = st.getEndingState("unlocked", "enabled", "null",  "providingservice", "enableNotFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 29");
+                       se = st.getEndingState("unlocked", "enabled", "null",  "providingservice", "disableDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 30");
+                       se = st.getEndingState("unlocked", "enabled", "null",  "providingservice", "enableNoDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 31");
+                       se = st.getEndingState("unlocked", "enabled", "null",  "providingservice", "promote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 32");
+                       se = st.getEndingState("unlocked", "enabled", "null",  "providingservice", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 33");
+                       se = st.getEndingState("unlocked", "enabled", "failed",  "null", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 34");
+                       se = st.getEndingState("unlocked", "enabled", "failed",  "null", "unlock");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 35");
+                       se = st.getEndingState("unlocked", "enabled", "failed",  "null", "disableFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 36");
+                       se = st.getEndingState("unlocked", "enabled", "failed",  "null", "enableNotFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 37");
+                       se = st.getEndingState("unlocked", "enabled", "failed",  "null", "disableDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 38");
+                       se = st.getEndingState("unlocked", "enabled", "failed",  "null", "enableNoDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 39");
+                       se = st.getEndingState("unlocked", "enabled", "failed",  "null", "promote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 40");
+                       se = st.getEndingState("unlocked", "enabled", "failed",  "null", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 41");
+                       se = st.getEndingState("unlocked", "enabled", "failed",  "coldstandby", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 42");
+                       se = st.getEndingState("unlocked", "enabled", "failed",  "coldstandby", "unlock");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 43");
+                       se = st.getEndingState("unlocked", "enabled", "failed",  "coldstandby", "disableFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 44");
+                       se = st.getEndingState("unlocked", "enabled", "failed",  "coldstandby", "enableNotFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 45");
+                       se = st.getEndingState("unlocked", "enabled", "failed",  "coldstandby", "disableDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 46");
+                       se = st.getEndingState("unlocked", "enabled", "failed",  "coldstandby", "enableNoDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 47");
+                       se = st.getEndingState("unlocked", "enabled", "failed",  "coldstandby", "promote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 48");
+                       se = st.getEndingState("unlocked", "enabled", "failed",  "coldstandby", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 49");
+                       se = st.getEndingState("unlocked", "enabled", "failed",  "hotstandby", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 50");
+                       se = st.getEndingState("unlocked", "enabled", "failed",  "hotstandby", "unlock");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 51");
+                       se = st.getEndingState("unlocked", "enabled", "failed",  "hotstandby", "disableFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 52");
+                       se = st.getEndingState("unlocked", "enabled", "failed",  "hotstandby", "enableNotFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 53");
+                       se = st.getEndingState("unlocked", "enabled", "failed",  "hotstandby", "disableDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 54");
+                       se = st.getEndingState("unlocked", "enabled", "failed",  "hotstandby", "enableNoDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 55");
+                       se = st.getEndingState("unlocked", "enabled", "failed",  "hotstandby", "promote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 56");
+                       se = st.getEndingState("unlocked", "enabled", "failed",  "hotstandby", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 57");
+                       se = st.getEndingState("unlocked", "enabled", "failed",  "providingservice", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 58");
+                       se = st.getEndingState("unlocked", "enabled", "failed",  "providingservice", "unlock");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 59");
+                       se = st.getEndingState("unlocked", "enabled", "failed",  "providingservice", "disableFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 60");
+                       se = st.getEndingState("unlocked", "enabled", "failed",  "providingservice", "enableNotFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 61");
+                       se = st.getEndingState("unlocked", "enabled", "failed",  "providingservice", "disableDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 62");
+                       se = st.getEndingState("unlocked", "enabled", "failed",  "providingservice", "enableNoDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 63");
+                       se = st.getEndingState("unlocked", "enabled", "failed",  "providingservice", "promote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 64");
+                       se = st.getEndingState("unlocked", "enabled", "failed",  "providingservice", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 65");
+                       se = st.getEndingState("unlocked", "enabled", "dependency",  "null", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 66");
+                       se = st.getEndingState("unlocked", "enabled", "dependency",  "null", "unlock");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 67");
+                       se = st.getEndingState("unlocked", "enabled", "dependency",  "null", "disableFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 68");
+                       se = st.getEndingState("unlocked", "enabled", "dependency",  "null", "enableNotFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 69");
+                       se = st.getEndingState("unlocked", "enabled", "dependency",  "null", "disableDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 70");
+                       se = st.getEndingState("unlocked", "enabled", "dependency",  "null", "enableNoDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 71");
+                       se = st.getEndingState("unlocked", "enabled", "dependency",  "null", "promote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 72");
+                       se = st.getEndingState("unlocked", "enabled", "dependency",  "null", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 73");
+                       se = st.getEndingState("unlocked", "enabled", "dependency",  "coldstandby", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 74");
+                       se = st.getEndingState("unlocked", "enabled", "dependency",  "coldstandby", "unlock");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 75");
+                       se = st.getEndingState("unlocked", "enabled", "dependency",  "coldstandby", "disableFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 76");
+                       se = st.getEndingState("unlocked", "enabled", "dependency",  "coldstandby", "enableNotFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 77");
+                       se = st.getEndingState("unlocked", "enabled", "dependency",  "coldstandby", "disableDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 78");
+                       se = st.getEndingState("unlocked", "enabled", "dependency",  "coldstandby", "enableNoDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 79");
+                       se = st.getEndingState("unlocked", "enabled", "dependency",  "coldstandby", "promote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 80");
+                       se = st.getEndingState("unlocked", "enabled", "dependency",  "coldstandby", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 81");
+                       se = st.getEndingState("unlocked", "enabled", "dependency",  "hotstandby", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 82");
+                       se = st.getEndingState("unlocked", "enabled", "dependency",  "hotstandby", "unlock");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 83");
+                       se = st.getEndingState("unlocked", "enabled", "dependency",  "hotstandby", "disableFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 84");
+                       se = st.getEndingState("unlocked", "enabled", "dependency",  "hotstandby", "enableNotFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 85");
+                       se = st.getEndingState("unlocked", "enabled", "dependency",  "hotstandby", "disableDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 86");
+                       se = st.getEndingState("unlocked", "enabled", "dependency",  "hotstandby", "enableNoDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 87");
+                       se = st.getEndingState("unlocked", "enabled", "dependency",  "hotstandby", "promote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 88");
+                       se = st.getEndingState("unlocked", "enabled", "dependency",  "hotstandby", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 89");
+                       se = st.getEndingState("unlocked", "enabled", "dependency",  "providingservice", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 90");
+                       se = st.getEndingState("unlocked", "enabled", "dependency",  "providingservice", "unlock");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 91");
+                       se = st.getEndingState("unlocked", "enabled", "dependency",  "providingservice", "disableFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 92");
+                       se = st.getEndingState("unlocked", "enabled", "dependency",  "providingservice", "enableNotFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 93");
+                       se = st.getEndingState("unlocked", "enabled", "dependency",  "providingservice", "disableDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 94");
+                       se = st.getEndingState("unlocked", "enabled", "dependency",  "providingservice", "enableNoDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 95");
+                       se = st.getEndingState("unlocked", "enabled", "dependency",  "providingservice", "promote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 96");
+                       se = st.getEndingState("unlocked", "enabled", "dependency",  "providingservice", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 97");
+                       se = st.getEndingState("unlocked", "enabled", "dependency,failed",  "null", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 98");
+                       se = st.getEndingState("unlocked", "enabled", "dependency,failed",  "null", "unlock");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 99");
+                       se = st.getEndingState("unlocked", "enabled", "dependency,failed",  "null", "disableFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 100");
+                       se = st.getEndingState("unlocked", "enabled", "dependency,failed",  "null", "enableNotFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 101");
+                       se = st.getEndingState("unlocked", "enabled", "dependency,failed",  "null", "disableDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 102");
+                       se = st.getEndingState("unlocked", "enabled", "dependency,failed",  "null", "enableNoDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 103");
+                       se = st.getEndingState("unlocked", "enabled", "dependency,failed",  "null", "promote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 104");
+                       se = st.getEndingState("unlocked", "enabled", "dependency,failed",  "null", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 105");
+                       se = st.getEndingState("unlocked", "enabled", "dependency,failed",  "coldstandby", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 106");
+                       se = st.getEndingState("unlocked", "enabled", "dependency,failed",  "coldstandby", "unlock");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 107");
+                       se = st.getEndingState("unlocked", "enabled", "dependency,failed",  "coldstandby", "disableFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 108");
+                       se = st.getEndingState("unlocked", "enabled", "dependency,failed",  "coldstandby", "enableNotFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 109");
+                       se = st.getEndingState("unlocked", "enabled", "dependency,failed",  "coldstandby", "disableDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 110");
+                       se = st.getEndingState("unlocked", "enabled", "dependency,failed",  "coldstandby", "enableNoDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 111");
+                       se = st.getEndingState("unlocked", "enabled", "dependency,failed",  "coldstandby", "promote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 112");
+                       se = st.getEndingState("unlocked", "enabled", "dependency,failed",  "coldstandby", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 113");
+                       se = st.getEndingState("unlocked", "enabled", "dependency,failed",  "hotstandby", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 114");
+                       se = st.getEndingState("unlocked", "enabled", "dependency,failed",  "hotstandby", "unlock");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 115");
+                       se = st.getEndingState("unlocked", "enabled", "dependency,failed",  "hotstandby", "disableFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 116");
+                       se = st.getEndingState("unlocked", "enabled", "dependency,failed",  "hotstandby", "enableNotFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 117");
+                       se = st.getEndingState("unlocked", "enabled", "dependency,failed",  "hotstandby", "disableDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 118");
+                       se = st.getEndingState("unlocked", "enabled", "dependency,failed",  "hotstandby", "enableNoDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 119");
+                       se = st.getEndingState("unlocked", "enabled", "dependency,failed",  "hotstandby", "promote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 120");
+                       se = st.getEndingState("unlocked", "enabled", "dependency,failed",  "hotstandby", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 121");
+                       se = st.getEndingState("unlocked", "enabled", "dependency,failed",  "providingservice", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 122");
+                       se = st.getEndingState("unlocked", "enabled", "dependency,failed",  "providingservice", "unlock");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 123");
+                       se = st.getEndingState("unlocked", "enabled", "dependency,failed",  "providingservice", "disableFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 124");
+                       se = st.getEndingState("unlocked", "enabled", "dependency,failed",  "providingservice", "enableNotFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 125");
+                       se = st.getEndingState("unlocked", "enabled", "dependency,failed",  "providingservice", "disableDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 126");
+                       se = st.getEndingState("unlocked", "enabled", "dependency,failed",  "providingservice", "enableNoDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 127");
+                       se = st.getEndingState("unlocked", "enabled", "dependency,failed",  "providingservice", "promote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 128");
+                       se = st.getEndingState("unlocked", "enabled", "dependency,failed",  "providingservice", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 129");
+                       se = st.getEndingState("unlocked", "disabled", "null",  "null", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 130");
+                       se = st.getEndingState("unlocked", "disabled", "null",  "null", "unlock");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 131");
+                       se = st.getEndingState("unlocked", "disabled", "null",  "null", "disableFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 132");
+                       se = st.getEndingState("unlocked", "disabled", "null",  "null", "enableNotFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 133");
+                       se = st.getEndingState("unlocked", "disabled", "null",  "null", "disableDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 134");
+                       se = st.getEndingState("unlocked", "disabled", "null",  "null", "enableNoDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 135");
+                       se = st.getEndingState("unlocked", "disabled", "null",  "null", "promote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 136");
+                       se = st.getEndingState("unlocked", "disabled", "null",  "null", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 137");
+                       se = st.getEndingState("unlocked", "disabled", "null",  "coldstandby", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 138");
+                       se = st.getEndingState("unlocked", "disabled", "null",  "coldstandby", "unlock");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 139");
+                       se = st.getEndingState("unlocked", "disabled", "null",  "coldstandby", "disableFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 140");
+                       se = st.getEndingState("unlocked", "disabled", "null",  "coldstandby", "enableNotFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 141");
+                       se = st.getEndingState("unlocked", "disabled", "null",  "coldstandby", "disableDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 142");
+                       se = st.getEndingState("unlocked", "disabled", "null",  "coldstandby", "enableNoDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 143");
+                       se = st.getEndingState("unlocked", "disabled", "null",  "coldstandby", "promote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 144");
+                       se = st.getEndingState("unlocked", "disabled", "null",  "coldstandby", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 145");
+                       se = st.getEndingState("unlocked", "disabled", "null",  "hotstandby", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 146");
+                       se = st.getEndingState("unlocked", "disabled", "null",  "hotstandby", "unlock");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 147");
+                       se = st.getEndingState("unlocked", "disabled", "null",  "hotstandby", "disableFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 148");
+                       se = st.getEndingState("unlocked", "disabled", "null",  "hotstandby", "enableNotFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 149");
+                       se = st.getEndingState("unlocked", "disabled", "null",  "hotstandby", "disableDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 150");
+                       se = st.getEndingState("unlocked", "disabled", "null",  "hotstandby", "enableNoDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 151");
+                       se = st.getEndingState("unlocked", "disabled", "null",  "hotstandby", "promote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 152");
+                       se = st.getEndingState("unlocked", "disabled", "null",  "hotstandby", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 153");
+                       se = st.getEndingState("unlocked", "disabled", "null",  "providingservice", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 154");
+                       se = st.getEndingState("unlocked", "disabled", "null",  "providingservice", "unlock");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 155");
+                       se = st.getEndingState("unlocked", "disabled", "null",  "providingservice", "disableFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 156");
+                       se = st.getEndingState("unlocked", "disabled", "null",  "providingservice", "enableNotFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 157");
+                       se = st.getEndingState("unlocked", "disabled", "null",  "providingservice", "disableDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 158");
+                       se = st.getEndingState("unlocked", "disabled", "null",  "providingservice", "enableNoDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 159");
+                       se = st.getEndingState("unlocked", "disabled", "null",  "providingservice", "promote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 160");
+                       se = st.getEndingState("unlocked", "disabled", "null",  "providingservice", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 161");
+                       se = st.getEndingState("unlocked", "disabled", "failed",  "null", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 162");
+                       se = st.getEndingState("unlocked", "disabled", "failed",  "null", "unlock");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 163");
+                       se = st.getEndingState("unlocked", "disabled", "failed",  "null", "disableFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 164");
+                       se = st.getEndingState("unlocked", "disabled", "failed",  "null", "enableNotFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 165");
+                       se = st.getEndingState("unlocked", "disabled", "failed",  "null", "disableDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 166");
+                       se = st.getEndingState("unlocked", "disabled", "failed",  "null", "enableNoDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 167");
+                       se = st.getEndingState("unlocked", "disabled", "failed",  "null", "promote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 168");
+                       se = st.getEndingState("unlocked", "disabled", "failed",  "null", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 169");
+                       se = st.getEndingState("unlocked", "disabled", "failed",  "coldstandby", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 170");
+                       se = st.getEndingState("unlocked", "disabled", "failed",  "coldstandby", "unlock");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 171");
+                       se = st.getEndingState("unlocked", "disabled", "failed",  "coldstandby", "disableFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 172");
+                       se = st.getEndingState("unlocked", "disabled", "failed",  "coldstandby", "enableNotFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 173");
+                       se = st.getEndingState("unlocked", "disabled", "failed",  "coldstandby", "disableDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 174");
+                       se = st.getEndingState("unlocked", "disabled", "failed",  "coldstandby", "enableNoDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 175");
+                       se = st.getEndingState("unlocked", "disabled", "failed",  "coldstandby", "promote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 176");
+                       se = st.getEndingState("unlocked", "disabled", "failed",  "coldstandby", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 177");
+                       se = st.getEndingState("unlocked", "disabled", "failed",  "hotstandby", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 178");
+                       se = st.getEndingState("unlocked", "disabled", "failed",  "hotstandby", "unlock");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 179");
+                       se = st.getEndingState("unlocked", "disabled", "failed",  "hotstandby", "disableFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 180");
+                       se = st.getEndingState("unlocked", "disabled", "failed",  "hotstandby", "enableNotFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 181");
+                       se = st.getEndingState("unlocked", "disabled", "failed",  "hotstandby", "disableDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 182");
+                       se = st.getEndingState("unlocked", "disabled", "failed",  "hotstandby", "enableNoDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 183");
+                       se = st.getEndingState("unlocked", "disabled", "failed",  "hotstandby", "promote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 184");
+                       se = st.getEndingState("unlocked", "disabled", "failed",  "hotstandby", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 185");
+                       se = st.getEndingState("unlocked", "disabled", "failed",  "providingservice", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 186");
+                       se = st.getEndingState("unlocked", "disabled", "failed",  "providingservice", "unlock");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 187");
+                       se = st.getEndingState("unlocked", "disabled", "failed",  "providingservice", "disableFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 188");
+                       se = st.getEndingState("unlocked", "disabled", "failed",  "providingservice", "enableNotFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 189");
+                       se = st.getEndingState("unlocked", "disabled", "failed",  "providingservice", "disableDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 190");
+                       se = st.getEndingState("unlocked", "disabled", "failed",  "providingservice", "enableNoDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 191");
+                       se = st.getEndingState("unlocked", "disabled", "failed",  "providingservice", "promote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 192");
+                       se = st.getEndingState("unlocked", "disabled", "failed",  "providingservice", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 193");
+                       se = st.getEndingState("unlocked", "disabled", "dependency",  "null", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 194");
+                       se = st.getEndingState("unlocked", "disabled", "dependency",  "null", "unlock");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 195");
+                       se = st.getEndingState("unlocked", "disabled", "dependency",  "null", "disableFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 196");
+                       se = st.getEndingState("unlocked", "disabled", "dependency",  "null", "enableNotFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 197");
+                       se = st.getEndingState("unlocked", "disabled", "dependency",  "null", "disableDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 198");
+                       se = st.getEndingState("unlocked", "disabled", "dependency",  "null", "enableNoDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 199");
+                       se = st.getEndingState("unlocked", "disabled", "dependency",  "null", "promote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 200");
+                       se = st.getEndingState("unlocked", "disabled", "dependency",  "null", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 201");
+                       se = st.getEndingState("unlocked", "disabled", "dependency",  "coldstandby", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 202");
+                       se = st.getEndingState("unlocked", "disabled", "dependency",  "coldstandby", "unlock");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 203");
+                       se = st.getEndingState("unlocked", "disabled", "dependency",  "coldstandby", "disableFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 204");
+                       se = st.getEndingState("unlocked", "disabled", "dependency",  "coldstandby", "enableNotFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 205");
+                       se = st.getEndingState("unlocked", "disabled", "dependency",  "coldstandby", "disableDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 206");
+                       se = st.getEndingState("unlocked", "disabled", "dependency",  "coldstandby", "enableNoDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 207");
+                       se = st.getEndingState("unlocked", "disabled", "dependency",  "coldstandby", "promote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 208");
+                       se = st.getEndingState("unlocked", "disabled", "dependency",  "coldstandby", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 209");
+                       se = st.getEndingState("unlocked", "disabled", "dependency",  "hotstandby", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 210");
+                       se = st.getEndingState("unlocked", "disabled", "dependency",  "hotstandby", "unlock");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 211");
+                       se = st.getEndingState("unlocked", "disabled", "dependency",  "hotstandby", "disableFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 212");
+                       se = st.getEndingState("unlocked", "disabled", "dependency",  "hotstandby", "enableNotFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 213");
+                       se = st.getEndingState("unlocked", "disabled", "dependency",  "hotstandby", "disableDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 214");
+                       se = st.getEndingState("unlocked", "disabled", "dependency",  "hotstandby", "enableNoDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 215");
+                       se = st.getEndingState("unlocked", "disabled", "dependency",  "hotstandby", "promote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 216");
+                       se = st.getEndingState("unlocked", "disabled", "dependency",  "hotstandby", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 217");
+                       se = st.getEndingState("unlocked", "disabled", "dependency",  "providingservice", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 218");
+                       se = st.getEndingState("unlocked", "disabled", "dependency",  "providingservice", "unlock");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 219");
+                       se = st.getEndingState("unlocked", "disabled", "dependency",  "providingservice", "disableFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 220");
+                       se = st.getEndingState("unlocked", "disabled", "dependency",  "providingservice", "enableNotFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 221");
+                       se = st.getEndingState("unlocked", "disabled", "dependency",  "providingservice", "disableDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 222");
+                       se = st.getEndingState("unlocked", "disabled", "dependency",  "providingservice", "enableNoDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 223");
+                       se = st.getEndingState("unlocked", "disabled", "dependency",  "providingservice", "promote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 224");
+                       se = st.getEndingState("unlocked", "disabled", "dependency",  "providingservice", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 225");
+                       se = st.getEndingState("unlocked", "disabled", "dependency,failed",  "null", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 226");
+                       se = st.getEndingState("unlocked", "disabled", "dependency,failed",  "null", "unlock");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 227");
+                       se = st.getEndingState("unlocked", "disabled", "dependency,failed",  "null", "disableFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 228");
+                       se = st.getEndingState("unlocked", "disabled", "dependency,failed",  "null", "enableNotFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 229");
+                       se = st.getEndingState("unlocked", "disabled", "dependency,failed",  "null", "disableDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 230");
+                       se = st.getEndingState("unlocked", "disabled", "dependency,failed",  "null", "enableNoDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 231");
+                       se = st.getEndingState("unlocked", "disabled", "dependency,failed",  "null", "promote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 232");
+                       se = st.getEndingState("unlocked", "disabled", "dependency,failed",  "null", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 233");
+                       se = st.getEndingState("unlocked", "disabled", "dependency,failed",  "coldstandby", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 234");
+                       se = st.getEndingState("unlocked", "disabled", "dependency,failed",  "coldstandby", "unlock");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 235");
+                       se = st.getEndingState("unlocked", "disabled", "dependency,failed",  "coldstandby", "disableFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 236");
+                       se = st.getEndingState("unlocked", "disabled", "dependency,failed",  "coldstandby", "enableNotFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 237");
+                       se = st.getEndingState("unlocked", "disabled", "dependency,failed",  "coldstandby", "disableDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 238");
+                       se = st.getEndingState("unlocked", "disabled", "dependency,failed",  "coldstandby", "enableNoDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 239");
+                       se = st.getEndingState("unlocked", "disabled", "dependency,failed",  "coldstandby", "promote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 240");
+                       se = st.getEndingState("unlocked", "disabled", "dependency,failed",  "coldstandby", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 241");
+                       se = st.getEndingState("unlocked", "disabled", "dependency,failed",  "hotstandby", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 242");
+                       se = st.getEndingState("unlocked", "disabled", "dependency,failed",  "hotstandby", "unlock");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 243");
+                       se = st.getEndingState("unlocked", "disabled", "dependency,failed",  "hotstandby", "disableFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 244");
+                       se = st.getEndingState("unlocked", "disabled", "dependency,failed",  "hotstandby", "enableNotFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 245");
+                       se = st.getEndingState("unlocked", "disabled", "dependency,failed",  "hotstandby", "disableDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 246");
+                       se = st.getEndingState("unlocked", "disabled", "dependency,failed",  "hotstandby", "enableNoDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 247");
+                       se = st.getEndingState("unlocked", "disabled", "dependency,failed",  "hotstandby", "promote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 248");
+                       se = st.getEndingState("unlocked", "disabled", "dependency,failed",  "hotstandby", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 249");
+                       se = st.getEndingState("unlocked", "disabled", "dependency,failed",  "providingservice", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 250");
+                       se = st.getEndingState("unlocked", "disabled", "dependency,failed",  "providingservice", "unlock");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 251");
+                       se = st.getEndingState("unlocked", "disabled", "dependency,failed",  "providingservice", "disableFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 252");
+                       se = st.getEndingState("unlocked", "disabled", "dependency,failed",  "providingservice", "enableNotFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 253");
+                       se = st.getEndingState("unlocked", "disabled", "dependency,failed",  "providingservice", "disableDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 254");
+                       se = st.getEndingState("unlocked", "disabled", "dependency,failed",  "providingservice", "enableNoDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 255");
+                       se = st.getEndingState("unlocked", "disabled", "dependency,failed",  "providingservice", "promote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 256");
+                       se = st.getEndingState("unlocked", "disabled", "dependency,failed",  "providingservice", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 257");
+                       se = st.getEndingState("locked", "enabled", "null",  "null", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 258");
+                       se = st.getEndingState("locked", "enabled", "null",  "null", "unlock");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 259");
+                       se = st.getEndingState("locked", "enabled", "null",  "null", "disableFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 260");
+                       se = st.getEndingState("locked", "enabled", "null",  "null", "enableNotFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 261");
+                       se = st.getEndingState("locked", "enabled", "null",  "null", "disableDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 262");
+                       se = st.getEndingState("locked", "enabled", "null",  "null", "enableNoDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 263");
+                       se = st.getEndingState("locked", "enabled", "null",  "null", "promote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 264");
+                       se = st.getEndingState("locked", "enabled", "null",  "null", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 265");
+                       se = st.getEndingState("locked", "enabled", "null",  "coldstandby", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 266");
+                       se = st.getEndingState("locked", "enabled", "null",  "coldstandby", "unlock");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 267");
+                       se = st.getEndingState("locked", "enabled", "null",  "coldstandby", "disableFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 268");
+                       se = st.getEndingState("locked", "enabled", "null",  "coldstandby", "enableNotFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 269");
+                       se = st.getEndingState("locked", "enabled", "null",  "coldstandby", "disableDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 270");
+                       se = st.getEndingState("locked", "enabled", "null",  "coldstandby", "enableNoDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 271");
+                       se = st.getEndingState("locked", "enabled", "null",  "coldstandby", "promote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 272");
+                       se = st.getEndingState("locked", "enabled", "null",  "coldstandby", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 273");
+                       se = st.getEndingState("locked", "enabled", "null",  "hotstandby", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 274");
+                       se = st.getEndingState("locked", "enabled", "null",  "hotstandby", "unlock");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 275");
+                       se = st.getEndingState("locked", "enabled", "null",  "hotstandby", "disableFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 276");
+                       se = st.getEndingState("locked", "enabled", "null",  "hotstandby", "enableNotFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 277");
+                       se = st.getEndingState("locked", "enabled", "null",  "hotstandby", "disableDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 278");
+                       se = st.getEndingState("locked", "enabled", "null",  "hotstandby", "enableNoDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 279");
+                       se = st.getEndingState("locked", "enabled", "null",  "hotstandby", "promote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 280");
+                       se = st.getEndingState("locked", "enabled", "null",  "hotstandby", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 281");
+                       se = st.getEndingState("locked", "enabled", "null",  "providingservice", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 282");
+                       se = st.getEndingState("locked", "enabled", "null",  "providingservice", "unlock");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 283");
+                       se = st.getEndingState("locked", "enabled", "null",  "providingservice", "disableFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 284");
+                       se = st.getEndingState("locked", "enabled", "null",  "providingservice", "enableNotFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 285");
+                       se = st.getEndingState("locked", "enabled", "null",  "providingservice", "disableDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 286");
+                       se = st.getEndingState("locked", "enabled", "null",  "providingservice", "enableNoDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 287");
+                       se = st.getEndingState("locked", "enabled", "null",  "providingservice", "promote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 288");
+                       se = st.getEndingState("locked", "enabled", "null",  "providingservice", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 289");
+                       se = st.getEndingState("locked", "enabled", "failed",  "null", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 290");
+                       se = st.getEndingState("locked", "enabled", "failed",  "null", "unlock");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 291");
+                       se = st.getEndingState("locked", "enabled", "failed",  "null", "disableFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 292");
+                       se = st.getEndingState("locked", "enabled", "failed",  "null", "enableNotFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 293");
+                       se = st.getEndingState("locked", "enabled", "failed",  "null", "disableDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 294");
+                       se = st.getEndingState("locked", "enabled", "failed",  "null", "enableNoDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 295");
+                       se = st.getEndingState("locked", "enabled", "failed",  "null", "promote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 296");
+                       se = st.getEndingState("locked", "enabled", "failed",  "null", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 297");
+                       se = st.getEndingState("locked", "enabled", "failed",  "coldstandby", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 298");
+                       se = st.getEndingState("locked", "enabled", "failed",  "coldstandby", "unlock");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 299");
+                       se = st.getEndingState("locked", "enabled", "failed",  "coldstandby", "disableFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 300");
+                       se = st.getEndingState("locked", "enabled", "failed",  "coldstandby", "enableNotFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 301");
+                       se = st.getEndingState("locked", "enabled", "failed",  "coldstandby", "disableDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 302");
+                       se = st.getEndingState("locked", "enabled", "failed",  "coldstandby", "enableNoDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 303");
+                       se = st.getEndingState("locked", "enabled", "failed",  "coldstandby", "promote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 304");
+                       se = st.getEndingState("locked", "enabled", "failed",  "coldstandby", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 305");
+                       se = st.getEndingState("locked", "enabled", "failed",  "hotstandby", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 306");
+                       se = st.getEndingState("locked", "enabled", "failed",  "hotstandby", "unlock");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 307");
+                       se = st.getEndingState("locked", "enabled", "failed",  "hotstandby", "disableFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 308");
+                       se = st.getEndingState("locked", "enabled", "failed",  "hotstandby", "enableNotFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 309");
+                       se = st.getEndingState("locked", "enabled", "failed",  "hotstandby", "disableDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 310");
+                       se = st.getEndingState("locked", "enabled", "failed",  "hotstandby", "enableNoDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 311");
+                       se = st.getEndingState("locked", "enabled", "failed",  "hotstandby", "promote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 312");
+                       se = st.getEndingState("locked", "enabled", "failed",  "hotstandby", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 313");
+                       se = st.getEndingState("locked", "enabled", "failed",  "providingservice", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 314");
+                       se = st.getEndingState("locked", "enabled", "failed",  "providingservice", "unlock");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 315");
+                       se = st.getEndingState("locked", "enabled", "failed",  "providingservice", "disableFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 316");
+                       se = st.getEndingState("locked", "enabled", "failed",  "providingservice", "enableNotFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 317");
+                       se = st.getEndingState("locked", "enabled", "failed",  "providingservice", "disableDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 318");
+                       se = st.getEndingState("locked", "enabled", "failed",  "providingservice", "enableNoDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 319");
+                       se = st.getEndingState("locked", "enabled", "failed",  "providingservice", "promote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 320");
+                       se = st.getEndingState("locked", "enabled", "failed",  "providingservice", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 321");
+                       se = st.getEndingState("locked", "enabled", "dependency",  "null", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 322");
+                       se = st.getEndingState("locked", "enabled", "dependency",  "null", "unlock");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 323");
+                       se = st.getEndingState("locked", "enabled", "dependency",  "null", "disableFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 324");
+                       se = st.getEndingState("locked", "enabled", "dependency",  "null", "enableNotFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 325");
+                       se = st.getEndingState("locked", "enabled", "dependency",  "null", "disableDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 326");
+                       se = st.getEndingState("locked", "enabled", "dependency",  "null", "enableNoDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 327");
+                       se = st.getEndingState("locked", "enabled", "dependency",  "null", "promote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 328");
+                       se = st.getEndingState("locked", "enabled", "dependency",  "null", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 329");
+                       se = st.getEndingState("locked", "enabled", "dependency",  "coldstandby", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 330");
+                       se = st.getEndingState("locked", "enabled", "dependency",  "coldstandby", "unlock");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 331");
+                       se = st.getEndingState("locked", "enabled", "dependency",  "coldstandby", "disableFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 332");
+                       se = st.getEndingState("locked", "enabled", "dependency",  "coldstandby", "enableNotFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 333");
+                       se = st.getEndingState("locked", "enabled", "dependency",  "coldstandby", "disableDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 334");
+                       se = st.getEndingState("locked", "enabled", "dependency",  "coldstandby", "enableNoDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 335");
+                       se = st.getEndingState("locked", "enabled", "dependency",  "coldstandby", "promote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 336");
+                       se = st.getEndingState("locked", "enabled", "dependency",  "coldstandby", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 337");
+                       se = st.getEndingState("locked", "enabled", "dependency",  "hotstandby", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 338");
+                       se = st.getEndingState("locked", "enabled", "dependency",  "hotstandby", "unlock");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 339");
+                       se = st.getEndingState("locked", "enabled", "dependency",  "hotstandby", "disableFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 340");
+                       se = st.getEndingState("locked", "enabled", "dependency",  "hotstandby", "enableNotFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 341");
+                       se = st.getEndingState("locked", "enabled", "dependency",  "hotstandby", "disableDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 342");
+                       se = st.getEndingState("locked", "enabled", "dependency",  "hotstandby", "enableNoDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 343");
+                       se = st.getEndingState("locked", "enabled", "dependency",  "hotstandby", "promote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 344");
+                       se = st.getEndingState("locked", "enabled", "dependency",  "hotstandby", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 345");
+                       se = st.getEndingState("locked", "enabled", "dependency",  "providingservice", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 346");
+                       se = st.getEndingState("locked", "enabled", "dependency",  "providingservice", "unlock");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 347");
+                       se = st.getEndingState("locked", "enabled", "dependency",  "providingservice", "disableFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 348");
+                       se = st.getEndingState("locked", "enabled", "dependency",  "providingservice", "enableNotFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 349");
+                       se = st.getEndingState("locked", "enabled", "dependency",  "providingservice", "disableDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 350");
+                       se = st.getEndingState("locked", "enabled", "dependency",  "providingservice", "enableNoDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 351");
+                       se = st.getEndingState("locked", "enabled", "dependency",  "providingservice", "promote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 352");
+                       se = st.getEndingState("locked", "enabled", "dependency",  "providingservice", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 353");
+                       se = st.getEndingState("locked", "enabled", "dependency,failed",  "null", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 354");
+                       se = st.getEndingState("locked", "enabled", "dependency,failed",  "null", "unlock");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 355");
+                       se = st.getEndingState("locked", "enabled", "dependency,failed",  "null", "disableFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 356");
+                       se = st.getEndingState("locked", "enabled", "dependency,failed",  "null", "enableNotFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 357");
+                       se = st.getEndingState("locked", "enabled", "dependency,failed",  "null", "disableDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 358");
+                       se = st.getEndingState("locked", "enabled", "dependency,failed",  "null", "enableNoDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 359");
+                       se = st.getEndingState("locked", "enabled", "dependency,failed",  "null", "promote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 360");
+                       se = st.getEndingState("locked", "enabled", "dependency,failed",  "null", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 361");
+                       se = st.getEndingState("locked", "enabled", "dependency,failed",  "coldstandby", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 362");
+                       se = st.getEndingState("locked", "enabled", "dependency,failed",  "coldstandby", "unlock");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 363");
+                       se = st.getEndingState("locked", "enabled", "dependency,failed",  "coldstandby", "disableFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 364");
+                       se = st.getEndingState("locked", "enabled", "dependency,failed",  "coldstandby", "enableNotFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 365");
+                       se = st.getEndingState("locked", "enabled", "dependency,failed",  "coldstandby", "disableDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 366");
+                       se = st.getEndingState("locked", "enabled", "dependency,failed",  "coldstandby", "enableNoDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 367");
+                       se = st.getEndingState("locked", "enabled", "dependency,failed",  "coldstandby", "promote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 368");
+                       se = st.getEndingState("locked", "enabled", "dependency,failed",  "coldstandby", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 369");
+                       se = st.getEndingState("locked", "enabled", "dependency,failed",  "hotstandby", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 370");
+                       se = st.getEndingState("locked", "enabled", "dependency,failed",  "hotstandby", "unlock");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 371");
+                       se = st.getEndingState("locked", "enabled", "dependency,failed",  "hotstandby", "disableFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 372");
+                       se = st.getEndingState("locked", "enabled", "dependency,failed",  "hotstandby", "enableNotFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 373");
+                       se = st.getEndingState("locked", "enabled", "dependency,failed",  "hotstandby", "disableDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 374");
+                       se = st.getEndingState("locked", "enabled", "dependency,failed",  "hotstandby", "enableNoDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 375");
+                       se = st.getEndingState("locked", "enabled", "dependency,failed",  "hotstandby", "promote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 376");
+                       se = st.getEndingState("locked", "enabled", "dependency,failed",  "hotstandby", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 377");
+                       se = st.getEndingState("locked", "enabled", "dependency,failed",  "providingservice", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 378");
+                       se = st.getEndingState("locked", "enabled", "dependency,failed",  "providingservice", "unlock");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 379");
+                       se = st.getEndingState("locked", "enabled", "dependency,failed",  "providingservice", "disableFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 380");
+                       se = st.getEndingState("locked", "enabled", "dependency,failed",  "providingservice", "enableNotFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 381");
+                       se = st.getEndingState("locked", "enabled", "dependency,failed",  "providingservice", "disableDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 382");
+                       se = st.getEndingState("locked", "enabled", "dependency,failed",  "providingservice", "enableNoDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 383");
+                       se = st.getEndingState("locked", "enabled", "dependency,failed",  "providingservice", "promote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 384");
+                       se = st.getEndingState("locked", "enabled", "dependency,failed",  "providingservice", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 385");
+                       se = st.getEndingState("locked", "disabled", "null",  "null", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 386");
+                       se = st.getEndingState("locked", "disabled", "null",  "null", "unlock");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 387");
+                       se = st.getEndingState("locked", "disabled", "null",  "null", "disableFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 388");
+                       se = st.getEndingState("locked", "disabled", "null",  "null", "enableNotFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 389");
+                       se = st.getEndingState("locked", "disabled", "null",  "null", "disableDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 390");
+                       se = st.getEndingState("locked", "disabled", "null",  "null", "enableNoDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 391");
+                       se = st.getEndingState("locked", "disabled", "null",  "null", "promote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 392");
+                       se = st.getEndingState("locked", "disabled", "null",  "null", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 393");
+                       se = st.getEndingState("locked", "disabled", "null",  "coldstandby", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 394");
+                       se = st.getEndingState("locked", "disabled", "null",  "coldstandby", "unlock");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 395");
+                       se = st.getEndingState("locked", "disabled", "null",  "coldstandby", "disableFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 396");
+                       se = st.getEndingState("locked", "disabled", "null",  "coldstandby", "enableNotFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 397");
+                       se = st.getEndingState("locked", "disabled", "null",  "coldstandby", "disableDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 398");
+                       se = st.getEndingState("locked", "disabled", "null",  "coldstandby", "enableNoDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 399");
+                       se = st.getEndingState("locked", "disabled", "null",  "coldstandby", "promote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 400");
+                       se = st.getEndingState("locked", "disabled", "null",  "coldstandby", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 401");
+                       se = st.getEndingState("locked", "disabled", "null",  "hotstandby", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 402");
+                       se = st.getEndingState("locked", "disabled", "null",  "hotstandby", "unlock");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 403");
+                       se = st.getEndingState("locked", "disabled", "null",  "hotstandby", "disableFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 404");
+                       se = st.getEndingState("locked", "disabled", "null",  "hotstandby", "enableNotFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 405");
+                       se = st.getEndingState("locked", "disabled", "null",  "hotstandby", "disableDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 406");
+                       se = st.getEndingState("locked", "disabled", "null",  "hotstandby", "enableNoDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 407");
+                       se = st.getEndingState("locked", "disabled", "null",  "hotstandby", "promote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 408");
+                       se = st.getEndingState("locked", "disabled", "null",  "hotstandby", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 409");
+                       se = st.getEndingState("locked", "disabled", "null",  "providingservice", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 410");
+                       se = st.getEndingState("locked", "disabled", "null",  "providingservice", "unlock");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 411");
+                       se = st.getEndingState("locked", "disabled", "null",  "providingservice", "disableFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 412");
+                       se = st.getEndingState("locked", "disabled", "null",  "providingservice", "enableNotFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 413");
+                       se = st.getEndingState("locked", "disabled", "null",  "providingservice", "disableDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 414");
+                       se = st.getEndingState("locked", "disabled", "null",  "providingservice", "enableNoDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 415");
+                       se = st.getEndingState("locked", "disabled", "null",  "providingservice", "promote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 416");
+                       se = st.getEndingState("locked", "disabled", "null",  "providingservice", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 417");
+                       se = st.getEndingState("locked", "disabled", "failed",  "null", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 418");
+                       se = st.getEndingState("locked", "disabled", "failed",  "null", "unlock");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 419");
+                       se = st.getEndingState("locked", "disabled", "failed",  "null", "disableFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 420");
+                       se = st.getEndingState("locked", "disabled", "failed",  "null", "enableNotFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 421");
+                       se = st.getEndingState("locked", "disabled", "failed",  "null", "disableDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 422");
+                       se = st.getEndingState("locked", "disabled", "failed",  "null", "enableNoDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 423");
+                       se = st.getEndingState("locked", "disabled", "failed",  "null", "promote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 424");
+                       se = st.getEndingState("locked", "disabled", "failed",  "null", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 425");
+                       se = st.getEndingState("locked", "disabled", "failed",  "coldstandby", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 426");
+                       se = st.getEndingState("locked", "disabled", "failed",  "coldstandby", "unlock");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 427");
+                       se = st.getEndingState("locked", "disabled", "failed",  "coldstandby", "disableFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 428");
+                       se = st.getEndingState("locked", "disabled", "failed",  "coldstandby", "enableNotFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 429");
+                       se = st.getEndingState("locked", "disabled", "failed",  "coldstandby", "disableDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 430");
+                       se = st.getEndingState("locked", "disabled", "failed",  "coldstandby", "enableNoDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 431");
+                       se = st.getEndingState("locked", "disabled", "failed",  "coldstandby", "promote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 432");
+                       se = st.getEndingState("locked", "disabled", "failed",  "coldstandby", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 433");
+                       se = st.getEndingState("locked", "disabled", "failed",  "hotstandby", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 434");
+                       se = st.getEndingState("locked", "disabled", "failed",  "hotstandby", "unlock");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 435");
+                       se = st.getEndingState("locked", "disabled", "failed",  "hotstandby", "disableFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 436");
+                       se = st.getEndingState("locked", "disabled", "failed",  "hotstandby", "enableNotFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 437");
+                       se = st.getEndingState("locked", "disabled", "failed",  "hotstandby", "disableDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 438");
+                       se = st.getEndingState("locked", "disabled", "failed",  "hotstandby", "enableNoDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 439");
+                       se = st.getEndingState("locked", "disabled", "failed",  "hotstandby", "promote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 440");
+                       se = st.getEndingState("locked", "disabled", "failed",  "hotstandby", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 441");
+                       se = st.getEndingState("locked", "disabled", "failed",  "providingservice", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 442");
+                       se = st.getEndingState("locked", "disabled", "failed",  "providingservice", "unlock");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 443");
+                       se = st.getEndingState("locked", "disabled", "failed",  "providingservice", "disableFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 444");
+                       se = st.getEndingState("locked", "disabled", "failed",  "providingservice", "enableNotFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 445");
+                       se = st.getEndingState("locked", "disabled", "failed",  "providingservice", "disableDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 446");
+                       se = st.getEndingState("locked", "disabled", "failed",  "providingservice", "enableNoDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 447");
+                       se = st.getEndingState("locked", "disabled", "failed",  "providingservice", "promote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 448");
+                       se = st.getEndingState("locked", "disabled", "failed",  "providingservice", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 449");
+                       se = st.getEndingState("locked", "disabled", "dependency",  "null", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 450");
+                       se = st.getEndingState("locked", "disabled", "dependency",  "null", "unlock");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 451");
+                       se = st.getEndingState("locked", "disabled", "dependency",  "null", "disableFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 452");
+                       se = st.getEndingState("locked", "disabled", "dependency",  "null", "enableNotFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 453");
+                       se = st.getEndingState("locked", "disabled", "dependency",  "null", "disableDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 454");
+                       se = st.getEndingState("locked", "disabled", "dependency",  "null", "enableNoDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 455");
+                       se = st.getEndingState("locked", "disabled", "dependency",  "null", "promote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 456");
+                       se = st.getEndingState("locked", "disabled", "dependency",  "null", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 457");
+                       se = st.getEndingState("locked", "disabled", "dependency",  "coldstandby", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 458");
+                       se = st.getEndingState("locked", "disabled", "dependency",  "coldstandby", "unlock");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 459");
+                       se = st.getEndingState("locked", "disabled", "dependency",  "coldstandby", "disableFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 460");
+                       se = st.getEndingState("locked", "disabled", "dependency",  "coldstandby", "enableNotFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 461");
+                       se = st.getEndingState("locked", "disabled", "dependency",  "coldstandby", "disableDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 462");
+                       se = st.getEndingState("locked", "disabled", "dependency",  "coldstandby", "enableNoDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 463");
+                       se = st.getEndingState("locked", "disabled", "dependency",  "coldstandby", "promote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 464");
+                       se = st.getEndingState("locked", "disabled", "dependency",  "coldstandby", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 465");
+                       se = st.getEndingState("locked", "disabled", "dependency",  "hotstandby", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 466");
+                       se = st.getEndingState("locked", "disabled", "dependency",  "hotstandby", "unlock");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 467");
+                       se = st.getEndingState("locked", "disabled", "dependency",  "hotstandby", "disableFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 468");
+                       se = st.getEndingState("locked", "disabled", "dependency",  "hotstandby", "enableNotFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 469");
+                       se = st.getEndingState("locked", "disabled", "dependency",  "hotstandby", "disableDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 470");
+                       se = st.getEndingState("locked", "disabled", "dependency",  "hotstandby", "enableNoDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 471");
+                       se = st.getEndingState("locked", "disabled", "dependency",  "hotstandby", "promote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 472");
+                       se = st.getEndingState("locked", "disabled", "dependency",  "hotstandby", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 473");
+                       se = st.getEndingState("locked", "disabled", "dependency",  "providingservice", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 474");
+                       se = st.getEndingState("locked", "disabled", "dependency",  "providingservice", "unlock");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 475");
+                       se = st.getEndingState("locked", "disabled", "dependency",  "providingservice", "disableFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 476");
+                       se = st.getEndingState("locked", "disabled", "dependency",  "providingservice", "enableNotFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 477");
+                       se = st.getEndingState("locked", "disabled", "dependency",  "providingservice", "disableDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 478");
+                       se = st.getEndingState("locked", "disabled", "dependency",  "providingservice", "enableNoDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 479");
+                       se = st.getEndingState("locked", "disabled", "dependency",  "providingservice", "promote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 480");
+                       se = st.getEndingState("locked", "disabled", "dependency",  "providingservice", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 481");
+                       se = st.getEndingState("locked", "disabled", "dependency,failed",  "null", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 482");
+                       se = st.getEndingState("locked", "disabled", "dependency,failed",  "null", "unlock");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 483");
+                       se = st.getEndingState("locked", "disabled", "dependency,failed",  "null", "disableFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 484");
+                       se = st.getEndingState("locked", "disabled", "dependency,failed",  "null", "enableNotFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 485");
+                       se = st.getEndingState("locked", "disabled", "dependency,failed",  "null", "disableDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 486");
+                       se = st.getEndingState("locked", "disabled", "dependency,failed",  "null", "enableNoDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 487");
+                       se = st.getEndingState("locked", "disabled", "dependency,failed",  "null", "promote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 488");
+                       se = st.getEndingState("locked", "disabled", "dependency,failed",  "null", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 489");
+                       se = st.getEndingState("locked", "disabled", "dependency,failed",  "coldstandby", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 490");
+                       se = st.getEndingState("locked", "disabled", "dependency,failed",  "coldstandby", "unlock");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 491");
+                       se = st.getEndingState("locked", "disabled", "dependency,failed",  "coldstandby", "disableFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 492");
+                       se = st.getEndingState("locked", "disabled", "dependency,failed",  "coldstandby", "enableNotFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 493");
+                       se = st.getEndingState("locked", "disabled", "dependency,failed",  "coldstandby", "disableDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 494");
+                       se = st.getEndingState("locked", "disabled", "dependency,failed",  "coldstandby", "enableNoDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 495");
+                       se = st.getEndingState("locked", "disabled", "dependency,failed",  "coldstandby", "promote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 496");
+                       se = st.getEndingState("locked", "disabled", "dependency,failed",  "coldstandby", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 497");
+                       se = st.getEndingState("locked", "disabled", "dependency,failed",  "hotstandby", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 498");
+                       se = st.getEndingState("locked", "disabled", "dependency,failed",  "hotstandby", "unlock");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 499");
+                       se = st.getEndingState("locked", "disabled", "dependency,failed",  "hotstandby", "disableFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 500");
+                       se = st.getEndingState("locked", "disabled", "dependency,failed",  "hotstandby", "enableNotFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 501");
+                       se = st.getEndingState("locked", "disabled", "dependency,failed",  "hotstandby", "disableDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 502");
+                       se = st.getEndingState("locked", "disabled", "dependency,failed",  "hotstandby", "enableNoDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 503");
+                       se = st.getEndingState("locked", "disabled", "dependency,failed",  "hotstandby", "promote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 504");
+                       se = st.getEndingState("locked", "disabled", "dependency,failed",  "hotstandby", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 505");
+                       se = st.getEndingState("locked", "disabled", "dependency,failed",  "providingservice", "demote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 506");
+                       se = st.getEndingState("locked", "disabled", "dependency,failed",  "providingservice", "unlock");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 507");
+                       se = st.getEndingState("locked", "disabled", "dependency,failed",  "providingservice", "disableFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 508");
+                       se = st.getEndingState("locked", "disabled", "dependency,failed",  "providingservice", "enableNotFailed");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 509");
+                       se = st.getEndingState("locked", "disabled", "dependency,failed",  "providingservice", "disableDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 510");
+                       se = st.getEndingState("locked", "disabled", "dependency,failed",  "providingservice", "enableNoDependency");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 511");
+                       se = st.getEndingState("locked", "disabled", "dependency,failed",  "providingservice", "promote");
+                       if (se != null) displayEndingState(se);
+
+                       logger.info("??? StateTransition testcase 512");
+                       se = st.getEndingState("locked", "disabled", "dependency,failed",  "providingservice", "demote");
+                       if (se != null) displayEndingState(se);
+                       
+                   } catch (Exception ex) {
+                       logger.error("EndingState NOT found");
+                       throw new Exception("EndingState NOT found. " + ex);
+                   }
+
+                       //if (emf.isOpen()) {
+                               //emf.close(); 
+                       //}
+               } catch(Exception ex) {
+                       logger.error("Exception: " + ex.toString());
+                       throw new Exception("Failure getting ending state. " + ex );
+               } finally {
+                       if (emf != null && emf.isOpen()) {
+                           emf.close(); 
+                       }
+               }
+
+           logger.info("\n\nStateTransitionTest: Exit\n\n");
+       }
+       
+       private void displayEndingState(StateElement se) 
+       {
+               String endingStandbyStatus = se.getEndingStandbyStatus(); 
+               if (endingStandbyStatus != null) {
+                       endingStandbyStatus.replace(".",  ",");
+               }
+           logger.info("EndingAdminState   = [" + se.getEndingAdminState() +"]"); 
+           logger.info("EndingOpState      = [" + se.getEndingOpState() +"]"); 
+               logger.info("EndingAvailStatus  = [" + se.getEndingAvailStatus() +"]"); 
+               logger.info("EndingStandbyStatus= [" + endingStandbyStatus +"]");
+               logger.info("Exception          = [" + se.getException() +"]");                 
+       } 
+}
\ No newline at end of file
diff --git a/integrity-monitor/src/test/resources/log4j.properties b/integrity-monitor/src/test/resources/log4j.properties
new file mode 100644 (file)
index 0000000..efc18e9
--- /dev/null
@@ -0,0 +1,54 @@
+###
+# ============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=========================================================
+###
+
+#
+# Use this properties for debugging and development.
+#
+#
+# For debug output, set root logger level to DEBUG and output to FILE and CONSOLE
+#log4j.rootLogger=DEBUG, FILE, CONSOLE
+log4j.rootLogger=INFO, FILE, CONSOLE
+
+# A1 is set to be a DailyRollingFileAppender.
+log4j.appender.FILE=org.apache.log4j.DailyRollingFileAppender
+
+# Set the name of the file
+log4j.appender.FILE.File=IntegrityMonitor.log
+
+# Set the immediate flush to true (default)
+log4j.appender.FILE.ImmediateFlush=true
+
+# Set the threshold to debug mode
+log4j.appender.FILE.Threshold=debug
+
+# Set the append to false, should not overwrite
+log4j.appender.FILE.Append=true
+
+# Set the DatePattern
+log4j.appender.FILE.DatePattern='.'yyyy-MM-dd
+
+# A1 uses PatternLayout.
+log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
+log4j.appender.FILE.layout.ConversionPattern=%d{yyyy_MM_dd_HH_mm_ss_SSS} [%t] %-5p %l- %m%n
+
+# for Developments and Debugging
+log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
+log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
+log4j.appender.CONSOLE.layout.ConversionPattern=%d{yyyy_MM_dd_HH_mm_ss_SSS} [%t] %-5p %l- %m%n
diff --git a/integrity-monitor/src/test/resources/logback.xml b/integrity-monitor/src/test/resources/logback.xml
new file mode 100644 (file)
index 0000000..3a87900
--- /dev/null
@@ -0,0 +1,209 @@
+<!--
+  ============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=========================================================
+  -->
+
+<!-- Controls the output of logs for JUnit tests -->
+
+<configuration scan="true" scanPeriod="3 seconds" debug="true">
+  <!--<jmxConfigurator /> -->
+  <!-- directory path for all other type logs -->
+  <property name="logDir" value="testingLogs" />
+  
+  <!-- directory path for debugging type logs -->
+  <property name="debugDir" value="testingLogs" />
+  
+  <!--  specify the component name 
+    <ECOMP-component-name>::= "MSO" | "DCAE" | "ASDC " | "AAI" |"Policy" | "SDNC" | "AC"  -->
+  <property name="componentName" value="common-modules"></property>
+  <property name="subComponentName" value="integrity-monitor"></property>
+  
+  <!--  log file names -->
+  <property name="errorLogName" value="error" />
+  <property name="metricsLogName" value="metrics" />
+  <property name="auditLogName" value="audit" />
+  <property name="debugLogName" value="debug" />
+  
+   <property name="defaultPattern" value="%d{&quot;yyyy-MM-dd'T'HH:mm:ss.SSSXXX&quot;, UTC}|%X{requestId}|%X{serviceInstanceId}|%t|%X{serverName}|%X{serviceName}|%X{instanceUuid}|%p|%X{severity}|%X{serverIpAddress}|%X{server}|%X{clientIpAddress}|%c||%msg%n" />
+   <!--  <property name="defaultPattern" value="%d{&quot;yyyy-MM-dd'T'HH:mm:ss.SSSXXX&quot;, UTC}|%X{RequestId}|%X{ServiceInstanceId}|%thread||%X{ServiceName}|%X{InstanceUUID}|%.-5level|%X{AlertSeverity}|%X{ServerIPAddress}|%X{ServerFQDN}|%X{RemoteHost}||%X{Timer}|%msg%n" />  -->
+  <property name="logDirectory" value="${logDir}/${componentName}/${subComponentName}" />
+  <property name="debugLogDirectory" value="${debugDir}/${componentName}/${subComponentName}" />
+   <!--
+  <property name="logDirectory" value="${logDir}/${componentName}/${subComponentName}" />
+  <property name="debugLogDirectory" value="${debugDir}/${componentName}/${subComponentName}" />
+  -->
+  <!-- example from old log4j.properties:  ${catalina.base}/logs/pdp-rest.log  -->  
+  <!-- Example evaluator filter applied against console appender -->
+  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+    <encoder>
+      <pattern>${defaultPattern}</pattern>
+    </encoder>
+  </appender>
+
+  <!-- ============================================================================ -->
+  <!-- EELF Appenders -->
+  <!-- ============================================================================ -->
+
+  <!-- The EELFAppender is used to record events to the general application 
+    log -->
+    
+    
+
+  
+  <!-- EELF Audit Appender. This appender is used to record audit engine 
+    related logging events. The audit logger and appender are specializations 
+    of the EELF application root logger and appender. This can be used to segregate 
+    Policy engine events from other components, or it can be eliminated to record 
+    these events as part of the application root log. -->
+    
+  <appender name="EELFAudit"
+    class="ch.qos.logback.core.rolling.RollingFileAppender">
+    <file>${logDirectory}/${auditLogName}.log</file>
+    <rollingPolicy
+      class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
+      <fileNamePattern>${logDirectory}/${auditLogName}.%i.log.zip
+      </fileNamePattern>
+      <minIndex>1</minIndex>
+      <maxIndex>9</maxIndex>
+    </rollingPolicy>
+    <triggeringPolicy
+      class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
+      <maxFileSize>5MB</maxFileSize>
+    </triggeringPolicy>
+    <encoder>
+         <pattern>${defaultPattern}</pattern>
+    </encoder>
+  </appender>
+  <appender name="asyncEELFAudit" class="ch.qos.logback.classic.AsyncAppender">
+    <queueSize>256</queueSize>
+    <appender-ref ref="EELFAudit" />
+  </appender>
+
+<appender name="EELFMetrics"
+    class="ch.qos.logback.core.rolling.RollingFileAppender">
+    <file>${logDirectory}/${metricsLogName}.log</file>
+    <rollingPolicy
+      class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
+      <fileNamePattern>${logDirectory}/${metricsLogName}.%i.log.zip
+      </fileNamePattern>
+      <minIndex>1</minIndex>
+      <maxIndex>9</maxIndex>
+    </rollingPolicy>
+    <triggeringPolicy
+      class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
+      <maxFileSize>5MB</maxFileSize>
+    </triggeringPolicy>
+    <encoder>
+      <!-- <pattern>"%d{HH:mm:ss.SSS} [%thread] %-5level %logger{1024} - 
+        %msg%n"</pattern> -->
+      <pattern>${defaultPattern}</pattern>
+    </encoder>
+  </appender>
+  
+  
+  <appender name="asyncEELFMetrics" class="ch.qos.logback.classic.AsyncAppender">
+    <queueSize>256</queueSize>
+    <appender-ref ref="EELFMetrics"/>
+  </appender>
+   
+  <appender name="EELFError"
+    class="ch.qos.logback.core.rolling.RollingFileAppender">
+    <file>${logDirectory}/${errorLogName}.log</file>
+    <rollingPolicy
+      class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
+      <fileNamePattern>${logDirectory}/${errorLogName}.%i.log.zip
+      </fileNamePattern>
+      <minIndex>1</minIndex>
+      <maxIndex>9</maxIndex>
+    </rollingPolicy>
+    <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
+     <level>ERROR</level>
+     </filter>
+    <triggeringPolicy
+      class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
+      <maxFileSize>5MB</maxFileSize>
+    </triggeringPolicy>
+    <encoder>
+      <pattern>${defaultPattern}</pattern>
+    </encoder>
+  </appender>
+  
+  <appender name="asyncEELFError" class="ch.qos.logback.classic.AsyncAppender">
+    <queueSize>256</queueSize>
+    <appender-ref ref="EELFError"/>
+  </appender>
+  
+   <appender name="EELFDebug"
+    class="ch.qos.logback.core.rolling.RollingFileAppender">
+    <file>${debugLogDirectory}/${debugLogName}.log</file>
+    <rollingPolicy
+      class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
+      <fileNamePattern>${debugLogDirectory}/${debugLogName}.%i.log.zip
+      </fileNamePattern>
+      <minIndex>1</minIndex>
+      <maxIndex>9</maxIndex>
+    </rollingPolicy>
+    <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
+     <!-- <level>INFO</level> -->
+     <level>DEBUG</level>
+     </filter>
+    <triggeringPolicy
+      class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
+      <maxFileSize>5MB</maxFileSize>
+    </triggeringPolicy>
+    <encoder>
+      <pattern>${defaultPattern}</pattern>
+    </encoder>
+  </appender>
+  
+  <appender name="asyncEELFDebug" class="ch.qos.logback.classic.AsyncAppender">
+    <queueSize>256</queueSize>
+    <appender-ref ref="EELFDebug" />
+    <includeCallerData>true</includeCallerData>
+  </appender>
+  
+  <!-- ============================================================================ -->
+  <!--  EELF loggers -->
+  <!-- ============================================================================ -->
+  <logger name="com.att.eelf.audit" level="info" additivity="false">
+    <appender-ref ref="asyncEELFAudit" />
+  </logger>
+  
+  <logger name="com.att.eelf.metrics" level="info" additivity="false">
+        <appender-ref ref="asyncEELFMetrics" />
+  </logger>
+    <logger name="com.att.eelf.error" level="error" additivity="false">
+  <appender-ref ref="asyncEELFError" />
+  </logger>
+  
+   <!-- <logger name="com.att.eelf.debug" level="info" additivity="false"> -->
+   <logger name="com.att.eelf.debug" level="debug" additivity="false">
+        <appender-ref ref="asyncEELFDebug" />
+  </logger>
+  
+  
+  <!-- <root level="INFO"> -->
+  <root level="DEBUG">
+        <appender-ref ref="asyncEELFDebug" />
+        <appender-ref ref="asyncEELFError" />
+  </root>
+
+</configuration>
diff --git a/pom.xml b/pom.xml
new file mode 100644 (file)
index 0000000..f9a59db
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,115 @@
+<!--
+  ============LICENSE_START=======================================================
+  ECOMP Policy Engine - Drools PDP
+  ================================================================================
+  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=========================================================
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+       <modelVersion>4.0.0</modelVersion>
+
+       <groupId>org.openecomp.policy.common</groupId>
+       <artifactId>common-modules</artifactId>
+       <version>1.0.0-SNAPSHOT</version>
+
+       <packaging>pom</packaging>
+
+       <name>ECOMP Policy Engine - Common Modules</name>
+       <description>Common Modules for Policy-Engine in both XACML and Drools flavor</description>
+
+       <properties>
+               <maven.compiler.source>1.8</maven.compiler.source>
+               <maven.compiler.target>1.8</maven.compiler.target>
+               <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+       </properties>
+
+
+       <modules>
+               <module>common-logging</module>
+               <module>integrity-audit</module>
+               <module>integrity-monitor</module>
+               <module>site-manager</module>
+       </modules>
+
+       <repositories>
+               <repository>
+                       <id>central</id>
+                       <name>Maven 2 repository</name>
+                       <url>http://repo2.maven.org/maven2/</url>
+               </repository>
+       </repositories>
+
+       <build>
+               <plugins>
+                       <plugin>
+                               <groupId>org.apache.maven.plugins</groupId>
+                               <artifactId>maven-deploy-plugin</artifactId>
+                               <version>2.8</version> <!-- This version supports the "deployAtEnd" parameter -->
+                       </plugin>
+                                               <!-- 
+                               license plugin
+                            Run 
+                               mvn clean 
+                            before running from the command line
+                               mvn license:update-file-header
+                       -->
+                       <plugin>
+                               <groupId>org.codehaus.mojo</groupId>
+                               <artifactId>license-maven-plugin</artifactId>
+                               <version>1.9</version>
+                               <configuration>
+                                       <extraExtensions>
+                                               <!-- Used to add or change the header style <fileTypeYouAreMapping> 
+                                                       fileTypeMappedInto </fileTypeYouAreMapping> -->
+                                               <drl>java</drl>
+                                               <ccf>properties</ccf>
+
+                                               <!-- Because the typical sql comment type confuses the update algorithm -->
+                                               <sql>java</sql>
+                                       </extraExtensions>
+                                       <licenseName>apache_v2</licenseName>
+
+                                       <inceptionYear>2017</inceptionYear>
+                                       <organizationName>AT&amp;T Intellectual Property. All rights reserved.</organizationName>
+
+                                       <!-- Once you have established the tags and delimiter, they cannot be 
+                                               changed -->
+                                       <processStartTag>============LICENSE_START=======================================================</processStartTag>
+                                       <processEndTag>============LICENSE_END=========================================================</processEndTag>
+                                       <sectionDelimiter>================================================================================</sectionDelimiter>
+                                       <addJavaLicenseAfterPackage>false</addJavaLicenseAfterPackage>
+                                       <canUpdateCopyright>true</canUpdateCopyright>
+                                       <canUpdateDescription>true</canUpdateDescription>
+                                       <canUpdateLicense>true</canUpdateLicense>
+                                       <emptyLineAfterHeader>true</emptyLineAfterHeader>
+                                       <roots>
+                                               <!-- Default is src, target/generated-sources, target/processed-sources -->
+
+                                               <!-- Everything except the files in the excludes section -->
+                                               <root>/</root>
+                                       </roots>
+                                       <excludes>
+                                               <!-- Files which are to be excluded. The pom.xml is excluded because 
+                                                       the start/end tags and the delimiters are in the body of the file. This confuses 
+                                                       the algorithm. So, this file must be manually updated with a license header. -->
+                                               <exclude>pom.xml</exclude>
+                                       </excludes>
+                               </configuration>
+                       </plugin>
+               </plugins>
+       </build>
+</project>
diff --git a/project-configs/maven/conf/settings.xml b/project-configs/maven/conf/settings.xml
new file mode 100644 (file)
index 0000000..87c2744
--- /dev/null
@@ -0,0 +1,166 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ============LICENSE_START=======================================================
+  ECOMP Policy Engine - Common Modules
+  ================================================================================
+  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=========================================================
+  -->
+
+
+<!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor 
+       license agreements. See the NOTICE file distributed with this work for additional 
+       information regarding copyright ownership. The ASF licenses this file to 
+       you 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. -->
+
+
+<!-- Special settings file for the maven installation on AT&T central Jenkins -->
+
+
+<!-- | This is the configuration file for Maven. It can be specified at two 
+       levels: | | 1. User Level. This settings.xml file provides configuration 
+       for a single user, | and is normally provided in ${user.home}/.m2/settings.xml. 
+       | | NOTE: This location can be overridden with the CLI option: | | -s /path/to/user/settings.xml 
+       | | 2. Global Level. This settings.xml file provides configuration for all 
+       Maven | users on a machine (assuming they're all using the same Maven | installation). 
+       It's normally provided in | ${maven.home}/conf/settings.xml. | | NOTE: This 
+       location can be overridden with the CLI option: | | -gs /path/to/global/settings.xml 
+       | | The sections in this sample file are intended to give you a running start 
+       at | getting the most out of your Maven installation. Where appropriate, 
+       the default | values (values used when the setting is not specified) are 
+       provided. | | -->
+<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
+       <!-- localRepository | The path to the local repository maven will use to 
+               store artifacts. | | Default: ${user.home}/.m2/repository <localRepository>/path/to/local/repo</localRepository> -->
+               
+       <!-- interactiveMode | This will determine whether maven prompts you when 
+               it needs input. If set to false, | maven will use a sensible default value, 
+               perhaps based on some other setting, for | the parameter in question. | | 
+               Default: true <interactiveMode>true</interactiveMode> -->
+
+       <!-- offline | Determines whether maven should attempt to connect to the 
+               network when executing a build. | This will have an effect on artifact downloads, 
+               artifact deployment, and others. | | Default: false <offline>false</offline> -->
+
+       <!-- pluginGroups | This is a list of additional group identifiers that 
+               will be searched when resolving plugins by their prefix, i.e. | when invoking 
+               a command line like "mvn prefix:goal". Maven will automatically add the group 
+               identifiers | "org.apache.maven.plugins" and "org.codehaus.mojo" if these 
+               are not already contained in the list. | -->
+       <pluginGroups>
+               <!-- pluginGroup | Specifies a further group identifier to use for plugin 
+                       lookup. <pluginGroup>com.your.plugins</pluginGroup> -->
+       </pluginGroups>
+
+       <!-- proxies | This is a list of proxies which can be used on this machine 
+               to connect to the network. | Unless otherwise specified (by system property 
+               or command-line switch), the first proxy | specification in this list marked 
+               as active will be used. | -->
+       <proxies>
+       </proxies>
+
+       <!-- servers | This is a list of authentication profiles, keyed by the server-id 
+               used within the system. | Authentication profiles can be used whenever maven 
+               must make a connection to a remote server. | -->
+       <servers>
+               <!-- server | Specifies the authentication information to use when connecting 
+                       to a particular server, identified by | a unique name within the system (referred 
+                       to by the 'id' attribute below). | | NOTE: You should either specify username/password 
+                       OR privateKey/passphrase, since these pairings are | used together. | <server> 
+                       <id>deploymentRepo</id> <username>repouser</username> <password>repopwd</password> 
+                       </server> -->
+
+               <!-- Another sample, using keys to authenticate. <server> <id>siteServer</id> 
+                       <privateKey>/path/to/private/key</privateKey> <passphrase>optional; leave 
+                       empty if not used.</passphrase> </server> -->
+       </servers>
+
+       <!-- mirrors | This is a list of mirrors to be used in downloading artifacts 
+               from remote repositories. | | It works like this: a POM may declare a repository 
+               to use in resolving certain artifacts. | However, this repository may have 
+               problems with heavy traffic at times, so people have mirrored | it to several 
+               places. | | That repository definition will have a unique id, so we can create 
+               a mirror reference for that | repository, to be used as an alternate download 
+               site. The mirror site will be the preferred | server for that repository. 
+               | -->
+       <mirrors>
+               <!-- mirror | Specifies a repository mirror site to use instead of a given 
+                       repository. The repository that | this mirror serves has an ID that matches 
+                       the mirrorOf element of this mirror. IDs are used | for inheritance and direct 
+                       lookup purposes, and must be unique across the set of mirrors. | -->
+
+       </mirrors>
+
+       <!-- profiles | This is a list of profiles which can be activated in a variety 
+               of ways, and which can modify | the build process. Profiles provided in the 
+               settings.xml are intended to provide local machine- | specific paths and 
+               repository locations which allow the build to work in the local environment. 
+               | | For example, if you have an integration testing plugin - like cactus 
+               - that needs to know where | your Tomcat instance is installed, you can provide 
+               a variable here such that the variable is | dereferenced during the build 
+               process to configure the cactus plugin. | | As noted above, profiles can 
+               be activated in a variety of ways. One way - the activeProfiles | section 
+               of this document (settings.xml) - will be discussed later. Another way essentially 
+               | relies on the detection of a system property, either matching a particular 
+               value for the property, | or merely testing its existence. Profiles can also 
+               be activated by JDK version prefix, where a | value of '1.4' might activate 
+               a profile when the build is executed on a JDK version of '1.4.2_07'. | Finally, 
+               the list of active profiles can be specified directly from the command line. 
+               | | NOTE: For profiles defined in the settings.xml, you are restricted to 
+               specifying only artifact | repositories, plugin repositories, and free-form 
+               properties to be used as configuration | variables for plugins in the POM. 
+               | | -->
+       <profiles>
+               <!-- profile | Specifies a set of introductions to the build process, to 
+                       be activated using one or more of the | mechanisms described above. For inheritance 
+                       purposes, and to activate profiles via <activatedProfiles/> | or the command 
+                       line, profiles have to have an ID that is unique. | | An encouraged best 
+                       practice for profile identification is to use a consistent naming convention 
+                       | for profiles, such as 'env-dev', 'env-test', 'env-production', 'user-jdcasey', 
+                       'user-brett', etc. | This will make it more intuitive to understand what 
+                       the set of introduced profiles is attempting | to accomplish, particularly 
+                       when you only have a list of profile id's for debug. | | This profile example 
+                       uses the JDK version to trigger activation, and provides a JDK-specific repo. 
+                       <profile> <id>jdk-1.4</id> <activation> <jdk>1.4</jdk> </activation> <repositories> 
+                       <repository> <id>jdk14</id> <name>Repository for JDK 1.4 builds</name> <url>http://www.myhost.com/maven/jdk14</url> 
+                       <layout>default</layout> <snapshotPolicy>always</snapshotPolicy> </repository> 
+                       </repositories> </profile> -->
+
+               <!-- | Here is another profile, activated by the system property 'target-env' 
+                       with a value of 'dev', | which provides a specific path to the Tomcat instance. 
+                       To use this, your plugin configuration | might hypothetically look like: 
+                       | | ... | <plugin> | <groupId>org.myco.myplugins</groupId> | <artifactId>myplugin</artifactId> 
+                       | | <configuration> | <tomcatLocation>${tomcatPath}</tomcatLocation> | </configuration> 
+                       | </plugin> | ... | | NOTE: If you just wanted to inject this configuration 
+                       whenever someone set 'target-env' to | anything, you could just leave off 
+                       the <value/> inside the activation-property. | <profile> <id>env-dev</id> 
+                       <activation> <property> <name>target-env</name> <value>dev</value> </property> 
+                       </activation> <properties> <tomcatPath>/path/to/tomcat/instance</tomcatPath> 
+                       </properties> </profile> -->
+       </profiles>
+
+       <!-- activeProfiles | List of profiles that are active for all builds. | 
+               <activeProfiles> <activeProfile>alwaysActiveProfile</activeProfile> <activeProfile>anotherAlwaysActiveProfile</activeProfile> 
+               </activeProfiles> -->
+</settings>
+
diff --git a/site-manager/pom.xml b/site-manager/pom.xml
new file mode 100644 (file)
index 0000000..9bd11e5
--- /dev/null
@@ -0,0 +1,128 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ============LICENSE_START=======================================================
+  ECOMP Policy Engine - Common Modules
+  ================================================================================
+  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=========================================================
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" 
+                xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+                xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+       
+       <modelVersion>4.0.0</modelVersion>
+
+       <groupId>org.openecomp.policy.common</groupId>
+       <artifactId>site-manager</artifactId>
+       <packaging>jar</packaging>
+
+       <parent>
+               <groupId>org.openecomp.policy.common</groupId>
+               <artifactId>common-modules</artifactId>
+               <version>1.0.0-SNAPSHOT</version>
+       </parent>
+
+       <name>site-manager</name>
+
+       <properties>
+               <maven.compiler.source>1.7</maven.compiler.source>
+               <maven.compiler.target>1.7</maven.compiler.target>
+       </properties>
+
+       <build>
+               <plugins>
+                       <plugin>
+                               <artifactId>maven-resources-plugin</artifactId>
+                               <version>2.6</version>
+                               <executions>
+                                       <execution>
+                                               <id>copy-resources</id>
+                                               <goals>
+                                                       <goal>copy-resources</goal>
+                                               </goals>
+                                               <phase>validate</phase>
+                                               <configuration>
+                                                       <outputDirectory>target/files</outputDirectory>
+                                                       <resources>
+                                                               <resource>
+                                                                       <directory>src/main/files</directory>
+                                                                       <filtering>true</filtering>
+                                                               </resource>
+                                                       </resources>
+                                               </configuration>
+                                       </execution>
+                               </executions>
+                       </plugin>
+                       <plugin>
+                               <groupId>org.apache.maven.plugins</groupId>
+                               <artifactId>maven-shade-plugin</artifactId>
+                               <version>1.4</version>
+                               <executions>
+                                       <execution>
+                                               <phase>package</phase>
+                                               <goals>
+                                                       <goal>shade</goal>
+                                               </goals>
+                                       </execution>
+                               </executions>
+                       </plugin>
+                       <plugin>
+                               <artifactId>maven-assembly-plugin</artifactId>
+                               <version>2.6</version>
+                               <executions>
+                                       <execution>
+                                               <id>zipfile</id>
+                                               <goals>
+                                                       <goal>single</goal>
+                                               </goals>
+                                               <phase>package</phase>
+                                               <configuration>
+                                                       <attach>true</attach>
+                                                       <finalName>${project.artifactId}-${project.version}</finalName>
+                                                       <descriptors>
+                                                               <descriptor>src/assembly/assemble_zip.xml</descriptor>
+                                                       </descriptors>
+                                                       <appendAssemblyId>false</appendAssemblyId>
+                                               </configuration>
+                                       </execution>
+                               </executions>
+                       </plugin>
+               </plugins>
+       </build>
+
+       <dependencies>
+               <dependency>
+                       <groupId>org.eclipse.persistence</groupId>
+                       <artifactId>javax.persistence</artifactId>
+                       <version>2.1.0</version>
+               </dependency>
+               <dependency>
+                       <groupId>org.openecomp.policy.common</groupId>
+                       <artifactId>integrity-monitor</artifactId>
+                       <version>1.0.0-SNAPSHOT</version>
+               </dependency>
+               <dependency>
+                       <groupId>org.mariadb.jdbc</groupId>
+                       <artifactId>mariadb-java-client</artifactId>
+                       <version>1.2.3</version>
+               </dependency>
+               <dependency>
+                       <groupId>commons-cli</groupId>
+                       <artifactId>commons-cli</artifactId>
+                       <version>1.3</version>
+               </dependency>
+       </dependencies>
+</project>
diff --git a/site-manager/src/assembly/assemble_zip.xml b/site-manager/src/assembly/assemble_zip.xml
new file mode 100644 (file)
index 0000000..9bd97cc
--- /dev/null
@@ -0,0 +1,62 @@
+<!--
+  ============LICENSE_START=======================================================
+  site-manager
+  ================================================================================
+  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=========================================================
+  -->
+
+<!-- Defines how we build the .zip file which is our distribution. -->
+
+<assembly
+       xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
+       <id>runtime</id>
+       <formats>
+               <format>zip</format>
+       </formats>
+
+       <!-- we want "system" and related files right at the root level as this 
+               file is suppose to be unzip on top of a karaf distro. -->
+       <includeBaseDirectory>false</includeBaseDirectory>
+
+       <fileSets>
+               <fileSet>
+                       <directory>target</directory>
+                       <outputDirectory>site-manager-${project.version}</outputDirectory>
+                       <includes>
+                               <include>site-manager-${project.version}.jar</include>
+                       </includes>
+               </fileSet>
+               <fileSet>
+                       <directory>target/files/</directory>
+                       <outputDirectory>site-manager-${project.version}</outputDirectory>
+                       <fileMode>0755</fileMode>
+                       <includes>
+                               <include>siteManager</include>
+                       </includes>
+               </fileSet>
+               <fileSet>
+                       <directory>target/files/</directory>
+                       <outputDirectory>site-manager-${project.version}</outputDirectory>
+                       <fileMode>0644</fileMode>
+                       <excludes>
+                               <exclude>siteManager</exclude>
+                       </excludes>
+               </fileSet>
+       </fileSets>
+
+</assembly>
diff --git a/site-manager/src/main/files/README b/site-manager/src/main/files/README
new file mode 100644 (file)
index 0000000..66cf08e
--- /dev/null
@@ -0,0 +1,26 @@
+Before using 'siteManager', the file 'siteManager.properties' needs to be
+edited to configure the parameters used to access the database:
+
+    javax.persistence.jdbc.driver - typically 'org.mariadb.jdbc.Driver'
+    javax.persistence.jdbc.url - URL referring to the database,
+        which typically has the form: 'jdbc:mariadb://<host>:<port>/<db>'
+               ('<db>' is probably 'xacml' in this case)
+    javax.persistence.jdbc.user - the user id for accessing the database
+    javax.persistence.jdbc.password - password for accessing the database
+
+Once the properties file has been updated, the 'siteManager' script can be
+invoked as follows:
+
+    siteManager show [ -s <site> | -r <resourceName> ] :
+        display node information
+    siteManager setAdminState { -s <site> | -r <resourceName> } <new-state> :
+        update admin state on selected nodes
+    siteManager lock { -s <site> | -r <resourceName> } :
+        lock selected nodes
+    siteManager unlock { -s <site> | -r <resourceName> } :
+        unlock selected nodes
+
+Note that the 'siteManager' script assumes that the script,
+'site-manager-${project.version}.jar' file and 'siteManager.properties' file
+are all in the same directory. If the files are separated, the 'siteManager'
+script will need to be modified so it can locate the jar and properties files.
diff --git a/site-manager/src/main/files/siteManager b/site-manager/src/main/files/siteManager
new file mode 100644 (file)
index 0000000..02e7c33
--- /dev/null
@@ -0,0 +1,7 @@
+#! /bin/bash
+
+dir="${0%/*}"
+CLASSPATH="${dir}/site-manager-${project.version}.jar" java \
+       -DsiteManager.properties=${dir}/siteManager.properties \
+       org.openecomp.policy.common.sitemanager.Main "$@" | \
+       grep -v "^\[EL Info\]"
diff --git a/site-manager/src/main/files/siteManager.properties b/site-manager/src/main/files/siteManager.properties
new file mode 100644 (file)
index 0000000..a280118
--- /dev/null
@@ -0,0 +1,24 @@
+###
+# ============LICENSE_START=======================================================
+# site-manager
+# ================================================================================
+# 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=========================================================
+###
+
+javax.persistence.jdbc.driver = org.mariadb.jdbc.Driver
+# javax.persistence.jdbc.url = jdbc:mariadb://<host>:3306/xacml
+# javax.persistence.jdbc.user = <userid>
+# javax.persistence.jdbc.password = <password>
diff --git a/site-manager/src/main/java/org/openecomp/policy/common/sitemanager/Main.java b/site-manager/src/main/java/org/openecomp/policy/common/sitemanager/Main.java
new file mode 100644 (file)
index 0000000..3344f92
--- /dev/null
@@ -0,0 +1,609 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * site-manager
+ * ================================================================================
+ * 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.sitemanager;
+
+/*
+ * Site Manager argument list:
+ *
+ * none - dump help information
+ * show - dump information about all nodes 
+ *             ([site, nodetype, resourceName],
+ *                     adminState, opState, availStatus, standbyStatus)
+ *                     The first 3 determine the sort order.
+ * setAdminState [ -s <site> | -r <resourceName> ] <new-state>
+ * lock [ -s <site> | -r <resourceName> ]
+ * unlock [ -s <site> | -r <resourceName> ]
+ */
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Properties;
+import java.util.TreeSet;
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.EntityTransaction;
+import javax.persistence.Query;
+import javax.persistence.Persistence;
+import javax.management.JMX;
+import javax.management.ObjectName;
+import javax.management.remote.JMXConnector;
+import javax.management.remote.JMXConnectorFactory;
+import javax.management.remote.JMXServiceURL;
+import org.openecomp.policy.common.im.jpa.ResourceRegistrationEntity;
+import org.openecomp.policy.common.im.jpa.StateManagementEntity;
+import org.openecomp.policy.common.im.jmx.ComponentAdminMBean;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.CommandLineParser;
+import org.apache.commons.cli.DefaultParser;
+import org.apache.commons.cli.Options;
+import org.apache.commons.cli.ParseException;
+
+/**
+ * This class contains the main entry point for Site Manager.
+ */
+public class Main
+{
+  // table mapping 'resourceName' to 'StateManagmentEntity'
+  static HashMap<String, StateManagementEntity> stateManagementTable =
+       new HashMap<String, StateManagementEntity>();
+
+  // table mapping 'resourceName' to 'StateManagmentEntity'
+  static HashMap<String, ResourceRegistrationEntity> resourceRegistrationTable =
+       new HashMap<String, ResourceRegistrationEntity>();
+
+  /**
+   * Print out help information regarding command arguments.
+   */
+  private static void help()
+  {
+       System.out.print
+         ("Usage:\n"
+          + "    siteManager show [ -s <site> | -r <resourceName> ] :\n"
+          + "        display node information\n"
+          + "    siteManager setAdminState { -s <site> | -r <resourceName> }"
+          + " <new-state> :\n"
+          + "        update admin state on selected nodes\n"
+          + "    siteManager lock { -s <site> | -r <resourceName> } :\n"
+          + "        lock selected nodes\n"
+          + "    siteManager unlock { -s <site> | -r <resourceName> } :\n"
+          + "        unlock selected nodes\n");
+  }
+
+  /**
+   * Print out help information regarding the properties file.
+   *
+   * @param propertiesFileName the path to the properties file
+   */
+  private static void helpProperties(String propertiesFileName)
+  {
+       if (propertiesFileName == null)
+         {
+               // file name not specified (missing system property)
+               System.out.print
+                 ("'siteManager' needs to be passed the system property\n"
+                  + "'siteManager.properties', which is the file name of a\n"
+                  + "properties file containing database access information\n\n");
+         }
+       else
+         {
+               File file = new File(propertiesFileName);
+               if (!file.exists())
+                 {
+                       // file name specified, but does not exist
+                       System.out.print
+                         ("Properties file '" + file.getAbsolutePath()
+                          + "' does not exist.\n\n");
+                 }
+               else
+                 {
+                       // file name specified and does exist -- presumably, the
+                       // problem is with one or more properties
+                       System.out.print
+                         ("One or more missing properties in\n'" + file.getAbsolutePath()
+                          + "'.\n\n");
+                 }
+         }
+
+       System.out.print
+         ("The following properties need to be specified:\n\n"
+          + "    javax.persistence.jdbc.driver -"
+          + " typically 'org.mariadb.jdbc.Driver'\n"
+          + "    javax.persistence.jdbc.url - URL referring to the database,\n"
+          + "        which typically has the form:"
+          + " 'jdbc:mariadb://<host>:<port>/<db>'\n"
+          + "        ('<db>' is probably 'xacml' in this case)\n"
+          + "    javax.persistence.jdbc.user - the user id for accessing the"
+          + " database\n"
+          + "    javax.persistence.jdbc.password - password for accessing the"
+          + " database\n");
+  }
+
+  /**
+   * This is the main entry point
+   *
+   * @param args these are command-line arguments to 'siteManager'
+   */
+  public static void main(String... args)
+  {
+       Options options = new Options();
+       options.addOption("s", true, "specify site");
+       options.addOption("r", true, "specify resource name");
+       options.addOption("h", false, "display help");
+       options.addOption("?", false, "display help");
+
+       // parse options
+       CommandLineParser parser = new DefaultParser();
+       CommandLine cmd = null;
+
+       try
+         {
+               cmd = parser.parse(options, args);
+         }
+       catch (ParseException e)
+         {
+               System.out.println(e.getMessage());
+               help();
+               System.exit(1);
+         }
+
+       if (cmd.getOptionValue('h') != null || cmd.getOptionValue('?') != null)
+         {
+               help();
+               System.exit(0);
+         }
+
+       // fetch options, and remaining arguments
+       String sOption = cmd.getOptionValue('s');
+       String rOption = cmd.getOptionValue('r');
+       List<String> argList = cmd.getArgList();
+
+       // a number of commands require either the '-r' option or '-s' option
+       boolean optionLetterSpecified = (rOption != null || sOption != null);
+
+       // used to accumulate any error messages that are generated
+       StringBuilder error = new StringBuilder();
+
+       // first non-option argument
+       String arg0 = null;
+
+       if (argList.size() == 0)
+         {
+               error.append("No command specified\n");
+         }
+       else
+         {
+               arg0 = argList.get(0);
+               if ("show".equalsIgnoreCase(arg0))
+                 {
+                       // show [ -s <site> | -r <resourceName> ]
+                       if (argList.size() != 1)
+                         {
+                               error.append("show: Extra arguments\n");
+                         }
+                 }
+               else if ("setAdminState".equalsIgnoreCase(arg0))
+                 {
+                       // setAdminState { -s <site> | -r <resourceName> } <new-state>
+                       switch (argList.size())
+                         {
+                         case 1:
+                               error.append("setAdminState: Missing <new-state> value\n");
+                               break;
+                         case 2:
+                               // this is expected
+                               break;
+                         default:
+                               error.append("setAdminState: Extra arguments\n");
+                               break;
+                         }
+                       if (!optionLetterSpecified)
+                         {
+                               error.append
+                                 ("setAdminState: Either '-s' or '-r' option is needed\n");
+                         }
+                 }
+               else if ("lock".equalsIgnoreCase(arg0))
+                 {
+                       // lock { -s <site> | -r <resourceName> }
+                       if (argList.size() != 1)
+                         {
+                               error.append("lock: Extra arguments\n");
+                         }
+                       if (!optionLetterSpecified)
+                         {
+                               error.append("lock: Either '-s' or '-r' option is needed\n");
+                         }
+                 }
+               else if ("unlock".equalsIgnoreCase(arg0))
+                 {
+                       // unlock { -s <site> | -r <resourceName> }
+                       if (argList.size() != 1)
+                         {
+                               error.append("unlock: Extra arguments\n");
+                         }
+                       if (!optionLetterSpecified)
+                         {
+                               error.append("unlock: Either '-s' or '-r' option is needed\n");
+                         }
+                 }
+               else
+                 {
+                       error.append(arg0).append(": Unknown command\n");
+                 }
+         }
+       if (sOption != null && rOption != null)
+         {
+               error
+                 .append(arg0)
+                 .append(":  'r' and 's' options are mutually exclusive\n");
+         }
+       if (error.length() != 0)
+         {
+               // if any errors have occurred, dump out the error string,
+               // help information, and exit
+               System.out.println(error.toString());
+               help();
+               System.exit(2);
+         }
+
+       // read in properties used to access the database
+       String propertiesFileName = System.getProperty("siteManager.properties");
+       File propertiesFile = null;
+
+       if (propertiesFileName == null
+               || !(propertiesFile = new File(propertiesFileName)).exists())
+         {
+               helpProperties(propertiesFileName);
+               System.exit(3);
+         }
+       FileInputStream fis = null;
+       Properties properties = new Properties();
+       try
+         {
+               fis = new FileInputStream(propertiesFile);
+               properties.load(fis);
+         }
+       catch (Exception e)
+         {
+               System.out.println("Exception loading properties: " + e);
+               helpProperties(propertiesFileName);
+               System.exit(3);
+         }
+       finally
+         {
+               try
+                 {
+                       fis.close();
+                 }
+               catch (Exception e)
+                 {
+                       // ignore exception
+                 }
+         }
+
+       // verify that we have all of the properties needed
+       if (properties.getProperty("javax.persistence.jdbc.driver") == null
+               || properties.getProperty("javax.persistence.jdbc.url") == null
+               || properties.getProperty("javax.persistence.jdbc.user") == null
+               || properties.getProperty("javax.persistence.jdbc.password") == null)
+         {
+               // one or more missing properties
+               helpProperties(propertiesFileName);
+               System.exit(3);
+         }
+
+       // access database through 'EntityManager'
+       EntityManagerFactory emf =
+         Persistence.createEntityManagerFactory("operationalPU", properties);
+       EntityManager em = emf.createEntityManager();
+
+       // sQuery - used for StateManagementEntity table
+       // rQuery - used for ResourceRegistrationEntity table
+       Query sQuery, rQuery;
+
+       if (rOption != null)
+         {
+               // 'resourceName' specified -- both queries are limited to this
+               // resource
+               sQuery = em.createQuery("SELECT s FROM StateManagementEntity s"
+                                                               + " WHERE s.resourceName = :resourceName")
+                 .setParameter("resourceName", rOption);
+               rQuery = em.createQuery("SELECT r FROM ResourceRegistrationEntity r"
+                                                               + " WHERE r.resourceName = :resourceName")
+                 .setParameter("resourceName", rOption);
+         }
+       else if (sOption != null)
+         {
+               // 'site' is specified -- 'ResourceRegistrationEntity' has a 'site'
+               // field, but 'StateManagementEntity' does not
+               sQuery = em.createQuery("SELECT s FROM StateManagementEntity s");
+               rQuery = em.createQuery("SELECT r FROM ResourceRegistrationEntity r"
+                                                               + " WHERE r.site = :site")
+                 .setParameter("site", sOption);
+         }
+       else
+         {
+               // query all entries
+               sQuery = em.createQuery("SELECT s FROM StateManagementEntity s");
+               rQuery = em.createQuery("SELECT r FROM ResourceRegistrationEntity r");
+         }
+
+       // perform 'StateManagementEntity' query, and place matching entries
+       // in 'stateManagementTable'
+       for (Object o : sQuery.getResultList())
+         {
+               if (o instanceof StateManagementEntity)
+                 {
+                       StateManagementEntity s = (StateManagementEntity) o;
+                       stateManagementTable.put(s.getResourceName(), s);
+                 }
+         }
+
+       // perform 'ResourceRegistrationQuery', and place matching entries
+       // in 'resourceRegistrationTable' ONLY if there is also an associated
+       // 'stateManagementTable' entry
+       for (Object o : rQuery.getResultList())
+         {
+               if (o instanceof ResourceRegistrationEntity)
+                 {
+                       ResourceRegistrationEntity r = (ResourceRegistrationEntity) o;
+                       String resourceName = r.getResourceName();
+                       if (stateManagementTable.get(resourceName) != null)
+                         {
+                               // only include entries that have a corresponding
+                               // state table entry -- silently ignore the rest
+                               resourceRegistrationTable.put(resourceName, r);
+                         }
+                 }
+         }
+
+       if (resourceRegistrationTable.size() == 0)
+         {
+               System.out.println(arg0 + ": No matching entries");
+               System.exit(4);
+         }
+
+       if ("setAdminState".equalsIgnoreCase(arg0))
+         {
+               // update admin state on all of the nodes
+               String adminState = argList.get(1);
+               EntityTransaction et = em.getTransaction();
+               et.begin();
+               try
+                 {
+                       // iterate over all matching 'ResourceRegistrationEntity' instances
+                       for (ResourceRegistrationEntity r :
+                                  resourceRegistrationTable.values())
+                         {
+                               // we know the corresponding 'StateManagementEntity' exists --
+                               // 'ResourceRegistrationEntity' entries without a matching
+                               // 'StateManagementEntity' entry were not placed in the table
+                               StateManagementEntity s =
+                                 stateManagementTable.get(r.getResourceName());
+
+                               // update the admin state, and save the changes
+                               s.setAdminState(adminState);
+                               em.persist(s);
+                         }
+                 }
+               finally
+                 {
+                       // do the commit
+                       em.flush();
+                       et.commit();
+                 }
+         }
+       else if ("lock".equalsIgnoreCase(arg0) || "unlock".equalsIgnoreCase(arg0))
+         {
+               // these use the JMX interface
+               for (ResourceRegistrationEntity r :
+                          resourceRegistrationTable.values())
+                 {
+                       // lock or unlock the entity
+                       jmxOp(arg0, r);
+
+                       // change should be reflected in 'adminState'
+                       em.refresh(stateManagementTable.get(r.getResourceName()));
+                 }
+         }
+
+       // free connection to the database
+       em.close();
+
+       // display all entries
+       display();
+  }
+
+  /**
+   * Process a 'lock' or 'unlock' operation on a single
+   * 'ResourceRegistrationEntity'
+   *
+   * @param arg0 this is the string "lock" or "unlock"
+   * @param r this is the ResourceRegistrationEntity to lock or unlock
+   */
+  static void jmxOp(String arg0, ResourceRegistrationEntity r)
+  {
+       String resourceName = r.getResourceName();
+       String jmxUrl = r.getResourceUrl();
+       if (jmxUrl == null)
+         {
+               System.out.println(arg0 + ": no resource URL for '"
+                                                  + resourceName + "'");
+               return;
+         }
+
+       JMXConnector connector = null;
+       try
+         {
+               connector = JMXConnectorFactory.connect(new JMXServiceURL(jmxUrl));
+               ComponentAdminMBean admin = JMX.newMXBeanProxy
+                 (connector.getMBeanServerConnection(),
+                  new ObjectName("ECOMP_POLICY_COMP:name=" + resourceName),
+                  ComponentAdminMBean.class);
+
+               if ("lock".equals(arg0))
+                 {
+                       admin.lock();
+                 }
+               else
+                 {
+                       admin.unlock();
+                 }
+         }
+       catch (Exception e)
+         {
+               // e.printStackTrace();
+               System.out.println(arg0 + " failed for '" + resourceName + "': " + e);
+         }
+       finally
+         {
+               if (connector != null)
+                 {
+                       try
+                         {
+                               connector.close();
+                         }
+                       catch (Exception e)
+                         {
+                               // ignore any errors here
+                         }
+                 }
+         }
+  }
+
+  /**
+   * Compare two strings, either of which may be null
+   *
+   * @param s1 the first string
+   * @param s2 the second string
+   * @return a negative value if s1<s2, 0 if they are equal,
+   *   and positive if s1>s2
+   */
+  static private int stringCompare(String s1, String s2)
+  {
+       return ((s1 == null) ?
+                       (s2 == null ? 0 : -1) :
+                       (s2 == null ? 1 : s1.compareTo(s2)));
+  }
+
+  /**
+   * Update an array of 'length' fields using an array of Strings, any of
+   * which may be 'null'. This method is used to determine the field width
+   * of each column in a tabular dump.
+   *
+   * @param current this is an array of length 7, containing the current
+   *   maximum lengths of each column in the tabular dump
+   * @param s this is an array of length 7, containing the current String
+   *   entry for each column
+   */
+  static private void updateLengths(int[] current, String[] s)
+  {
+       for (int i = 0 ; i < 7 ; i += 1)
+         {
+               String str = s[i];
+               int newLength = (str == null ? 4 : str.length());
+               if (current[i] < newLength)
+                 {
+                       // this column needs to be expanded
+                       current[i] = newLength;
+                 }
+         }
+  }
+
+  /**
+   * Ordered display -- dump out all of the entries, in 
+   */
+  static void display()
+  {
+       TreeSet<String[]> treeset = new TreeSet<String[]>
+         (new Comparator<String[]>()
+         {
+               public int compare(String[] r1, String[] r2)
+                 {
+                       int rval = 0;
+
+                       // the first 3 columns are 'Site', 'NodeType', and 'ResourceName',
+                       // and are used to sort the entries
+                       for (int i = 0 ; i < 3 ; i += 1)
+                         {
+                               if ((rval = stringCompare(r1[i], r2[i])) != 0)
+                                 break;
+                         }
+                       return(rval);
+                 }
+         });
+
+       String[] labels = new String[]
+         {"Site", "NodeType", "ResourceName",
+          "AdminState", "OpState", "AvailStatus", "StandbyStatus"};
+       String[] underlines = new String[]
+         {"----", "--------", "------------",
+          "----------", "-------", "-----------", "-------------"};
+
+       // each column needs to be at least wide enough to fit the column label
+       int lengths[] = new int[7];
+       updateLengths(lengths, labels);
+
+       // Go through the 'resourceRegistrationTable', and generate the
+       // associated table row. Maximum column widths are updated, and the
+       // entry is inserted into tree, which has the effect of sorting the
+       // entries.
+       for (ResourceRegistrationEntity r : resourceRegistrationTable.values())
+         {
+               StateManagementEntity s =
+                 stateManagementTable.get(r.getResourceName());
+
+               // these are the entries to be displayed for this row
+               String[] values = new String[]
+                 {
+                       r.getSite(), r.getNodeType(), r.getResourceName(),
+                       s.getAdminState(), s.getOpState(),
+                       s.getAvailStatus(), s.getStandbyStatus()
+                 };
+
+               treeset.add(values);
+               updateLengths(lengths, values);
+         }
+
+       // generate format string
+       StringBuilder sb = new StringBuilder();
+       for (int i = 0 ; i < 7 ; i += 1)
+         {
+               sb.append('%').append(i+1).append("$-")
+                 .append(lengths[i]).append("s ");
+         }
+       sb.setCharAt(sb.length()-1, '\n');
+       String formatString = sb.toString();
+
+       // display column headers
+       System.out.printf(formatString, labels);
+       System.out.printf(formatString, underlines);
+
+       // display all of the rows
+       for (String[] values : treeset)
+         {
+               System.out.printf(formatString, values);
+         }
+  }
+}
diff --git a/version.properties b/version.properties
new file mode 100644 (file)
index 0000000..2c7aa96
--- /dev/null
@@ -0,0 +1,35 @@
+###
+# ============LICENSE_START=======================================================
+# ECOMP Policy Engine - Common Modules
+# ================================================================================
+# 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=========================================================
+###
+
+###########################################################
+# Versioning variables
+# Note that these variables cannot be structured (e.g. : version.release or version.snapshot etc... )
+# because they are used in Jenkins, whose plug-in doesn't support
+release_name=1610
+sprint_number=34
+feature_revision=11
+swm_revision=4
+
+base_version=${release_name}.${sprint_number}.${feature_revision}
+
+# Release must be completed with svn revision # in Jenkins
+release_version=${base_version}-${swm_revision}
+snapshot_version=${base_version}-SNAPSHOT