aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPamela Dragosh <pdragosh@research.att.com>2017-02-14 19:31:53 -0500
committerPamela Dragosh <pdragosh@research.att.com>2017-02-14 19:32:27 -0500
commita974aa0cfb827476104c140096de676711d2b673 (patch)
treed636dd0cd1473dc5156eb20fd93c27861f2ffb0b
parent23bb08a5de4b88ed843970db2e702319585cc2aa (diff)
Initial OpenECOMP policy/common commit
Change-Id: I61cd29d6d8bf8702c1a66915895b519bf3484afa Signed-off-by: Pamela Dragosh <pdragosh@research.att.com>
-rw-r--r--.gitattributes37
-rw-r--r--.gitignore31
-rw-r--r--.gitreview4
-rw-r--r--LICENSE.txt16
-rw-r--r--README.md3
-rw-r--r--common-logging/config/policyLogger.properties44
-rw-r--r--common-logging/policyLogger.properties50
-rw-r--r--common-logging/pom.xml120
-rw-r--r--common-logging/src/main/java/org/openecomp/policy/common/logging/ECOMPLoggingContext.java530
-rw-r--r--common-logging/src/main/java/org/openecomp/policy/common/logging/ECOMPLoggingUtils.java52
-rw-r--r--common-logging/src/main/java/org/openecomp/policy/common/logging/eelf/Configuration.java91
-rw-r--r--common-logging/src/main/java/org/openecomp/policy/common/logging/eelf/DroolsPDPMDCInfo.java53
-rw-r--r--common-logging/src/main/java/org/openecomp/policy/common/logging/eelf/ErrorCodeMap.java112
-rw-r--r--common-logging/src/main/java/org/openecomp/policy/common/logging/eelf/EventData.java93
-rw-r--r--common-logging/src/main/java/org/openecomp/policy/common/logging/eelf/EventTrackInfo.java90
-rw-r--r--common-logging/src/main/java/org/openecomp/policy/common/logging/eelf/EventTrackInfoHandler.java109
-rw-r--r--common-logging/src/main/java/org/openecomp/policy/common/logging/eelf/MDCInfo.java35
-rw-r--r--common-logging/src/main/java/org/openecomp/policy/common/logging/eelf/MessageCodes.java163
-rw-r--r--common-logging/src/main/java/org/openecomp/policy/common/logging/eelf/PolicyLogger.java1438
-rw-r--r--common-logging/src/main/java/org/openecomp/policy/common/logging/flexlogger/EelfLogger.java481
-rw-r--r--common-logging/src/main/java/org/openecomp/policy/common/logging/flexlogger/FlexLogger.java366
-rw-r--r--common-logging/src/main/java/org/openecomp/policy/common/logging/flexlogger/FlexLoggerTester.java81
-rw-r--r--common-logging/src/main/java/org/openecomp/policy/common/logging/flexlogger/Logger.java226
-rw-r--r--common-logging/src/main/java/org/openecomp/policy/common/logging/flexlogger/Logger4J.java454
-rw-r--r--common-logging/src/main/java/org/openecomp/policy/common/logging/flexlogger/LoggerType.java30
-rw-r--r--common-logging/src/main/java/org/openecomp/policy/common/logging/flexlogger/PropertyUtil.java403
-rw-r--r--common-logging/src/main/java/org/openecomp/policy/common/logging/flexlogger/SystemOutLogger.java497
-rw-r--r--common-logging/src/main/java/org/openecomp/policy/common/logging/nsa/LoggingContext.java61
-rw-r--r--common-logging/src/main/java/org/openecomp/policy/common/logging/nsa/LoggingContextFactory.java55
-rw-r--r--common-logging/src/main/java/org/openecomp/policy/common/logging/nsa/SharedLoggingContext.java37
-rw-r--r--common-logging/src/main/java/org/openecomp/policy/common/logging/nsa/impl/SharedContext.java58
-rw-r--r--common-logging/src/main/java/org/openecomp/policy/common/logging/nsa/impl/Slf4jLoggingContext.java71
-rw-r--r--common-logging/src/main/java/org/openecomp/policy/common/logging/nsa/package-info.java27
-rw-r--r--common-logging/src/main/resources/org/openecomp/policy/common/logging/eelf/Resources.properties245
-rw-r--r--integrity-audit/config/policyLogger.properties44
-rw-r--r--integrity-audit/policyLogger.properties44
-rw-r--r--integrity-audit/pom.xml119
-rw-r--r--integrity-audit/src/main/java/org/openecomp/policy/common/ia/AuditThread.java769
-rw-r--r--integrity-audit/src/main/java/org/openecomp/policy/common/ia/DbAudit.java464
-rw-r--r--integrity-audit/src/main/java/org/openecomp/policy/common/ia/DbAuditException.java37
-rw-r--r--integrity-audit/src/main/java/org/openecomp/policy/common/ia/DbDAO.java740
-rw-r--r--integrity-audit/src/main/java/org/openecomp/policy/common/ia/DbDaoTransactionException.java37
-rw-r--r--integrity-audit/src/main/java/org/openecomp/policy/common/ia/IntegrityAudit.java241
-rw-r--r--integrity-audit/src/main/java/org/openecomp/policy/common/ia/IntegrityAuditProperties.java54
-rw-r--r--integrity-audit/src/main/java/org/openecomp/policy/common/ia/IntegrityAuditPropertiesException.java37
-rw-r--r--integrity-audit/src/main/java/org/openecomp/policy/common/ia/jpa/IntegrityAuditEntity.java204
-rw-r--r--integrity-audit/src/main/resources/META-INF/persistence.xml46
-rw-r--r--integrity-audit/src/main/resources/log4j.properties48
-rw-r--r--integrity-audit/src/main/resources/logback.xml205
-rw-r--r--integrity-audit/src/test/java/org/openecomp/policy/common/ia/test/AuditPeriodTest.java475
-rw-r--r--integrity-audit/src/test/java/org/openecomp/policy/common/ia/test/DbAuditCompareEntriesTest.java615
-rw-r--r--integrity-audit/src/test/java/org/openecomp/policy/common/ia/test/DbAuditTest.java749
-rw-r--r--integrity-audit/src/test/java/org/openecomp/policy/common/ia/test/DbDAOTest.java713
-rw-r--r--integrity-audit/src/test/java/org/openecomp/policy/common/ia/test/IntegrityAuditDesignationTest.java1101
-rw-r--r--integrity-audit/src/test/java/org/openecomp/policy/common/ia/test/jpa/IaTestEntity.java163
-rw-r--r--integrity-audit/src/test/java/org/openecomp/policy/common/ia/test/jpa/PersonTest.java64
-rw-r--r--integrity-audit/src/test/resources/log4j.properties54
-rw-r--r--integrity-audit/src/test/resources/logback.xml209
-rw-r--r--integrity-audit/src/test/resources/policyLogger.properties44
-rw-r--r--integrity-monitor/policyLogger.properties44
-rw-r--r--integrity-monitor/pom.xml115
-rw-r--r--integrity-monitor/src/main/java/org/openecomp/policy/common/im/AdministrativeStateException.java37
-rw-r--r--integrity-monitor/src/main/java/org/openecomp/policy/common/im/ForwardProgressException.java37
-rw-r--r--integrity-monitor/src/main/java/org/openecomp/policy/common/im/IntegrityMonitor.java1300
-rw-r--r--integrity-monitor/src/main/java/org/openecomp/policy/common/im/IntegrityMonitorProperties.java55
-rw-r--r--integrity-monitor/src/main/java/org/openecomp/policy/common/im/IntegrityMonitorPropertiesException.java37
-rw-r--r--integrity-monitor/src/main/java/org/openecomp/policy/common/im/StandbyStatusException.java48
-rw-r--r--integrity-monitor/src/main/java/org/openecomp/policy/common/im/StateChangeNotifier.java76
-rw-r--r--integrity-monitor/src/main/java/org/openecomp/policy/common/im/StateElement.java160
-rw-r--r--integrity-monitor/src/main/java/org/openecomp/policy/common/im/StateManagement.java1015
-rw-r--r--integrity-monitor/src/main/java/org/openecomp/policy/common/im/StateTransition.java726
-rw-r--r--integrity-monitor/src/main/java/org/openecomp/policy/common/im/jmx/ComponentAdmin.java227
-rw-r--r--integrity-monitor/src/main/java/org/openecomp/policy/common/im/jmx/ComponentAdminMBean.java50
-rw-r--r--integrity-monitor/src/main/java/org/openecomp/policy/common/im/jmx/JmxAgentConnection.java133
-rw-r--r--integrity-monitor/src/main/java/org/openecomp/policy/common/im/jpa/ForwardProgressEntity.java131
-rw-r--r--integrity-monitor/src/main/java/org/openecomp/policy/common/im/jpa/ImTestEntity.java146
-rw-r--r--integrity-monitor/src/main/java/org/openecomp/policy/common/im/jpa/ResourceRegistrationEntity.java150
-rw-r--r--integrity-monitor/src/main/java/org/openecomp/policy/common/im/jpa/StateManagementEntity.java143
-rw-r--r--integrity-monitor/src/main/resources/META-INF/persistence.xml51
-rw-r--r--integrity-monitor/src/main/resources/log4j.properties48
-rw-r--r--integrity-monitor/src/main/resources/logback.xml205
-rw-r--r--integrity-monitor/src/test/java/org/openecomp/policy/common/im/test/IntegrityMonitorTest.java734
-rw-r--r--integrity-monitor/src/test/java/org/openecomp/policy/common/im/test/StateManagementEntityTest.java195
-rw-r--r--integrity-monitor/src/test/java/org/openecomp/policy/common/im/test/StateManagementTest.java336
-rw-r--r--integrity-monitor/src/test/java/org/openecomp/policy/common/im/test/StateTransitionTest.java2186
-rw-r--r--integrity-monitor/src/test/resources/log4j.properties54
-rw-r--r--integrity-monitor/src/test/resources/logback.xml209
-rw-r--r--pom.xml115
-rw-r--r--project-configs/maven/conf/settings.xml166
-rw-r--r--site-manager/pom.xml128
-rw-r--r--site-manager/src/assembly/assemble_zip.xml62
-rw-r--r--site-manager/src/main/files/README26
-rw-r--r--site-manager/src/main/files/siteManager7
-rw-r--r--site-manager/src/main/files/siteManager.properties24
-rw-r--r--site-manager/src/main/java/org/openecomp/policy/common/sitemanager/Main.java609
-rw-r--r--version.properties35
96 files changed, 23259 insertions, 0 deletions
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..a6c1a2a
--- /dev/null
+++ b/.gitattributes
@@ -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
index 0000000..5480485
--- /dev/null
+++ b/.gitignore
@@ -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
index 0000000..9b55188
--- /dev/null
+++ b/.gitreview
@@ -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
index 0000000..e8c89ea
--- /dev/null
+++ b/LICENSE.txt
@@ -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
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
index 0000000..6aaa6a9
--- /dev/null
+++ b/common-logging/config/policyLogger.properties
@@ -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
index 0000000..7f160b6
--- /dev/null
+++ b/common-logging/policyLogger.properties
@@ -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
index 0000000..c674ffa
--- /dev/null
+++ b/common-logging/pom.xml
@@ -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
index 0000000..71e75a1
--- /dev/null
+++ b/common-logging/src/main/java/org/openecomp/policy/common/logging/ECOMPLoggingContext.java
@@ -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
index 0000000..5e6aa90
--- /dev/null
+++ b/common-logging/src/main/java/org/openecomp/policy/common/logging/ECOMPLoggingUtils.java
@@ -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
index 0000000..a2a0b78
--- /dev/null
+++ b/common-logging/src/main/java/org/openecomp/policy/common/logging/eelf/Configuration.java
@@ -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
index 0000000..ad50247
--- /dev/null
+++ b/common-logging/src/main/java/org/openecomp/policy/common/logging/eelf/DroolsPDPMDCInfo.java
@@ -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
index 0000000..4e4457d
--- /dev/null
+++ b/common-logging/src/main/java/org/openecomp/policy/common/logging/eelf/ErrorCodeMap.java
@@ -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
index 0000000..549651f
--- /dev/null
+++ b/common-logging/src/main/java/org/openecomp/policy/common/logging/eelf/EventData.java
@@ -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
index 0000000..c6ed63d
--- /dev/null
+++ b/common-logging/src/main/java/org/openecomp/policy/common/logging/eelf/EventTrackInfo.java
@@ -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
index 0000000..a947ed0
--- /dev/null
+++ b/common-logging/src/main/java/org/openecomp/policy/common/logging/eelf/EventTrackInfoHandler.java
@@ -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
index 0000000..6b5e395
--- /dev/null
+++ b/common-logging/src/main/java/org/openecomp/policy/common/logging/eelf/MDCInfo.java
@@ -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
index 0000000..6f1437e
--- /dev/null
+++ b/common-logging/src/main/java/org/openecomp/policy/common/logging/eelf/MessageCodes.java
@@ -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
index 0000000..624ba58
--- /dev/null
+++ b/common-logging/src/main/java/org/openecomp/policy/common/logging/eelf/PolicyLogger.java
@@ -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
index 0000000..6e74b94
--- /dev/null
+++ b/common-logging/src/main/java/org/openecomp/policy/common/logging/flexlogger/EelfLogger.java
@@ -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
index 0000000..4748e34
--- /dev/null
+++ b/common-logging/src/main/java/org/openecomp/policy/common/logging/flexlogger/FlexLogger.java
@@ -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
index 0000000..3e0d558
--- /dev/null
+++ b/common-logging/src/main/java/org/openecomp/policy/common/logging/flexlogger/FlexLoggerTester.java
@@ -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
index 0000000..ae21008
--- /dev/null
+++ b/common-logging/src/main/java/org/openecomp/policy/common/logging/flexlogger/Logger.java
@@ -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
index 0000000..02f95cf
--- /dev/null
+++ b/common-logging/src/main/java/org/openecomp/policy/common/logging/flexlogger/Logger4J.java
@@ -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
index 0000000..8fe55b2
--- /dev/null
+++ b/common-logging/src/main/java/org/openecomp/policy/common/logging/flexlogger/LoggerType.java
@@ -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
index 0000000..462e10c
--- /dev/null
+++ b/common-logging/src/main/java/org/openecomp/policy/common/logging/flexlogger/PropertyUtil.java
@@ -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
index 0000000..26f0664
--- /dev/null
+++ b/common-logging/src/main/java/org/openecomp/policy/common/logging/flexlogger/SystemOutLogger.java
@@ -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
index 0000000..56f6686
--- /dev/null
+++ b/common-logging/src/main/java/org/openecomp/policy/common/logging/nsa/LoggingContext.java
@@ -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
index 0000000..b8fce10
--- /dev/null
+++ b/common-logging/src/main/java/org/openecomp/policy/common/logging/nsa/LoggingContextFactory.java
@@ -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
index 0000000..2ecbcb0
--- /dev/null
+++ b/common-logging/src/main/java/org/openecomp/policy/common/logging/nsa/SharedLoggingContext.java
@@ -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
index 0000000..96ffbf6
--- /dev/null
+++ b/common-logging/src/main/java/org/openecomp/policy/common/logging/nsa/impl/SharedContext.java
@@ -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
index 0000000..de31af9
--- /dev/null
+++ b/common-logging/src/main/java/org/openecomp/policy/common/logging/nsa/impl/Slf4jLoggingContext.java
@@ -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
index 0000000..e1ef710
--- /dev/null
+++ b/common-logging/src/main/java/org/openecomp/policy/common/logging/nsa/package-info.java
@@ -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
index 0000000..c79061b
--- /dev/null
+++ b/common-logging/src/main/resources/org/openecomp/policy/common/logging/eelf/Resources.properties
@@ -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
index 0000000..1e7187f
--- /dev/null
+++ b/integrity-audit/config/policyLogger.properties
@@ -0,0 +1,44 @@
+###
+# ============LICENSE_START=======================================================
+# Integrity Audit
+# ================================================================================
+# Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+# ================================================================================
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# ============LICENSE_END=========================================================
+###
+
+################################### Set concurrentHashMap and timer info #######################
+#Timer initial delay and the delay between in milliseconds before task is to be execute.
+timer.delay.time=1000
+#Timer scheduleAtFixedRate period - time in milliseconds between successive task executions.
+check.interval= 30000
+#Longest time an event info can be stored in the concurrentHashMap for logging - in seconds.
+event.expired.time=86400
+#Size of the concurrentHashMap which stores the event starting time, etc - when its size reaches this limit, the Timer gets executed
+#to remove all expired records from this concurrentHashMap.
+concurrentHashMap.limit=5000
+#Size of the concurrentHashMap - when its size drops to this point, stop the Timer
+stop.check.point=2500
+################################### Set logging format #############################################
+# set EELF for EELF logging format, set LOG4J for using log4j, set SYSTEMOUT for using system.out.println
+logger.type=EELF
+#################################### Set level for EELF or SYSTEMOUT logging ##################################
+# Set level for debug file. Set DEBUG to enable .info, .warn and .debug; set INFO for enable .info and .warn; set OFF to disable all
+debugLogger.level=INFO
+# Set level for metrics file. Set OFF to disable; set ON to enable
+metricsLogger.level=ON
+# Set level for error file. Set OFF to disable; set ON to enable
+error.level=ON
+# Set level for audit file. Set OFF to disable; set ON to enable
+audit.level=ON
diff --git a/integrity-audit/policyLogger.properties b/integrity-audit/policyLogger.properties
new file mode 100644
index 0000000..1e7187f
--- /dev/null
+++ b/integrity-audit/policyLogger.properties
@@ -0,0 +1,44 @@
+###
+# ============LICENSE_START=======================================================
+# Integrity Audit
+# ================================================================================
+# Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+# ================================================================================
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# ============LICENSE_END=========================================================
+###
+
+################################### Set concurrentHashMap and timer info #######################
+#Timer initial delay and the delay between in milliseconds before task is to be execute.
+timer.delay.time=1000
+#Timer scheduleAtFixedRate period - time in milliseconds between successive task executions.
+check.interval= 30000
+#Longest time an event info can be stored in the concurrentHashMap for logging - in seconds.
+event.expired.time=86400
+#Size of the concurrentHashMap which stores the event starting time, etc - when its size reaches this limit, the Timer gets executed
+#to remove all expired records from this concurrentHashMap.
+concurrentHashMap.limit=5000
+#Size of the concurrentHashMap - when its size drops to this point, stop the Timer
+stop.check.point=2500
+################################### Set logging format #############################################
+# set EELF for EELF logging format, set LOG4J for using log4j, set SYSTEMOUT for using system.out.println
+logger.type=EELF
+#################################### Set level for EELF or SYSTEMOUT logging ##################################
+# Set level for debug file. Set DEBUG to enable .info, .warn and .debug; set INFO for enable .info and .warn; set OFF to disable all
+debugLogger.level=INFO
+# Set level for metrics file. Set OFF to disable; set ON to enable
+metricsLogger.level=ON
+# Set level for error file. Set OFF to disable; set ON to enable
+error.level=ON
+# Set level for audit file. Set OFF to disable; set ON to enable
+audit.level=ON
diff --git a/integrity-audit/pom.xml b/integrity-audit/pom.xml
new file mode 100644
index 0000000..26ffdea
--- /dev/null
+++ b/integrity-audit/pom.xml
@@ -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
index 0000000..2319f21
--- /dev/null
+++ b/integrity-audit/src/main/java/org/openecomp/policy/common/ia/AuditThread.java
@@ -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
index 0000000..9af8999
--- /dev/null
+++ b/integrity-audit/src/main/java/org/openecomp/policy/common/ia/DbAudit.java
@@ -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
index 0000000..956dd43
--- /dev/null
+++ b/integrity-audit/src/main/java/org/openecomp/policy/common/ia/DbAuditException.java
@@ -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
index 0000000..70f39a2
--- /dev/null
+++ b/integrity-audit/src/main/java/org/openecomp/policy/common/ia/DbDAO.java
@@ -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
index 0000000..fc2fea0
--- /dev/null
+++ b/integrity-audit/src/main/java/org/openecomp/policy/common/ia/DbDaoTransactionException.java
@@ -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
index 0000000..1dd260d
--- /dev/null
+++ b/integrity-audit/src/main/java/org/openecomp/policy/common/ia/IntegrityAudit.java
@@ -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
index 0000000..5a87c9c
--- /dev/null
+++ b/integrity-audit/src/main/java/org/openecomp/policy/common/ia/IntegrityAuditProperties.java
@@ -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
index 0000000..77c8558
--- /dev/null
+++ b/integrity-audit/src/main/java/org/openecomp/policy/common/ia/IntegrityAuditPropertiesException.java
@@ -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
index 0000000..3d50d83
--- /dev/null
+++ b/integrity-audit/src/main/java/org/openecomp/policy/common/ia/jpa/IntegrityAuditEntity.java
@@ -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
index 0000000..31ffb4d
--- /dev/null
+++ b/integrity-audit/src/main/resources/META-INF/persistence.xml
@@ -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
index 0000000..65b9e55
--- /dev/null
+++ b/integrity-audit/src/main/resources/log4j.properties
@@ -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
index 0000000..426adf9
--- /dev/null
+++ b/integrity-audit/src/main/resources/logback.xml
@@ -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
index 0000000..649b71f
--- /dev/null
+++ b/integrity-audit/src/test/java/org/openecomp/policy/common/ia/test/AuditPeriodTest.java
@@ -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
index 0000000..92483c5
--- /dev/null
+++ b/integrity-audit/src/test/java/org/openecomp/policy/common/ia/test/DbAuditCompareEntriesTest.java
@@ -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
index 0000000..f94dc21
--- /dev/null
+++ b/integrity-audit/src/test/java/org/openecomp/policy/common/ia/test/DbAuditTest.java
@@ -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
index 0000000..1c59b01
--- /dev/null
+++ b/integrity-audit/src/test/java/org/openecomp/policy/common/ia/test/DbDAOTest.java
@@ -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
index 0000000..6eb5fa4
--- /dev/null
+++ b/integrity-audit/src/test/java/org/openecomp/policy/common/ia/test/IntegrityAuditDesignationTest.java
@@ -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
index 0000000..e875fa3
--- /dev/null
+++ b/integrity-audit/src/test/java/org/openecomp/policy/common/ia/test/jpa/IaTestEntity.java
@@ -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
index 0000000..7ec5e29
--- /dev/null
+++ b/integrity-audit/src/test/java/org/openecomp/policy/common/ia/test/jpa/PersonTest.java
@@ -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
index 0000000..3defb16
--- /dev/null
+++ b/integrity-audit/src/test/resources/log4j.properties
@@ -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
index 0000000..78de63a
--- /dev/null
+++ b/integrity-audit/src/test/resources/logback.xml
@@ -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
index 0000000..cb5ef8d
--- /dev/null
+++ b/integrity-audit/src/test/resources/policyLogger.properties
@@ -0,0 +1,44 @@
+###
+# ============LICENSE_START=======================================================
+# Integrity Audit
+# ================================================================================
+# Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+# ================================================================================
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# ============LICENSE_END=========================================================
+###
+
+################################### Set concurrentHashMap and timer info #######################
+#Timer initial delay and the delay between in milliseconds before task is to be execute.
+timer.delay.time=1000
+#Timer scheduleAtFixedRate period - time in milliseconds between successive task executions.
+check.interval= 30000
+#Longest time an event info can be stored in the concurrentHashMap for logging - in seconds.
+event.expired.time=86400
+#Size of the concurrentHashMap which stores the event starting time, etc - when its size reaches this limit, the Timer gets executed
+#to remove all expired records from this concurrentHashMap.
+concurrentHashMap.limit=5000
+#Size of the concurrentHashMap - when its size drops to this point, stop the Timer
+stop.check.point=2500
+################################### Set logging format #############################################
+# set EELF for EELF logging format, set LOG4J for using log4j, set SYSTEMOUT for using system.out.println
+logger.type=EELF
+#################################### Set level for EELF or SYSTEMOUT logging ##################################
+# Set level for debug file. Set DEBUG to enable .info, .warn and .debug; set INFO for enable .info and .warn; set OFF to disable all
+debugLogger.level=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
index 0000000..6a4c2d1
--- /dev/null
+++ b/integrity-monitor/policyLogger.properties
@@ -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
index 0000000..9265df5
--- /dev/null
+++ b/integrity-monitor/pom.xml
@@ -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
index 0000000..1115c17
--- /dev/null
+++ b/integrity-monitor/src/main/java/org/openecomp/policy/common/im/AdministrativeStateException.java
@@ -0,0 +1,37 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Integrity Monitor
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.policy.common.im;
+
+public class AdministrativeStateException extends Exception{
+ private static final long serialVersionUID = 1L;
+ public AdministrativeStateException() {
+ }
+ public AdministrativeStateException(String message) {
+ super(message);
+ }
+
+ public AdministrativeStateException(Throwable cause) {
+ super(cause);
+ }
+ public AdministrativeStateException(String message, Throwable cause) {
+ super(message, cause);
+ }
+}
diff --git a/integrity-monitor/src/main/java/org/openecomp/policy/common/im/ForwardProgressException.java b/integrity-monitor/src/main/java/org/openecomp/policy/common/im/ForwardProgressException.java
new file mode 100644
index 0000000..982f71a
--- /dev/null
+++ b/integrity-monitor/src/main/java/org/openecomp/policy/common/im/ForwardProgressException.java
@@ -0,0 +1,37 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Integrity Monitor
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.policy.common.im;
+
+public class ForwardProgressException extends Exception{
+ private static final long serialVersionUID = 1L;
+ public ForwardProgressException() {
+ }
+ public ForwardProgressException(String message) {
+ super(message);
+ }
+
+ public ForwardProgressException(Throwable cause) {
+ super(cause);
+ }
+ public ForwardProgressException(String message, Throwable cause) {
+ super(message, cause);
+ }
+}
diff --git a/integrity-monitor/src/main/java/org/openecomp/policy/common/im/IntegrityMonitor.java b/integrity-monitor/src/main/java/org/openecomp/policy/common/im/IntegrityMonitor.java
new file mode 100644
index 0000000..6c575ab
--- /dev/null
+++ b/integrity-monitor/src/main/java/org/openecomp/policy/common/im/IntegrityMonitor.java
@@ -0,0 +1,1300 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Integrity Monitor
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.policy.common.im;
+
+import java.net.InetAddress;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.List;
+import java.util.Properties;
+import java.util.concurrent.TimeUnit;
+
+import javax.management.JMX;
+import javax.management.MBeanServerConnection;
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.EntityTransaction;
+import javax.persistence.FlushModeType;
+import javax.persistence.LockModeType;
+import javax.persistence.Persistence;
+import javax.persistence.Query;
+
+//import org.apache.log4j.Logger;
+
+import org.openecomp.policy.common.im.jmx.*;
+import org.openecomp.policy.common.im.jpa.ForwardProgressEntity;
+import org.openecomp.policy.common.im.jpa.ResourceRegistrationEntity;
+import org.openecomp.policy.common.im.jpa.StateManagementEntity;
+import org.openecomp.policy.common.logging.flexlogger.FlexLogger;
+import org.openecomp.policy.common.logging.flexlogger.Logger;
+
+/**
+ * IntegrityMonitor
+ * Main class for monitoring the integrity of a resource and managing its state. State management follows
+ * the X.731 ITU standard.
+ */
+public class IntegrityMonitor {
+ private static final Logger logger = FlexLogger.getLogger(IntegrityMonitor.class.getName());
+
+ //private static final Map<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
index 0000000..8c3d7e6
--- /dev/null
+++ b/integrity-monitor/src/main/java/org/openecomp/policy/common/im/IntegrityMonitorProperties.java
@@ -0,0 +1,55 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Integrity Monitor
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.policy.common.im;
+
+public class IntegrityMonitorProperties {
+
+ public static final String DEFAULT_DB_DRIVER = "org.h2.Driver";
+ public static final String DEFAULT_DB_URL = "jdbc:h2:file:./sql/imTest";
+ public static final String DEFAULT_DB_USER = "sa";
+ public static final String DEFAULT_DB_PWD = "";
+
+ public static final String DB_DRIVER = "javax.persistence.jdbc.driver";
+ public static final String DB_URL = "javax.persistence.jdbc.url";
+ public static final String DB_USER = "javax.persistence.jdbc.user";
+ public static final String DB_PWD = "javax.persistence.jdbc.password";
+
+ // intervals specified are in seconds
+ public static final int DEFAULT_MONITOR_INTERVAL = 30;
+ public static final int DEFAULT_FAILED_COUNTER_THRESHOLD = 3;
+ public static final int DEFAULT_TEST_INTERVAL = 10; //20;
+ public static final int DEFAULT_WRITE_FPC_INTERVAL = 5;
+ public static final int DEFAULT_MAX_FPC_UPDATE_INTERVAL = 60;
+
+ public static final String FP_MONITOR_INTERVAL = "fp_monitor_interval";
+ public static final String FAILED_COUNTER_THRESHOLD = "failed_counter_threshold";
+ public static final String TEST_TRANS_INTERVAL = "test_trans_interval";
+ public static final String WRITE_FPC_INTERVAL = "write_fpc_interval";
+
+ public static final String DEPENDENCY_GROUPS = "dependency_groups";
+ public static final String SITE_NAME = "site_name";
+ public static final String NODE_TYPE = "node_type";
+
+ public static final String TEST_VIA_JMX = "test_via_jmx";
+ public static final String JMX_FQDN = "jmx_fqdn";
+ public static final String MAX_FPC_UPDATE_INTERVAL = "max_fpc_update_interval";
+
+}
diff --git a/integrity-monitor/src/main/java/org/openecomp/policy/common/im/IntegrityMonitorPropertiesException.java b/integrity-monitor/src/main/java/org/openecomp/policy/common/im/IntegrityMonitorPropertiesException.java
new file mode 100644
index 0000000..07737e1
--- /dev/null
+++ b/integrity-monitor/src/main/java/org/openecomp/policy/common/im/IntegrityMonitorPropertiesException.java
@@ -0,0 +1,37 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Integrity Monitor
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.policy.common.im;
+
+public class IntegrityMonitorPropertiesException extends Exception{
+ private static final long serialVersionUID = 1L;
+ public IntegrityMonitorPropertiesException() {
+ }
+ public IntegrityMonitorPropertiesException(String message) {
+ super(message);
+ }
+
+ public IntegrityMonitorPropertiesException(Throwable cause) {
+ super(cause);
+ }
+ public IntegrityMonitorPropertiesException(String message, Throwable cause) {
+ super(message, cause);
+ }
+}
diff --git a/integrity-monitor/src/main/java/org/openecomp/policy/common/im/StandbyStatusException.java b/integrity-monitor/src/main/java/org/openecomp/policy/common/im/StandbyStatusException.java
new file mode 100644
index 0000000..3167dde
--- /dev/null
+++ b/integrity-monitor/src/main/java/org/openecomp/policy/common/im/StandbyStatusException.java
@@ -0,0 +1,48 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Integrity Monitor
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.policy.common.im;
+
+public class StandbyStatusException extends Exception {
+ public StandbyStatusException()
+ {
+ }
+
+ public StandbyStatusException(String message)
+ {
+ super(message);
+ }
+
+ public StandbyStatusException(Throwable cause)
+ {
+ super(cause);
+ }
+
+ public StandbyStatusException(String message, Throwable cause)
+ {
+ super(message, cause);
+ }
+
+ public StandbyStatusException(String message, Throwable cause,
+ boolean enableSuppression, boolean writableStackTrace)
+ {
+ super(message, cause, enableSuppression, writableStackTrace);
+ }
+}
diff --git a/integrity-monitor/src/main/java/org/openecomp/policy/common/im/StateChangeNotifier.java b/integrity-monitor/src/main/java/org/openecomp/policy/common/im/StateChangeNotifier.java
new file mode 100644
index 0000000..8906bb7
--- /dev/null
+++ b/integrity-monitor/src/main/java/org/openecomp/policy/common/im/StateChangeNotifier.java
@@ -0,0 +1,76 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Integrity Monitor
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.policy.common.im;
+
+import java.util.Observable;
+import java.util.Observer;
+/*
+ * This is implementing the Observer interface to make it specific for
+ * state management.
+ *
+ * It saves the StateManagement object and a String message that is
+ * passed in when notifyObservers is called by the Observable
+ * host class.
+ *
+ * It provides an abstract method for handling the state change
+ * so this class must be overwritten and made concrete for the
+ * Observer who is monitoring the state changes.
+ */
+
+//import org.apache.log4j.Logger;
+import org.openecomp.policy.common.logging.flexlogger.FlexLogger;
+import org.openecomp.policy.common.logging.flexlogger.Logger;
+
+/**
+ *
+ * StateChangeNotifier class implements the Observer pattern and is used to distribute
+ * state change notifications to any entity that registers a derived class with an
+ * instance of the StateManagement class.
+ *
+ */
+public class StateChangeNotifier implements Observer {
+ private static final Logger logger = FlexLogger.getLogger(StateChangeNotifier.class);
+ //The observable class
+ StateManagement stateManagement;
+
+ // A string argument passed by the observable class when
+ // Observable:notifyObservers(Object arg) is called
+ String message;
+
+ @Override
+ public void update(Observable o, Object arg) {
+ this.stateManagement = (StateManagement) o;
+ this.message = (String) arg;
+ handleStateChange();
+ }
+
+ public void handleStateChange() {
+ logger.debug("handleStateChange, message: " + this.message);
+ }
+
+ public StateManagement getStateManagement() {
+ return stateManagement;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+} \ No newline at end of file
diff --git a/integrity-monitor/src/main/java/org/openecomp/policy/common/im/StateElement.java b/integrity-monitor/src/main/java/org/openecomp/policy/common/im/StateElement.java
new file mode 100644
index 0000000..6c6ce59
--- /dev/null
+++ b/integrity-monitor/src/main/java/org/openecomp/policy/common/im/StateElement.java
@@ -0,0 +1,160 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Integrity Monitor
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.policy.common.im;
+
+import java.util.*;
+
+//import org.apache.log4j.Logger;
+import org.openecomp.policy.common.logging.flexlogger.FlexLogger;
+import org.openecomp.policy.common.logging.flexlogger.Logger;
+
+public class StateElement {
+ private static final Logger logger = FlexLogger.getLogger(StateElement.class);
+
+ String adminState = null;
+ String opState = null;
+ String availStatus = null;
+ String standbyStatus = null;
+ String actionName = null;
+ String endingAdminState = null;
+ String endingOpState = null;
+ String endingAvailStatus = null;
+ String endingStandbyStatus = null;
+ String exception = null;
+
+ public void StateElement()
+ {
+ }
+
+ public String getAdminState()
+ {
+ return this.adminState;
+ }
+
+ public void setAdminState(String adminState)
+ {
+ this.adminState = adminState;
+ }
+
+ public String getOpState()
+ {
+ return this.opState;
+ }
+
+ public void setOpState(String opState)
+ {
+ this.opState = opState;
+ }
+
+ public String getAvailStatus()
+ {
+ return this.availStatus;
+ }
+
+ public void setAvailStatus(String availStatus)
+ {
+ this.availStatus = availStatus;
+ }
+
+ public String getStandbyStatus()
+ {
+ return this.standbyStatus;
+ }
+
+ public void setStandbyStatus(String standbyStatus)
+ {
+ this.standbyStatus = standbyStatus;
+ }
+
+ public String getActionName()
+ {
+ return this.actionName;
+ }
+
+ public void setActionName(String actionName)
+ {
+ this.actionName = actionName;
+ }
+
+ public String getEndingAdminState()
+ {
+ return this.endingAdminState;
+ }
+
+ public void setEndingAdminState(String endingAdminState)
+ {
+ this.endingAdminState = endingAdminState;
+ }
+
+ public String getEndingOpState()
+ {
+ return this.endingOpState;
+ }
+
+ public void setEndingOpState(String endingOpState)
+ {
+ this.endingOpState = endingOpState;
+ }
+
+ public String getEndingAvailStatus()
+ {
+ return this.endingAvailStatus;
+ }
+
+ public void setEndingAvailStatus(String endingAvailStatus)
+ {
+ this.endingAvailStatus = endingAvailStatus;
+ }
+
+ public String getEndingStandbyStatus()
+ {
+ return this.endingStandbyStatus;
+ }
+
+ public void setEndingStandbyStatus(String endingStandbyStatus)
+ {
+ this.endingStandbyStatus = endingStandbyStatus;
+ }
+
+ public String getException()
+ {
+ return this.exception;
+ }
+
+ public void setException(String exception)
+ {
+ this.exception = exception;
+ }
+
+ public void displayStateElement()
+ {
+ logger.debug("adminState=[" + getAdminState() +
+ "], opState=[" + getOpState() +
+ "], availStatus=[" + getAvailStatus() +
+ "], standbyStatus=[" + getStandbyStatus() +
+ "], actionName=[" + getActionName() +
+ "], endingAdminState=[" + getEndingAdminState() +
+ "], endingOpState=[" + getEndingOpState() +
+ "], endingAvailStatus=[" + getEndingAvailStatus() +
+ "], endingStandbyStatus=[" + getEndingStandbyStatus() +
+ "], exception=[" + getException() + "]");
+ }
+}
diff --git a/integrity-monitor/src/main/java/org/openecomp/policy/common/im/StateManagement.java b/integrity-monitor/src/main/java/org/openecomp/policy/common/im/StateManagement.java
new file mode 100644
index 0000000..14d35e1
--- /dev/null
+++ b/integrity-monitor/src/main/java/org/openecomp/policy/common/im/StateManagement.java
@@ -0,0 +1,1015 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Integrity Monitor
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.policy.common.im;
+
+import java.util.*;
+
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.EntityTransaction;
+import javax.persistence.FlushModeType;
+import javax.persistence.LockModeType;
+import javax.persistence.Query;
+
+//import org.apache.log4j.Logger;
+
+import org.openecomp.policy.common.im.jpa.StateManagementEntity;
+import org.openecomp.policy.common.im.StateElement;
+import org.openecomp.policy.common.im.StandbyStatusException;
+import org.openecomp.policy.common.im.StateChangeNotifier;
+import org.openecomp.policy.common.logging.flexlogger.FlexLogger;
+import org.openecomp.policy.common.logging.flexlogger.Logger;
+
+/**
+ *
+ * StateManagement class handles all state changes per the Telecom standard X.731.
+ * It extends the Observable class and, thus, has an interface to register
+ * instances of the StateChangeNotifier/Observer class. When any state change
+ * occurs, the registered observers are notified.
+ *
+ */
+public class StateManagement extends Observable {
+ private static final Logger logger = FlexLogger.getLogger(StateManagement.class);
+ public static final String LOCKED = "locked";
+ public static final String UNLOCKED = "unlocked";
+ public static final String ENABLED = "enabled";
+ public static final String DISABLED = "disabled";
+ public static final String ENABLE_NOT_FAILED = "enableNotFailed";
+ public static final String DISABLE_FAILED = "disableFailed";
+ public static final String FAILED = "failed";
+ public static final String DEPENDENCY = "dependency";
+ public static final String DEPENDENCY_FAILED = "dependency,failed";
+ public static final String DISABLE_DEPENDENCY = "disableDependency";
+ public static final String ENABLE_NO_DEPENDENCY = "enableNoDependency";
+ public static final String NULL_VALUE = "null";
+ public static final String LOCK = "lock";
+ public static final String UNLOCK = "unlock";
+ public static final String PROMOTE = "promote";
+ public static final String DEMOTE = "demote";
+ public static final String HOT_STANDBY = "hotstandby";
+ public static final String COLD_STANDBY = "coldstandby";
+ public static final String PROVIDING_SERVICE = "providingservice";
+
+ public static final String ADMIN_STATE = "adminState";
+ public static final String OPERATION_STATE = "opState";
+ public static final String AVAILABLE_STATUS= "availStatus";
+ public static final String STANDBY_STATUS = "standbyStatus";
+
+ private static final String REMOVE = "remove";
+ private static final String ADD = "add";
+
+ private String resourceName = null;
+ private String adminState = null;
+ private String opState = null;
+ private String availStatus = null;
+ private String standbyStatus = null;
+ private EntityManager em;
+ private EntityManagerFactory emf = null;
+ private StateTransition st = null;
+
+ /*
+ * Guarantees single-threadedness of all actions. Only one action can execute
+ * at a time. That avoids race conditions between actions being called
+ * from different places.
+ *
+ * Some actions can take significant time to complete and, if another conflicting
+ * action is called during its execution, it could put the system in an inconsistent
+ * state. This very thing happened when demote was called and the active/standby
+ * algorithm, seeing the state attempted to promote the PDP-D.
+ *
+ */
+ private static final Object SYNCLOCK = new Object();
+ private static final Object FLUSHLOCK = new Object();
+
+ /**
+ * StateManagement constructor
+ * @param emf
+ * @param resourceName
+ * @throws Exception
+ */
+ public StateManagement(EntityManagerFactory emf, String resourceName) throws Exception
+ {
+ logger.debug("StateManagement: constructor, resourceName: " + resourceName);
+ this.emf = emf;
+ em = emf.createEntityManager();
+ EntityTransaction et = em.getTransaction();
+
+ if(!et.isActive()){
+ et.begin();
+ }
+ this.resourceName = resourceName;
+ logger.info("resourceName = " + this.resourceName);
+
+
+ try {
+ //Create a StateManagementEntity object
+ logger.debug("findStateManagementEntity for " + this.resourceName);
+ StateManagementEntity sm = findStateManagementEntity(em, this.resourceName);
+
+ //persist the administrative state
+ if (sm != null) {
+ logger.debug("Persist adminstrative state, resourceName = " + this.resourceName);
+ em.persist(sm);
+ synchronized(FLUSHLOCK){
+ em.flush();
+ if(et.isActive()){
+ et.commit();
+ }
+ }
+ } else {
+ synchronized(FLUSHLOCK){
+ if(et.isActive()){
+ et.commit();
+ }
+ }
+ }
+
+ //Load the StateTransition hash table
+ st = new StateTransition();
+
+ logger.debug("StateManagement: constructor end, resourceName: " + this.resourceName);
+ } catch(Exception ex) {
+ synchronized(FLUSHLOCK){
+ if(et.isActive()){
+ et.commit();
+ }
+ }
+ ex.printStackTrace();
+ logger.error("StateManagement: constructor caught unexpected exception: " + ex);
+ throw new Exception("StateManagement: Exception: " + ex.toString());
+ }
+ }
+
+ /**
+ * initializeState() is called when it is necessary to set the StateManagement to a known initial state.
+ * It preserves the Administrative State since it must persist across node reboots.
+ * Starting from this state, the IntegrityMonitory will determine the Operational State and the
+ * owning application will set the StandbyStatus.
+ */
+ public void initializeState() throws Exception
+ {
+ synchronized (SYNCLOCK){
+ logger.debug("\nStateManagement: SYNCLOCK initializeState() operation for resourceName = " + this.resourceName + "\n");
+ logger.debug("StateManagement: initializeState() operation started, resourceName = " + this.resourceName);
+ EntityTransaction et = em.getTransaction();
+
+ if(!et.isActive()){
+ et.begin();
+ }
+
+ try {
+ logger.debug("findStateManagementEntity for " + this.resourceName);
+ StateManagementEntity sm = findStateManagementEntity(em, this.resourceName);
+ // set state
+ sm.setAdminState(sm.getAdminState()); //preserve the Admin state
+ sm.setOpState(StateManagement.ENABLED);
+ sm.setAvailStatus(StateManagement.NULL_VALUE);
+ sm.setStandbyStatus(StateManagement.NULL_VALUE);
+
+ em.persist(sm);
+ synchronized(FLUSHLOCK){
+ em.flush();
+ if(et.isActive()){
+ et.commit();
+ }
+ }
+ setChanged();
+ notifyObservers(ADMIN_STATE);
+
+ logger.debug("StateManagement: initializeState() operation completed, resourceName = " + this.resourceName);
+ } catch(Exception ex) {
+ synchronized(FLUSHLOCK){
+ if(et.isActive()){
+ et.commit();
+ }
+ }
+ ex.printStackTrace();
+ logger.error("StateManagement.initializeState() caught unexpected exception: " + ex);
+ throw new Exception("StateManagement.initializeState() Exception: " + ex);
+ }
+ }
+ }
+
+ /**
+ * lock() changes the administrative state to locked.
+ * @throws Exception
+ */
+ public void lock() throws Exception
+ {
+ synchronized (SYNCLOCK){
+ logger.debug("\nStateManagement: SYNCLOCK lock() operation for resourceName = " + this.resourceName + "\n");
+ logger.debug("StateManagement: lock() operation started, resourceName = " + this.resourceName);
+ EntityTransaction et = em.getTransaction();
+
+ if(!et.isActive()){
+ et.begin();
+ }
+
+ try {
+ logger.debug("findStateManagementEntity for " + this.resourceName);
+ StateManagementEntity sm = findStateManagementEntity(em, this.resourceName);
+
+ StateElement stateElement = st.getEndingState(sm.getAdminState(), sm.getOpState(),
+ sm.getAvailStatus(), sm.getStandbyStatus(), LOCK);
+
+ sm.setAdminState(stateElement.getEndingAdminState());
+ sm.setOpState(stateElement.getEndingOpState());
+ sm.setAvailStatus(stateElement.getEndingAvailStatus());
+ sm.setStandbyStatus(stateElement.getEndingStandbyStatus());
+
+ em.persist(sm);
+ synchronized(FLUSHLOCK){
+ em.flush();
+ if(et.isActive()){
+ et.commit();
+ }
+ }
+ setChanged();
+ notifyObservers(ADMIN_STATE);
+
+ logger.debug("StateManagement: lock() operation completed, resourceName = " + this.resourceName);
+ } catch(Exception ex) {
+ synchronized(FLUSHLOCK){
+ if(et.isActive()){
+ et.commit();
+ }
+ }
+ ex.printStackTrace();
+ logger.error("StateManagement.lock() caught unexpected exception: " + ex);
+ throw new Exception("StateManagement.lock() Exception: " + ex.toString());
+ }
+ }
+ }
+
+ /**
+ * unlock() changes the administrative state to unlocked.
+ * @throws Exception
+ */
+ public void unlock() throws Exception
+ {
+ synchronized (SYNCLOCK){
+ logger.debug("\nStateManagement: SYNCLOCK unlock() operation for resourceName = " + this.resourceName + "\n");
+ logger.debug("StateManagement: unlock() operation started, resourceName = " + this.resourceName);
+ EntityTransaction et = em.getTransaction();
+
+ if(!et.isActive()){
+ et.begin();
+ }
+
+ try {
+ logger.debug("findStateManagementEntity for " + this.resourceName);
+ StateManagementEntity sm = findStateManagementEntity(em, this.resourceName);
+ StateElement stateElement = st.getEndingState(sm.getAdminState(), sm.getOpState(),
+ sm.getAvailStatus(), sm.getStandbyStatus(), UNLOCK);
+ // set transition state
+ sm.setAdminState(stateElement.getEndingAdminState());
+ sm.setOpState(stateElement.getEndingOpState());
+ sm.setAvailStatus(stateElement.getEndingAvailStatus());
+ sm.setStandbyStatus(stateElement.getEndingStandbyStatus());
+
+ em.persist(sm);
+ synchronized(FLUSHLOCK){
+ em.flush();
+ if(et.isActive()){
+ et.commit();
+ }
+ }
+ setChanged();
+ notifyObservers(ADMIN_STATE);
+
+ logger.debug("StateManagement: unlock() operation completed, resourceName = " + this.resourceName);
+ } catch(Exception ex) {
+ synchronized(FLUSHLOCK){
+ if(et.isActive()){
+ et.commit();
+ }
+ }
+ ex.printStackTrace();
+ logger.error("StateManagement.unlock() caught unexpected exception: " + ex);
+ throw new Exception("StateManagement.unlock() Exception: " + ex);
+ }
+ }
+ }
+
+ /**
+ * enableNotFailed() removes the "failed" availability status and changes the operational
+ * state to enabled if no dependency is also failed.
+ * @throws Exception
+ */
+ public void enableNotFailed() throws Exception
+ {
+ synchronized (SYNCLOCK){
+ logger.debug("\nStateManagement: SYNCLOCK enabledNotFailed() operation for resourceName = " + this.resourceName + "\n");
+ logger.debug("StateManagement: enableNotFailed() operation started, resourceName = " + this.resourceName);
+ EntityTransaction et = em.getTransaction();
+
+ if(!et.isActive()){
+ et.begin();
+ }
+
+ try {
+ logger.debug("findStateManagementEntity for " + this.resourceName);
+ StateManagementEntity sm = findStateManagementEntity(em, this.resourceName);
+ StateElement stateElement = st.getEndingState(sm.getAdminState(), sm.getOpState(),
+ sm.getAvailStatus(), sm.getStandbyStatus(), ENABLE_NOT_FAILED);
+ // set transition state
+ sm.setAdminState(stateElement.getEndingAdminState());
+ sm.setOpState(stateElement.getEndingOpState());
+ sm.setAvailStatus(stateElement.getEndingAvailStatus());
+ sm.setStandbyStatus(stateElement.getEndingStandbyStatus());
+
+ em.persist(sm);
+ synchronized(FLUSHLOCK){
+ em.flush();
+ if(et.isActive()){
+ et.commit();
+ }
+ }
+ setChanged();
+ notifyObservers(OPERATION_STATE);
+
+ logger.debug("StateManagement enableNotFailed() operation completed, resourceName = " + this.resourceName);
+ } catch(Exception ex) {
+ synchronized(FLUSHLOCK){
+ if(et.isActive()){
+ et.commit();
+ }
+ }
+ ex.printStackTrace();
+ logger.error("StateManagement.enableNotFailed() caught unexpected exception: " + ex);
+ throw new Exception("StateManagement.enableNotFailed() Exception: " + ex);
+ }
+ }
+ }
+
+ /**
+ * disableFailed() changes the operational state to disabled and adds availability status of "failed"
+ * @throws Exception
+ */
+ public void disableFailed() throws Exception
+ {
+ synchronized (SYNCLOCK){
+ logger.debug("\nStateManagement: SYNCLOCK disabledFailed() operation for resourceName = " + this.resourceName + "\n");
+ logger.debug("StateManagement: disableFailed() operation started, resourceName = " + this.resourceName);
+ EntityTransaction et = em.getTransaction();
+ if(!et.isActive()){
+ et.begin();
+ }
+
+ try {
+ logger.debug("findStateManagementEntity for " + this.resourceName);
+ StateManagementEntity sm = findStateManagementEntity(em, this.resourceName);
+ StateElement stateElement = st.getEndingState(sm.getAdminState(), sm.getOpState(),
+ sm.getAvailStatus(), sm.getStandbyStatus(), DISABLE_FAILED);
+ // set transition state
+ sm.setAdminState(stateElement.getEndingAdminState());
+ sm.setOpState(stateElement.getEndingOpState());
+ sm.setAvailStatus(stateElement.getEndingAvailStatus());
+ sm.setStandbyStatus(stateElement.getEndingStandbyStatus());
+
+ em.persist(sm);
+ synchronized(FLUSHLOCK){
+ em.flush();
+ if(et.isActive()){
+ et.commit();
+ }
+ }
+ setChanged();
+ notifyObservers(OPERATION_STATE);
+
+ logger.debug("StateManagement: disableFailed() operation completed, resourceName = " + this.resourceName);
+ } catch(Exception ex) {
+ synchronized(FLUSHLOCK){
+ if(et.isActive()){
+ et.commit();
+ }
+ }
+ ex.printStackTrace();
+ logger.error("StateManagement.disableFailed() caught unexpected exception: " + ex);
+ throw new Exception("StateManagement.disableFailed() Exception: " + ex);
+ }
+ }
+ }
+ /**
+ * This version of disableFailed is to be used to manipulate the state of a remote resource in the event
+ * that remote resource has failed but its state is still showing that it is viable.
+ * @throws Exception
+ */
+ public void disableFailed(String otherResourceName) throws Exception
+ {
+ synchronized (SYNCLOCK){
+ if(otherResourceName == null){
+ logger.error("\nStateManagement: SYNCLOCK disableFailed(otherResourceName) operation: resourceName is NULL.\n");
+ return;
+ }
+ logger.debug("\nStateManagement: SYNCLOCK disabledFailed(otherResourceName) operation for resourceName = "
+ + otherResourceName + "\n");
+ logger.debug("StateManagement: disableFailed(otherResourceName) operation started, resourceName = "
+ + otherResourceName);
+ EntityTransaction et = em.getTransaction();
+ if(!et.isActive()){
+ et.begin();
+ }
+
+ try {
+ logger.debug("findStateManagementEntity for " + otherResourceName);
+ StateManagementEntity sm = findStateManagementEntity(em, otherResourceName);
+ StateElement stateElement = st.getEndingState(sm.getAdminState(), sm.getOpState(),
+ sm.getAvailStatus(), sm.getStandbyStatus(), DISABLE_FAILED);
+ // set transition state
+ sm.setAdminState(stateElement.getEndingAdminState());
+ sm.setOpState(stateElement.getEndingOpState());
+ sm.setAvailStatus(stateElement.getEndingAvailStatus());
+ sm.setStandbyStatus(stateElement.getEndingStandbyStatus());
+
+ em.persist(sm);
+ synchronized(FLUSHLOCK){
+ em.flush();
+ if(et.isActive()){
+ et.commit();
+ }
+ }
+ setChanged();
+ notifyObservers(OPERATION_STATE);
+
+ logger.debug("StateManagement: disableFailed(otherResourceName) operation completed, resourceName = "
+ + otherResourceName);
+ } catch(Exception ex) {
+ synchronized(FLUSHLOCK){
+ if(et.isActive()){
+ et.commit();
+ }
+ }
+ ex.printStackTrace();
+ logger.error("StateManagement.disableFailed(otherResourceName) caught unexpected exception: " + ex);
+ throw new Exception("StateManagement.disableFailed(otherResourceName) Exception: " + ex);
+ }
+ }
+ }
+
+ /**
+ * disableDependency() changes operational state to disabled and adds availability status of "dependency"
+ * @throws Exception
+ */
+ public void disableDependency() throws Exception
+ {
+ synchronized (SYNCLOCK){
+ logger.debug("\nStateManagement: SYNCLOCK disableDependency() operation for resourceName = " + this.resourceName + "\n");
+ logger.debug("StateManagement: disableDependency() operation started, resourceName = " + this.resourceName);
+ EntityTransaction et = em.getTransaction();
+
+ if(!et.isActive()){
+ et.begin();
+ }
+
+ try {
+ logger.debug("findStateManagementEntity for " + this.resourceName);
+ StateManagementEntity sm = findStateManagementEntity(em, this.resourceName);
+ StateElement stateElement = st.getEndingState(sm.getAdminState(), sm.getOpState(),
+ sm.getAvailStatus(), sm.getStandbyStatus(), DISABLE_DEPENDENCY);
+ // set transition state
+ sm.setAdminState(stateElement.getEndingAdminState());
+ sm.setOpState(stateElement.getEndingOpState());
+ sm.setAvailStatus(stateElement.getEndingAvailStatus());
+ sm.setStandbyStatus(stateElement.getEndingStandbyStatus());
+
+ em.persist(sm);
+ synchronized(FLUSHLOCK){
+ em.flush();
+ if(et.isActive()){
+ et.commit();
+ }
+ }
+ setChanged();
+ notifyObservers(OPERATION_STATE);
+
+ logger.debug("StateManagement: disableDependency() operation completed, resourceName = " + this.resourceName);
+ } catch(Exception ex) {
+ synchronized(FLUSHLOCK){
+ if(et.isActive()){
+ et.commit();
+ }
+ }
+ ex.printStackTrace();
+ logger.error("StateManagement.disableDependency() caught unexpected exception: " + ex);
+ throw new Exception("StateManagement.disableDependency() Exception: " + ex);
+ }
+ }
+ }
+
+ /**
+ * enableNoDependency() removes the availability status of "dependency " and will change the
+ * operational state to enabled if not otherwise failed.
+ * @throws Exception
+ */
+ public void enableNoDependency() throws Exception
+ {
+ synchronized (SYNCLOCK){
+ logger.debug("\nStateManagement: SYNCLOCK enableNoDependency() operation for resourceName = " + this.resourceName + "\n");
+ logger.debug("StateManagement: enableNoDependency() operation started, resourceName = " + this.resourceName);
+ EntityTransaction et = em.getTransaction();
+
+ if(!et.isActive()){
+ et.begin();
+ }
+
+ try {
+ logger.debug("findStateManagementEntity for " + this.resourceName);
+ StateManagementEntity sm = findStateManagementEntity(em, this.resourceName);
+ StateElement stateElement = st.getEndingState(sm.getAdminState(), sm.getOpState(),
+ sm.getAvailStatus(), sm.getStandbyStatus(), ENABLE_NO_DEPENDENCY);
+ // set transition state
+ sm.setAdminState(stateElement.getEndingAdminState());
+ sm.setOpState(stateElement.getEndingOpState());
+ sm.setAvailStatus(stateElement.getEndingAvailStatus());
+ sm.setStandbyStatus(stateElement.getEndingStandbyStatus());
+
+ em.persist(sm);
+ synchronized(FLUSHLOCK){
+ em.flush();
+ if(et.isActive()){
+ et.commit();
+ }
+ }
+ setChanged();
+ notifyObservers(OPERATION_STATE);
+
+ logger.debug("StateManagement: enableNoDependency() operation completed, resourceName = " + this.resourceName);
+ } catch(Exception ex) {
+ synchronized(FLUSHLOCK){
+ if(et.isActive()){
+ et.commit();
+ }
+ }
+ ex.printStackTrace();
+ logger.error("StateManagement.enableNoDependency() caught unexpected exception: " + ex);
+ throw new Exception("StateManagement.enableNoDependency() Exception: " + ex);
+ }
+ }
+ }
+
+ /**
+ * promote() changes the standby status to providingservice if not otherwise failed.
+ * @throws StandbyStatusException
+ * @throws Exception
+ */
+ public void promote() throws StandbyStatusException, Exception
+ {
+ synchronized (SYNCLOCK){
+ logger.debug("\nStateManagement: SYNCLOCK promote() operation for resourceName = " + this.resourceName + "\n");
+ logger.debug("StateManagement: promote() operation started, resourceName = " + this.resourceName);
+ EntityTransaction et = em.getTransaction();
+
+ if(!et.isActive()){
+ et.begin();
+ }
+
+ StateManagementEntity sm;
+
+ try{
+ logger.debug("findStateManagementEntity for " + this.resourceName);
+ sm = findStateManagementEntity(em, this.resourceName);
+ StateElement stateElement = st.getEndingState(sm.getAdminState(), sm.getOpState(),
+ sm.getAvailStatus(), sm.getStandbyStatus(), PROMOTE);
+ // set transition state
+ sm.setAdminState(stateElement.getEndingAdminState());
+ sm.setOpState(stateElement.getEndingOpState());
+ sm.setAvailStatus(stateElement.getEndingAvailStatus());
+ sm.setStandbyStatus(stateElement.getEndingStandbyStatus());
+
+ em.persist(sm);
+ synchronized(FLUSHLOCK){
+ em.flush();
+ if(et.isActive()){
+ et.commit();
+ }
+ }
+ setChanged();
+ notifyObservers(STANDBY_STATUS);
+ }catch(Exception ex){
+ synchronized(FLUSHLOCK){
+ if(et.isActive()){
+ et.commit();
+ }
+ }
+ ex.printStackTrace();
+ logger.error("StateManagement.promote() caught unexpected exception: " + ex);
+ throw new Exception("StateManagement.promote() Exception: " + ex);
+ }
+
+ logger.debug("StateManagement: promote() operation completed, resourceName = " + this.resourceName);
+ if (sm.getStandbyStatus().equals(StateManagement.COLD_STANDBY)){
+ String msg = "Failure to promote " + this.resourceName + " StandbyStatus = " + StateManagement.COLD_STANDBY;
+ throw new StandbyStatusException(msg);
+ }
+ }
+ }
+
+ /**
+ * demote() changes standbystatus to hotstandby or, if failed, coldstandby
+ * @throws Exception
+ */
+ public void demote() throws Exception
+ {
+ synchronized (SYNCLOCK){
+ logger.debug("\nStateManagement: SYNCLOCK demote() operation for resourceName = " + this.resourceName + "\n");
+ logger.debug("StateManagement: demote() operation started, resourceName = " + this.resourceName);
+ EntityTransaction et = em.getTransaction();
+
+ if(!et.isActive()){
+ et.begin();
+ }
+
+ try {
+ logger.debug("findStateManagementEntity for " + this.resourceName);
+ StateManagementEntity sm = findStateManagementEntity(em, this.resourceName);
+ StateElement stateElement = st.getEndingState(sm.getAdminState(), sm.getOpState(),
+ sm.getAvailStatus(), sm.getStandbyStatus(), DEMOTE);
+ // set transition state
+ sm.setAdminState(stateElement.getEndingAdminState());
+ sm.setOpState(stateElement.getEndingOpState());
+ sm.setAvailStatus(stateElement.getEndingAvailStatus());
+ sm.setStandbyStatus(stateElement.getEndingStandbyStatus());
+
+ em.persist(sm);
+ synchronized(FLUSHLOCK){
+ em.flush();
+ if(et.isActive()){
+ et.commit();
+ }
+ }
+ setChanged();
+ notifyObservers(STANDBY_STATUS);
+
+ logger.debug("StateManagement: demote() operation completed, resourceName = " + this.resourceName);
+ } catch(Exception ex) {
+ synchronized(FLUSHLOCK){
+ if(et.isActive()){
+ et.commit();
+ }
+ }
+ ex.printStackTrace();
+ logger.error("StateManagement.demote() caught unexpected exception: " + ex);
+ throw new Exception("StateManagement.demote() Exception: " + ex);
+ }
+ }
+ }
+
+ /**
+ *
+ * Only used for a remote resource. It will not notify observers. It is used only in cases where
+ * the remote resource has failed is such a way that it cannot update its own states. In particular
+ * this is observed by PDP-D DroolsPdpsElectionHandler when it is trying to determine which PDP-D should
+ * be designated as the lead.
+ * @param otherResourceName
+ * @throws Exception
+ */
+ public void demote(String otherResourceName) throws Exception
+ {
+ synchronized (SYNCLOCK){
+ if(otherResourceName==null){
+ logger.error("\nStateManagement: SYNCLOCK demote(otherResourceName) operation: resourceName is NULL.\n");
+ return;
+ }
+ logger.debug("\nStateManagement: SYNCLOCK demote(otherResourceName) operation for resourceName = " + otherResourceName + "\n");
+
+ EntityTransaction et = em.getTransaction();
+
+ if(!et.isActive()){
+ et.begin();
+ }
+
+ try {
+ logger.debug("StateManagement: SYNCLOCK demote(otherResourceName) findStateManagementEntity for " + otherResourceName);
+ StateManagementEntity sm = findStateManagementEntity(em, otherResourceName);
+ StateElement stateElement = st.getEndingState(sm.getAdminState(), sm.getOpState(),
+ sm.getAvailStatus(), sm.getStandbyStatus(), DEMOTE);
+ // set transition state
+ sm.setAdminState(stateElement.getEndingAdminState());
+ sm.setOpState(stateElement.getEndingOpState());
+ sm.setAvailStatus(stateElement.getEndingAvailStatus());
+ sm.setStandbyStatus(stateElement.getEndingStandbyStatus());
+
+ em.persist(sm);
+ synchronized(FLUSHLOCK){
+ em.flush();
+ if(et.isActive()){
+ et.commit();
+ }
+ }
+ //We don't notify observers because this is assumed to be a remote resource
+
+ logger.debug("StateManagement: demote(otherResourceName) operation completed, resourceName = " + otherResourceName);
+ } catch(Exception ex) {
+ synchronized(FLUSHLOCK){
+ if(et.isActive()){
+ et.commit();
+ }
+ }
+ ex.printStackTrace();
+ logger.error("StateManagement.demote(otherResourceName) caught unexpected exception: " + ex);
+ throw new Exception("StateManagement.demote(otherResourceName) Exception: " + ex);
+ }
+ }
+ }
+
+ /**
+ * @return
+ */
+public String getAdminState()
+ {
+ logger.debug("StateManagement(6/1/16): getAdminState for resourceName " + this.resourceName);
+ try {
+ Query query = em.createQuery("Select p from StateManagementEntity p where p.resourceName=:resource");
+
+ query.setParameter("resource", this.resourceName);
+
+ //Just test that we are retrieving the right object
+ @SuppressWarnings("rawtypes")
+ List resourceList = query.setLockMode(
+ LockModeType.NONE).setFlushMode(FlushModeType.COMMIT).getResultList();
+ if (!resourceList.isEmpty()) {
+ // exist
+ StateManagementEntity stateManagementEntity = (StateManagementEntity) resourceList.get(0);
+ // refresh the object from DB in case cached data was returned
+ em.refresh(stateManagementEntity);
+ this.adminState = stateManagementEntity.getAdminState();
+ } else {
+ this.adminState = null;
+ }
+ } catch(Exception ex) {
+ ex.printStackTrace();
+ logger.error("StateManagement: getAdminState exception: " + ex.toString());
+ }
+
+ return this.adminState;
+ }
+
+ /**
+ * @return
+ */
+public String getOpState()
+ {
+ logger.debug("StateManagement(6/1/16): getOpState for resourceName " + this.resourceName);
+ try {
+ Query query = em.createQuery("Select p from StateManagementEntity p where p.resourceName=:resource");
+
+ query.setParameter("resource", this.resourceName);
+
+ //Just test that we are retrieving the right object
+ @SuppressWarnings("rawtypes")
+ List resourceList = query.setLockMode(
+ LockModeType.NONE).setFlushMode(FlushModeType.COMMIT).getResultList();
+ if (!resourceList.isEmpty()) {
+ // exist
+ StateManagementEntity stateManagementEntity = (StateManagementEntity) resourceList.get(0);
+ // refresh the object from DB in case cached data was returned
+ em.refresh(stateManagementEntity);
+ this.opState = stateManagementEntity.getOpState();
+ } else {
+ this.opState = null;
+ }
+ } catch(Exception ex) {
+ ex.printStackTrace();
+ logger.error("StateManagement: getOpState exception: " + ex.toString());
+ }
+
+ return this.opState;
+ }
+
+ /**
+ * @return
+ */
+ public String getAvailStatus()
+ {
+ logger.debug("StateManagement(6/1/16): getAvailStatus for resourceName " + this.resourceName);
+ try {
+ Query query = em.createQuery("Select p from StateManagementEntity p where p.resourceName=:resource");
+
+ query.setParameter("resource", this.resourceName);
+
+ //Just test that we are retrieving the right object
+ @SuppressWarnings("rawtypes")
+ List resourceList = query.setLockMode(
+ LockModeType.NONE).setFlushMode(FlushModeType.COMMIT).getResultList();
+ if (!resourceList.isEmpty()) {
+ // exist
+ StateManagementEntity stateManagementEntity = (StateManagementEntity) resourceList.get(0);
+ // refresh the object from DB in case cached data was returned
+ em.refresh(stateManagementEntity);
+ this.availStatus = stateManagementEntity.getAvailStatus();
+ } else {
+ this.availStatus = null;
+ }
+ } catch(Exception ex) {
+ ex.printStackTrace();
+ logger.error("StateManagement: getAvailStatus exception: " + ex.toString());
+ }
+
+ return this.availStatus;
+ }
+
+ /**
+ * @return
+ */
+ public String getStandbyStatus()
+ {
+ logger.debug("StateManagement(6/1/16): getStandbyStatus for resourceName " + this.resourceName);
+ try {
+ Query query = em.createQuery("Select p from StateManagementEntity p where p.resourceName=:resource");
+
+ query.setParameter("resource", this.resourceName);
+
+ //Just test that we are retrieving the right object
+ @SuppressWarnings("rawtypes")
+ List resourceList = query.setLockMode(
+ LockModeType.NONE).setFlushMode(FlushModeType.COMMIT).getResultList();
+ if (!resourceList.isEmpty()) {
+ // exist
+ StateManagementEntity stateManagementEntity = (StateManagementEntity) resourceList.get(0);
+ // refresh the object from DB in case cached data was returned
+ em.refresh(stateManagementEntity);
+ this.standbyStatus = stateManagementEntity.getStandbyStatus();
+ } else {
+ this.standbyStatus = null;
+ }
+ } catch(Exception ex) {
+ ex.printStackTrace();
+ logger.error("StateManagement: getStandbyStatus exception: " + ex.toString());
+ }
+
+ return this.standbyStatus;
+ }
+
+ /**
+ * Find a StateManagementEntity
+ * @param em
+ * @param otherResourceName
+ * @return
+ */
+ private static StateManagementEntity findStateManagementEntity(EntityManager em, String otherResourceName)
+ {
+ logger.debug("StateManagementEntity: findStateManagementEntity: Entry");
+ StateManagementEntity stateManagementEntity = null;
+ try {
+ Query query = em.createQuery("Select p from StateManagementEntity p where p.resourceName=:resource");
+
+ query.setParameter("resource", otherResourceName);
+
+ //Just test that we are retrieving the right object
+ @SuppressWarnings("rawtypes")
+ List resourceList = query.setLockMode(
+ LockModeType.NONE).setFlushMode(FlushModeType.COMMIT).getResultList();
+ if (!resourceList.isEmpty()) {
+ // exist
+ stateManagementEntity = (StateManagementEntity) resourceList.get(0);
+ // refresh the object from DB in case cached data was returned
+ em.refresh(stateManagementEntity);
+ stateManagementEntity.setModifiedDate(new Date());
+ } else {
+ // not exist - create one
+ stateManagementEntity = new StateManagementEntity();
+ stateManagementEntity.setResourceName(otherResourceName);
+ stateManagementEntity.setAdminState(UNLOCKED);
+ stateManagementEntity.setOpState(ENABLED);
+ stateManagementEntity.setAvailStatus(NULL_VALUE);
+ stateManagementEntity.setStandbyStatus(NULL_VALUE); // default
+ }
+ } catch(Exception ex) {
+ ex.printStackTrace();
+ logger.error("findStateManagementEntity exception: " + ex.toString());
+ }
+ return stateManagementEntity;
+ }
+
+ /**
+ * Get the standbystatus of a particular resource
+ * @param otherResourceName
+ * @return
+ */
+ public String getStandbyStatus(String otherResourceName) {
+
+ if (logger.isDebugEnabled()) {
+ logger.debug("StateManagement: getStandbyStatus: Entering, resourceName='"
+ + otherResourceName + "'");
+ }
+
+ String standbyStatus = null;
+
+ EntityTransaction et = em.getTransaction();
+ if(!et.isActive()){
+ et.begin();
+ }
+ try {
+
+ Query stateManagementListQuery = em
+ .createQuery("SELECT p FROM StateManagementEntity p WHERE p.resourceName=:resource");
+ stateManagementListQuery.setParameter("resource", otherResourceName);
+ List<?> stateManagementList = stateManagementListQuery.setLockMode(
+ LockModeType.NONE).setFlushMode(FlushModeType.COMMIT).getResultList();
+ if (stateManagementList.size() == 1
+ && stateManagementList.get(0) instanceof StateManagementEntity) {
+ StateManagementEntity stateManagementEntity = (StateManagementEntity) stateManagementList
+ .get(0);
+ // refresh the object from DB in case cached data was returned
+ em.refresh(stateManagementEntity);
+ standbyStatus = stateManagementEntity.getStandbyStatus();
+ if (logger.isDebugEnabled()) {
+ logger.debug("getStandbyStatus: resourceName =" + otherResourceName
+ + " has standbyStatus=" + standbyStatus);
+ }
+ } else {
+ logger.error("getStandbyStatus: resourceName =" + otherResourceName
+ + " not found in statemanagemententity table");
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ logger.error("getStandbyStatus: Caught Exception attempting to get statemanagemententity record, message='"
+ + e.getMessage() + "'");
+ }
+ synchronized(FLUSHLOCK){
+ if(et.isActive()){
+ et.commit();
+ }
+ }
+
+ if (logger.isDebugEnabled()) {
+ logger.debug("getStandbyStatus: Returning standbyStatus="
+ + standbyStatus);
+ }
+
+ return standbyStatus;
+ }
+
+ /**
+ * Clean up all the StateManagementEntities
+ */
+ public void deleteAllStateManagementEntities() {
+
+ logger.info("StateManagement: deleteAllStateManagementEntities: Entering");
+
+ /*
+ * Start transaction
+ */
+ EntityTransaction et = em.getTransaction();
+ if(!et.isActive()){
+ et.begin();
+ }
+
+ try{
+ Query stateManagementEntityListQuery = em
+ .createQuery("SELECT p FROM StateManagementEntity p");
+ @SuppressWarnings("unchecked")
+ List<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
index 0000000..3bc5bbc
--- /dev/null
+++ b/integrity-monitor/src/main/java/org/openecomp/policy/common/im/StateTransition.java
@@ -0,0 +1,726 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Integrity Monitor
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.policy.common.im;
+
+import java.util.*;
+
+//import org.apache.log4j.Logger;
+
+import org.openecomp.policy.common.im.StateElement;
+import org.openecomp.policy.common.im.StateManagement;
+import org.openecomp.policy.common.logging.flexlogger.FlexLogger;
+import org.openecomp.policy.common.logging.flexlogger.Logger;
+
+/**
+ * The StateTransition class coordinates all state transitions.
+ */
+public class StateTransition {
+ private static final Logger logger = FlexLogger.getLogger(StateTransition.class);
+
+ public static final String ADMIN_STATE = "adminState";
+ public static final String OPERATION_STATE = "opState";
+ public static final String AVAILABLE_STATUS= "availStatus";
+ public static final String STANDBY_STATUS = "standbyStatus";
+ public static final String ACTOIN_NAME = "actionName";
+
+ private HashMap<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,p