aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--LICENSE.txt2
-rw-r--r--docker_build.sh4
-rw-r--r--docker_merge.sh4
-rw-r--r--docker_verify.sh2
-rw-r--r--feature-distributed-locking/pom.xml130
-rw-r--r--feature-distributed-locking/src/assembly/assemble_zip.xml75
-rw-r--r--feature-distributed-locking/src/main/feature/config/feature-distributed-locking.properties34
-rw-r--r--feature-distributed-locking/src/main/feature/db/pooling/sql/1804-distributedlocking.downgrade.sql20
-rw-r--r--feature-distributed-locking/src/main/feature/db/pooling/sql/1804-distributedlocking.upgrade.sql23
-rw-r--r--feature-distributed-locking/src/main/java/org/onap/policy/distributed/locking/DistributedLockingFeature.java158
-rw-r--r--feature-distributed-locking/src/main/java/org/onap/policy/distributed/locking/DistributedLockingFeatureException.java (renamed from policy-utils/src/test/java/org/onap/policy/drools/utils/LoggerUtilTest.java)23
-rw-r--r--feature-distributed-locking/src/main/java/org/onap/policy/distributed/locking/DistributedLockingProperties.java127
-rw-r--r--feature-distributed-locking/src/main/java/org/onap/policy/distributed/locking/Heartbeat.java78
-rw-r--r--feature-distributed-locking/src/main/java/org/onap/policy/distributed/locking/TargetLock.java233
-rw-r--r--feature-distributed-locking/src/main/resources/META-INF/services/org.onap.policy.drools.core.lock.PolicyResourceLockFeatureAPI1
-rw-r--r--feature-distributed-locking/src/main/resources/META-INF/services/org.onap.policy.drools.features.PolicyEngineFeatureAPI1
-rw-r--r--feature-distributed-locking/src/test/java/org/onap/policy/distributed/locking/test/DistributedLockingFeatureExceptionTest.java36
-rw-r--r--feature-distributed-locking/src/test/java/org/onap/policy/distributed/locking/test/TargetLockTest.java220
-rw-r--r--feature-distributed-locking/src/test/resources/feature-distributed-locking.properties26
-rw-r--r--feature-eelf/src/main/feature/config/logback-eelf.xml10
-rw-r--r--feature-simulators/src/test/java/org/onap/policy/drools/simulators/DMaaPSimulatorTest.java6
-rw-r--r--packages/base/src/files/etc/profile.d/env.sh3
-rw-r--r--packages/docker/pom.xml4
-rw-r--r--packages/docker/src/main/docker/Dockerfile26
-rw-r--r--packages/docker/src/main/docker/do-start.sh27
-rw-r--r--packages/docker/src/main/docker/docker-install.sh40
-rw-r--r--packages/install/src/files/base.conf3
-rw-r--r--policy-core/src/main/java/org/onap/policy/drools/core/lock/LockRequestFuture.java261
-rw-r--r--policy-core/src/main/java/org/onap/policy/drools/core/lock/PolicyResourceLockFeatureAPI.java190
-rw-r--r--policy-endpoints/src/main/java/org/onap/policy/drools/http/server/internal/JettyJerseyServer.java9
-rw-r--r--policy-management/src/main/java/org/onap/policy/drools/server/restful/RestManager.java2
-rw-r--r--policy-management/src/main/java/org/onap/policy/drools/system/Main.java38
-rw-r--r--policy-management/src/main/java/org/onap/policy/drools/system/PolicyEngine.java54
-rw-r--r--policy-management/src/main/server-gen/bin/policy-management-controller20
-rw-r--r--policy-management/src/main/server/config/logback.xml89
-rw-r--r--policy-utils/src/main/java/org/onap/policy/drools/utils/LoggerUtil.java58
-rw-r--r--policy-utils/src/main/java/org/onap/policy/drools/utils/NetworkUtil.java112
-rw-r--r--policy-utils/src/main/java/org/onap/policy/drools/utils/logging/LoggerMarkerFilter.java77
-rw-r--r--policy-utils/src/main/java/org/onap/policy/drools/utils/logging/LoggerUtil.java83
-rw-r--r--policy-utils/src/main/java/org/onap/policy/drools/utils/logging/MDCTransaction.java1194
-rw-r--r--policy-utils/src/test/java/org/onap/policy/drools/utils/NetworkUtilTest.java2
-rw-r--r--policy-utils/src/test/java/org/onap/policy/drools/utils/logging/LoggerUtilTest.java56
-rw-r--r--policy-utils/src/test/java/org/onap/policy/drools/utils/logging/MDCTransactionTest.java265
-rw-r--r--policy-utils/src/test/resources/logback-test.xml36
-rw-r--r--pom.xml3
45 files changed, 3635 insertions, 230 deletions
diff --git a/LICENSE.txt b/LICENSE.txt
index 0b6bee52..929e9686 100644
--- a/LICENSE.txt
+++ b/LICENSE.txt
@@ -12,5 +12,3 @@ 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 is a trademark and service mark of AT&T Intellectual Property.
diff --git a/docker_build.sh b/docker_build.sh
index 1168a2a8..a7e79db6 100644
--- a/docker_build.sh
+++ b/docker_build.sh
@@ -58,7 +58,7 @@ TAGS="${TAGS} --tag ${DOCKER_REPOSITORY}/onap/${IMAGE}:${MVN_MAJMIN_VERSION}-lat
#
# This has the nexus repo prepended and major/minor/patch version with timestamp
#
-TAGS="${TAGS} --tag ${DOCKER_REPOSITORY}/onap/${IMAGE}:${MVN_VERSION}-STAGING-${TIMESTAMP}"
+TAGS="${TAGS} --tag ${DOCKER_REPOSITORY}/onap/${IMAGE}:${MVN_VERSION}-STAGING-${TIMESTAMP}Z"
echo $TAGS
@@ -92,7 +92,7 @@ then
exit 1
fi
-docker push ${DOCKER_REPOSITORY}/onap/${IMAGE}:${MVN_VERSION}-STAGING-${TIMESTAMP}
+docker push ${DOCKER_REPOSITORY}/onap/${IMAGE}:${MVN_VERSION}-STAGING-${TIMESTAMP}Z
if [ $? -ne 0 ]
then
diff --git a/docker_merge.sh b/docker_merge.sh
index bd2b99bc..2175d714 100644
--- a/docker_merge.sh
+++ b/docker_merge.sh
@@ -54,7 +54,7 @@ TAGS="${TAGS} --tag ${DOCKER_REPOSITORY}/onap/${IMAGE}:${MVN_MAJMIN_VERSION}-lat
#
# This has the nexus repo prepended and major/minor/patch version with timestamp
#
-TAGS="${TAGS} --tag ${DOCKER_REPOSITORY}/onap/${IMAGE}:${MVN_VERSION}-${TIMESTAMP}"
+TAGS="${TAGS} --tag ${DOCKER_REPOSITORY}/onap/${IMAGE}:${MVN_VERSION}-${TIMESTAMP}Z"
echo $TAGS
@@ -81,7 +81,7 @@ then
exit 1
fi
-docker push ${DOCKER_REPOSITORY}/onap/$IMAGE:${MVN_VERSION}-${TIMESTAMP}
+docker push ${DOCKER_REPOSITORY}/onap/$IMAGE:${MVN_VERSION}-${TIMESTAMP}Z
if [ $? -ne 0 ]
then
diff --git a/docker_verify.sh b/docker_verify.sh
index 99043f62..2e2c7110 100644
--- a/docker_verify.sh
+++ b/docker_verify.sh
@@ -57,7 +57,7 @@ TAGS="${TAGS} --tag ${DOCKER_REPOSITORY}/onap/${IMAGE}:${MVN_MAJMIN_VERSION}-lat
#
# This has the nexus repo prepended and major/minor/patch version with timestamp
#
-TAGS="${TAGS} --tag ${DOCKER_REPOSITORY}/onap/${IMAGE}:${MVN_VERSION}-${TIMESTAMP}"
+TAGS="${TAGS} --tag ${DOCKER_REPOSITORY}/onap/${IMAGE}:${MVN_VERSION}-${TIMESTAMP}Z"
echo $TAGS
diff --git a/feature-distributed-locking/pom.xml b/feature-distributed-locking/pom.xml
new file mode 100644
index 00000000..c4beacc2
--- /dev/null
+++ b/feature-distributed-locking/pom.xml
@@ -0,0 +1,130 @@
+<!--
+ ============LICENSE_START=======================================================
+ ONAP Policy Engine - Drools PDP
+ ================================================================================
+ Copyright (C) 2018 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.onap.policy.drools-pdp</groupId>
+ <artifactId>drools-pdp</artifactId>
+ <version>1.2.0-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>feature-distributed-locking</artifactId>
+
+ <name>feature-distributed-locking</name>
+ <description>Loadable module that provides distributed locking capability</description>
+
+ <properties>
+ <maven.compiler.source>1.8</maven.compiler.source>
+ <maven.compiler.target>1.8</maven.compiler.target>
+ </properties>
+
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-assembly-plugin</artifactId>
+ <version>2.6</version>
+ <executions>
+ <execution>
+ <id>zipfile</id>
+ <goals>
+ <goal>single</goal>
+ </goals>
+ <phase>package</phase>
+ <configuration>
+ <attach>true</attach>
+ <finalName>${project.artifactId}-${project.version}</finalName>
+ <descriptors>
+ <descriptor>src/assembly/assemble_zip.xml</descriptor>
+ </descriptors>
+ <appendAssemblyId>false</appendAssemblyId>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <version>2.8</version>
+ <executions>
+ <execution>
+ <id>copy-dependencies</id>
+ <goals>
+ <goal>copy-dependencies</goal>
+ </goals>
+ <phase>prepare-package</phase>
+ <configuration>
+ <transitive>false</transitive>
+ <outputDirectory>${project.build.directory}/assembly/lib</outputDirectory>
+ <overWriteReleases>false</overWriteReleases>
+ <overWriteSnapshots>true</overWriteSnapshots>
+ <overWriteIfNewer>true</overWriteIfNewer>
+ <useRepositoryLayout>false</useRepositoryLayout>
+ <addParentPoms>false</addParentPoms>
+ <copyPom>false</copyPom>
+ <includeScope>runtime</includeScope>
+ <excludeTransitive>true</excludeTransitive>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.onap.policy.drools-pdp</groupId>
+ <artifactId>policy-core</artifactId>
+ <version>${project.version}</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.onap.policy.drools-pdp</groupId>
+ <artifactId>policy-management</artifactId>
+ <version>${project.version}</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.h2database</groupId>
+ <artifactId>h2</artifactId>
+ <version>[1.4.186,)</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.onap.policy.common</groupId>
+ <artifactId>utils</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.onap.policy.common</groupId>
+ <artifactId>utils-test</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ </dependencies>
+
+</project>
diff --git a/feature-distributed-locking/src/assembly/assemble_zip.xml b/feature-distributed-locking/src/assembly/assemble_zip.xml
new file mode 100644
index 00000000..2112fbcd
--- /dev/null
+++ b/feature-distributed-locking/src/assembly/assemble_zip.xml
@@ -0,0 +1,75 @@
+<!--
+ ============LICENSE_START=======================================================
+ feature-distributed-locking
+ ================================================================================
+ Copyright (C) 2018 AT&T Intellectual Property. All rights reserved.
+ ================================================================================
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ============LICENSE_END=========================================================
+ -->
+
+<!-- Defines how we build the .zip file which is our distribution. -->
+
+<assembly
+ xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
+ <id>feature-distributed-locking</id>
+ <formats>
+ <format>zip</format>
+ </formats>
+
+ <includeBaseDirectory>false</includeBaseDirectory>
+
+ <fileSets>
+ <fileSet>
+ <directory>target</directory>
+ <outputDirectory>lib/feature</outputDirectory>
+ <includes>
+ <include>feature-distributed-locking-${project.version}.jar</include>
+ </includes>
+ </fileSet>
+ <fileSet>
+ <directory>target/assembly/lib</directory>
+ <outputDirectory>lib/dependencies</outputDirectory>
+ <includes>
+ <include>*.jar</include>
+ </includes>
+ </fileSet>
+ <fileSet>
+ <directory>src/main/feature/config</directory>
+ <outputDirectory>config</outputDirectory>
+ <fileMode>0644</fileMode>
+ <excludes/>
+ </fileSet>
+ <fileSet>
+ <directory>src/main/feature/bin</directory>
+ <outputDirectory>bin</outputDirectory>
+ <fileMode>0744</fileMode>
+ <excludes/>
+ </fileSet>
+ <fileSet>
+ <directory>src/main/feature/db</directory>
+ <outputDirectory>db</outputDirectory>
+ <fileMode>0744</fileMode>
+ <excludes/>
+ </fileSet>
+ <fileSet>
+ <directory>src/main/feature/install</directory>
+ <outputDirectory>install</outputDirectory>
+ <fileMode>0744</fileMode>
+ <excludes/>
+ </fileSet>
+ </fileSets>
+
+</assembly>
diff --git a/feature-distributed-locking/src/main/feature/config/feature-distributed-locking.properties b/feature-distributed-locking/src/main/feature/config/feature-distributed-locking.properties
new file mode 100644
index 00000000..ee4aa474
--- /dev/null
+++ b/feature-distributed-locking/src/main/feature/config/feature-distributed-locking.properties
@@ -0,0 +1,34 @@
+###
+# ============LICENSE_START=======================================================
+ # feature-distributed-locking
+# ================================================================================
+# Copyright (C) 2018 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=========================================================
+###
+
+#Database properties
+#javax.persistence.jdbc.driver= org.mariadb.jdbc.Driver
+#javax.persistence.jdbc.url=jdbc:mariadb://${{SQL_HOST}}:3306/locks
+#javax.persistence.jdbc.user=${{SQL_USER}}
+#javax.persistence.jdbc.password=${{SQL_PASSWORD}}
+
+#This value is added to System.currentTimeMs to
+#set expirationTime when a lock is obtained.
+#distributed.locking.lock.aging=1000
+
+#The frequency (in milliseconds) that the heartbeat
+#thread refreshes locks owned by the current host
+#distributed.locking.heartbeat.interval=5000
+
diff --git a/feature-distributed-locking/src/main/feature/db/pooling/sql/1804-distributedlocking.downgrade.sql b/feature-distributed-locking/src/main/feature/db/pooling/sql/1804-distributedlocking.downgrade.sql
new file mode 100644
index 00000000..cd1b815d
--- /dev/null
+++ b/feature-distributed-locking/src/main/feature/db/pooling/sql/1804-distributedlocking.downgrade.sql
@@ -0,0 +1,20 @@
+# ============LICENSE_START=======================================================
+# feature-distributed-locking
+# ================================================================================
+# Copyright (C) 2018 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 pooling;
+drop table if exists locks; \ No newline at end of file
diff --git a/feature-distributed-locking/src/main/feature/db/pooling/sql/1804-distributedlocking.upgrade.sql b/feature-distributed-locking/src/main/feature/db/pooling/sql/1804-distributedlocking.upgrade.sql
new file mode 100644
index 00000000..be56d35e
--- /dev/null
+++ b/feature-distributed-locking/src/main/feature/db/pooling/sql/1804-distributedlocking.upgrade.sql
@@ -0,0 +1,23 @@
+# ============LICENSE_START=======================================================
+# feature-distributed-locking
+# ================================================================================
+# Copyright (C) 2018 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 foreign_key_checks=0;
+
+ CREATE TABLE if not exists pooling.locks (resourceId VARCHAR(128), host VARCHAR(128), owner VARCHAR(128), expirationTime BIGINT, PRIMARY KEY (resourceId), INDEX idx_expirationTime(expirationTime), INDEX idx_host(host));
+
+ set foreign_key_checks=1; \ No newline at end of file
diff --git a/feature-distributed-locking/src/main/java/org/onap/policy/distributed/locking/DistributedLockingFeature.java b/feature-distributed-locking/src/main/java/org/onap/policy/distributed/locking/DistributedLockingFeature.java
new file mode 100644
index 00000000..cc7a7a12
--- /dev/null
+++ b/feature-distributed-locking/src/main/java/org/onap/policy/distributed/locking/DistributedLockingFeature.java
@@ -0,0 +1,158 @@
+/*
+ * ============LICENSE_START=======================================================
+ * feature-distributed-locking
+ * ================================================================================
+ * Copyright (C) 2018 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.onap.policy.distributed.locking;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.util.UUID;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
+import org.onap.policy.common.utils.properties.exception.PropertyException;
+import org.onap.policy.drools.core.lock.LockRequestFuture;
+import org.onap.policy.drools.core.lock.PolicyResourceLockFeatureAPI;
+import org.onap.policy.drools.features.PolicyEngineFeatureAPI;
+import org.onap.policy.drools.persistence.SystemPersistence;
+import org.onap.policy.drools.system.PolicyEngine;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class DistributedLockingFeature implements PolicyEngineFeatureAPI, PolicyResourceLockFeatureAPI {
+
+ /**
+ * Logger instance
+ */
+ private static final Logger logger = LoggerFactory.getLogger(DistributedLockingFeature.class);
+
+ /**
+ * Properties Configuration Name
+ */
+ public static final String CONFIGURATION_PROPERTIES_NAME = "feature-distributed-locking";
+
+ /**
+ * Properties for locking feature
+ */
+ private DistributedLockingProperties lockProps;
+
+ /**
+ *ScheduledExecutorService for LockHeartbeat
+ */
+ private ScheduledExecutorService scheduledExecutorService;
+
+ /**
+ * UUID
+ */
+ private static final UUID uuid = UUID.randomUUID();
+
+ /**
+ * Config directory
+ */
+ @Override
+ public int getSequenceNumber() {
+ return 1000;
+ }
+
+ @Override
+ public Future<Boolean> beforeLock(String resourceId, String owner, Callback callback) {
+
+ TargetLock tLock = new TargetLock(resourceId, this.uuid, owner, lockProps);
+
+ return new LockRequestFuture(resourceId, owner, tLock.lock());
+
+ }
+
+ @Override
+ public Boolean beforeUnlock(String resourceId, String owner) {
+ TargetLock tLock = new TargetLock(resourceId, this.uuid, owner, lockProps);
+
+ return tLock.unlock();
+ }
+
+ @Override
+ public Boolean beforeIsLockedBy(String resourceId, String owner) {
+ TargetLock tLock = new TargetLock(resourceId, this.uuid, owner, lockProps);
+
+ return tLock.isActive();
+ }
+
+ @Override
+ public Boolean beforeIsLocked(String resourceId) {
+ TargetLock tLock = new TargetLock(resourceId, this.uuid, "dummyOwner", lockProps);
+
+ return tLock.isLocked();
+ }
+
+ @Override
+ public boolean afterStart(PolicyEngine engine) {
+
+ try {
+ this.lockProps = new DistributedLockingProperties(SystemPersistence.manager.getProperties(DistributedLockingFeature.CONFIGURATION_PROPERTIES_NAME));
+ } catch (PropertyException e) {
+ logger.error("DistributedLockingFeature feature properies have not been loaded", e);
+ throw new DistributedLockingFeatureException(e);
+ }
+
+ long heartbeatInterval = this.lockProps.getHeartBeatIntervalProperty();
+
+ cleanLockTable();
+ Heartbeat heartbeat = new Heartbeat(this.uuid, lockProps);
+
+ this.scheduledExecutorService = Executors.newScheduledThreadPool(1);
+ this.scheduledExecutorService.scheduleAtFixedRate(heartbeat, heartbeatInterval, heartbeatInterval, TimeUnit.MILLISECONDS);
+ return false;
+ }
+
+ /**
+ * This method kills the heartbeat thread and calls refreshLockTable which removes
+ * any records from the db where the current host is the owner.
+ */
+ @Override
+ public boolean beforeShutdown(PolicyEngine engine) {
+ scheduledExecutorService.shutdown();
+ cleanLockTable();
+ return false;
+ }
+
+ /**
+ * This method removes all records owned by the current host from the db.
+ */
+ private void cleanLockTable() {
+
+ try (Connection conn = DriverManager.getConnection(lockProps.getDbUrl(),
+ lockProps.getDbUser(),
+ lockProps.getDbPwd());
+ PreparedStatement statement = conn.prepareStatement("DELETE FROM pooling.locks WHERE host = ? OR expirationTime < ?");
+ ){
+
+ statement.setString(1, this.uuid.toString());
+ statement.setLong(2, System.currentTimeMillis());
+ statement.executeUpdate();
+
+ } catch (SQLException e) {
+ logger.error("error in refreshLockTable()", e);
+ }
+
+ }
+
+}
diff --git a/policy-utils/src/test/java/org/onap/policy/drools/utils/LoggerUtilTest.java b/feature-distributed-locking/src/main/java/org/onap/policy/distributed/locking/DistributedLockingFeatureException.java
index d942a427..f28ccbc9 100644
--- a/policy-utils/src/test/java/org/onap/policy/drools/utils/LoggerUtilTest.java
+++ b/feature-distributed-locking/src/main/java/org/onap/policy/distributed/locking/DistributedLockingFeatureException.java
@@ -1,6 +1,6 @@
-/*-
+/*
* ============LICENSE_START=======================================================
- * policy-utils
+ * feature-distributed-locking
* ================================================================================
* Copyright (C) 2018 AT&T Intellectual Property. All rights reserved.
* ================================================================================
@@ -17,17 +17,18 @@
* limitations under the License.
* ============LICENSE_END=========================================================
*/
-package org.onap.policy.drools.utils;
-import static org.junit.Assert.*;
+package org.onap.policy.distributed.locking;
-import org.junit.Test;
+public class DistributedLockingFeatureException extends RuntimeException {
+ private static final long serialVersionUID = 1L;
-public class LoggerUtilTest {
-
- @Test
- public void test() {
- assertNotNull(LoggerUtil.setLevel("foo", "warn"));
+ /**
+ *
+ * @param e
+ * exception to be wrapped
+ */
+ public DistributedLockingFeatureException(Exception e) {
+ super(e);
}
-
}
diff --git a/feature-distributed-locking/src/main/java/org/onap/policy/distributed/locking/DistributedLockingProperties.java b/feature-distributed-locking/src/main/java/org/onap/policy/distributed/locking/DistributedLockingProperties.java
new file mode 100644
index 00000000..139bfb7b
--- /dev/null
+++ b/feature-distributed-locking/src/main/java/org/onap/policy/distributed/locking/DistributedLockingProperties.java
@@ -0,0 +1,127 @@
+/*
+ * ============LICENSE_START=======================================================
+ * feature-distributed-locking
+ * ================================================================================
+ * Copyright (C) 2018 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.onap.policy.distributed.locking;
+
+import java.util.Properties;
+
+import org.onap.policy.common.utils.properties.PropertyConfiguration;
+import org.onap.policy.common.utils.properties.exception.PropertyException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+public class DistributedLockingProperties extends PropertyConfiguration{
+
+ private static final Logger logger = LoggerFactory.getLogger(DistributedLockingProperties.class);
+
+ /**
+ * Feature properties all begin with this prefix.
+ */
+ public static final String PREFIX = "distributed.locking.";
+
+ 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 AGING_PROPERTY = PREFIX + "lock.aging";
+ public static final String HEARTBEAT_INTERVAL_PROPERTY = PREFIX + "heartbeat.interval";
+
+ /**
+ * Properties from which this was constructed.
+ */
+ private Properties source;
+
+ /**
+ * Database driver
+ */
+ @Property(name = DB_DRIVER)
+ private String dbDriver;
+
+ /**
+ * Database url
+ */
+ @Property(name = DB_URL)
+ private String dbUrl;
+
+ /**
+ * Database user
+ */
+ @Property(name = DB_USER)
+ private String dbUser;
+
+ /**
+ * Database password
+ */
+ @Property(name = DB_PWD)
+ private String dbPwd;
+
+ /**
+ * Used to set expiration time for lock.
+ */
+ @Property(name = AGING_PROPERTY, defaultValue = "300000")
+ private long agingProperty;
+
+ /**
+ * Indicates intervals at which we refresh locks.
+ */
+ @Property(name = HEARTBEAT_INTERVAL_PROPERTY, defaultValue = "60000")
+ private long heartBeatIntervalProperty;
+
+ public DistributedLockingProperties(Properties props) throws PropertyException {
+ super(props);
+ source = props;
+ }
+
+
+ public Properties getSource() {
+ return source;
+ }
+
+
+ public String getDbDriver() {
+ return dbDriver;
+ }
+
+
+ public String getDbUrl() {
+ return dbUrl;
+ }
+
+
+ public String getDbUser() {
+ return dbUser;
+ }
+
+
+ public String getDbPwd() {
+ return dbPwd;
+ }
+
+
+ public long getAgingProperty() {
+ return agingProperty;
+ }
+
+
+ public long getHeartBeatIntervalProperty() {
+ return heartBeatIntervalProperty;
+ }
+
+}
diff --git a/feature-distributed-locking/src/main/java/org/onap/policy/distributed/locking/Heartbeat.java b/feature-distributed-locking/src/main/java/org/onap/policy/distributed/locking/Heartbeat.java
new file mode 100644
index 00000000..c753dba9
--- /dev/null
+++ b/feature-distributed-locking/src/main/java/org/onap/policy/distributed/locking/Heartbeat.java
@@ -0,0 +1,78 @@
+/*
+ * ============LICENSE_START=======================================================
+ * feature-distributed-locking
+ * ================================================================================
+ * Copyright (C) 2018 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.onap.policy.distributed.locking;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.util.Properties;
+import java.util.UUID;
+
+import org.onap.policy.drools.utils.NetworkUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ *
+ * This runnable class scans the locks table for all locks owned by this host.
+ * It refreshes the expiration time of each lock using the locking.distributed.aging
+ * property
+ *
+ */
+public class Heartbeat implements Runnable{
+
+ private static final Logger logger = LoggerFactory.getLogger(Heartbeat.class);
+
+ /**
+ * Properties object containing properties needed by class
+ */
+ private DistributedLockingProperties lockProps;
+
+ /**
+ * UUID
+ */
+ private UUID uuid;
+
+ public Heartbeat(UUID uuid, DistributedLockingProperties lockProps) {
+ this.lockProps = lockProps;
+ this.uuid = uuid;
+ }
+
+ @Override
+ public void run() {
+
+ long expirationAge = lockProps.getAgingProperty();
+
+ try (Connection conn = DriverManager.getConnection(lockProps.getDbUrl(), lockProps.getDbUser(),
+ lockProps.getDbPwd());
+ PreparedStatement statement = conn
+ .prepareStatement("UPDATE pooling.locks SET expirationTime = ? WHERE host = ?");) {
+
+ statement.setLong(1, System.currentTimeMillis() + expirationAge);
+ statement.setString(2, this.uuid.toString());
+ statement.executeUpdate();
+ } catch (SQLException e) {
+ logger.error("error in Heartbeat.run()", e);
+ }
+
+ }
+}
diff --git a/feature-distributed-locking/src/main/java/org/onap/policy/distributed/locking/TargetLock.java b/feature-distributed-locking/src/main/java/org/onap/policy/distributed/locking/TargetLock.java
new file mode 100644
index 00000000..ceaa849f
--- /dev/null
+++ b/feature-distributed-locking/src/main/java/org/onap/policy/distributed/locking/TargetLock.java
@@ -0,0 +1,233 @@
+/*
+ * ============LICENSE_START=======================================================
+ * feature-distributed-locking
+ * ================================================================================
+ * Copyright (C) 2018 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.onap.policy.distributed.locking;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.UUID;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class TargetLock {
+
+ private static final Logger logger = LoggerFactory.getLogger(TargetLock.class);
+
+ /**
+ * The Target resource we want to lock
+ */
+ private String resourceId;
+
+ /**
+ * Properties object containing properties needed by class
+ */
+ private DistributedLockingProperties lockProps;
+
+ /**
+ * UUID
+ */
+ private UUID uuid;
+
+ /**
+ * Owner
+ */
+ private String owner;
+
+ /**
+ * Constructs a TargetLock object.
+ *
+ * @param resourceId ID of the entity we want to lock
+ * @param lockProps Properties object containing properties needed by class
+ */
+ public TargetLock (String resourceId, UUID uuid, String owner, DistributedLockingProperties lockProps) {
+ this.resourceId = resourceId;
+ this.uuid = uuid;
+ this.owner = owner;
+ this.lockProps = lockProps;
+ }
+
+ /**
+ * obtain a lock
+ */
+ public boolean lock() {
+
+ return grabLock();
+ }
+
+ /**
+ * Unlock a resource by deleting it's associated record in the db
+ */
+ public boolean unlock() {
+ return deleteLock();
+ }
+
+ /**
+ * "Grabs" lock by attempting to insert a new record in the db.
+ * If the insert fails due to duplicate key error resource is already locked
+ * so we call secondGrab.
+ */
+ private boolean grabLock() {
+
+ try (Connection conn = DriverManager.getConnection(lockProps.getDbUrl(), lockProps.getDbUser(),
+ lockProps.getDbPwd());
+
+ // try to insert a record into the table(thereby grabbing the lock)
+ PreparedStatement statement = conn
+ .prepareStatement("INSERT INTO pooling.locks (resourceId, host, owner, expirationTime) values (?, ?, ?, ?)");) {
+ statement.setString(1, this.resourceId);
+ statement.setString(2, this.uuid.toString());
+ statement.setString(3, this.owner);
+ statement.setLong(4, System.currentTimeMillis() + lockProps.getAgingProperty());
+
+ statement.executeUpdate();
+ } catch (SQLException e) {
+ logger.error("error in TargetLock.grabLock()", e);
+ return secondGrab();
+ }
+
+ return true;
+ }
+
+ /**
+ * A second attempt at grabbing a lock. It first attempts to update the lock in case it is expired.
+ * If that fails, it attempts to insert a new record again
+ */
+ private boolean secondGrab() {
+
+ try (Connection conn = DriverManager.getConnection(lockProps.getDbUrl(), lockProps.getDbUser(),
+ lockProps.getDbPwd());
+
+ PreparedStatement updateStatement = conn.prepareStatement("UPDATE pooling.locks SET host = ?, owner = ?, expirationTime = ? WHERE expirationTime <= ? AND resourceId = ?");
+
+ PreparedStatement insertStatement = conn.prepareStatement("INSERT INTO pooling.locks (resourceId, host, owner, expirationTime) values (?, ?, ?, ?)");) {
+
+ updateStatement.setString(1, this.uuid.toString());
+ updateStatement.setString(2, this.owner);
+ updateStatement.setLong(3, System.currentTimeMillis() + lockProps.getAgingProperty());
+ updateStatement.setLong(4, System.currentTimeMillis());
+ updateStatement.setString(5, this.resourceId);
+
+ // The lock was expired and we grabbed it.
+ // return true
+ if (updateStatement.executeUpdate() == 1) {
+ return true;
+ }
+ // If our update does not return 1 row, the lock either has not expired
+ // or it was removed. Try one last grab
+ else {
+ insertStatement.setString(1, this.resourceId);
+ insertStatement.setString(2, this.uuid.toString());
+ insertStatement.setString(3, this.owner);
+ insertStatement.setLong(4, System.currentTimeMillis() + lockProps.getAgingProperty());
+
+ // If our insert returns 1 we successfully grabbed the lock
+ return (insertStatement.executeUpdate() == 1);
+ }
+
+ } catch (SQLException e) {
+ logger.error("error in TargetLock.secondGrab()", e);
+ return false;
+ }
+
+ }
+
+ /**
+ *To remove a lock we simply delete the record from the db
+ */
+ private boolean deleteLock() {
+
+ try (Connection conn = DriverManager.getConnection(lockProps.getDbUrl(), lockProps.getDbUser(),
+ lockProps.getDbPwd());
+
+ PreparedStatement deleteStatement = conn
+ .prepareStatement("DELETE FROM pooling.locks WHERE resourceId = ? AND owner = ? AND host = ?");) {
+
+ deleteStatement.setString(1, this.resourceId);
+ deleteStatement.setString(2, this.owner);
+ deleteStatement.setString(3, this.uuid.toString());
+
+ return (deleteStatement.executeUpdate() == 1);
+
+ } catch (SQLException e) {
+ logger.error("error in TargetLock.deleteLock()", e);
+ return false;
+ }
+
+ }
+
+ /**
+ * Is the lock active
+ */
+ public boolean isActive() {
+
+ try (Connection conn = DriverManager.getConnection(lockProps.getDbUrl(), lockProps.getDbUser(),
+ lockProps.getDbPwd());
+
+ PreparedStatement selectStatement = conn
+ .prepareStatement("SELECT * FROM pooling.locks WHERE resourceId = ? AND host = ? AND owner= ? AND expirationTime >= ?");) {
+ {
+ selectStatement.setString(1, this.resourceId);
+ selectStatement.setString(2, this.uuid.toString());
+ selectStatement.setString(3, this.owner);
+ selectStatement.setLong(4, System.currentTimeMillis());
+
+ ResultSet result = selectStatement.executeQuery();
+
+ // This will return true if the
+ // query returned at least one row
+ return result.first();
+
+ }
+ } catch (SQLException e) {
+ logger.error("error in TargetLock.isActive()", e);
+ return false;
+ }
+ }
+
+ /**
+ * Is the resource locked
+ */
+ public boolean isLocked() {
+
+ try (Connection conn = DriverManager.getConnection(lockProps.getDbUrl(), lockProps.getDbUser(),
+ lockProps.getDbPwd());
+
+ PreparedStatement selectStatement = conn
+ .prepareStatement("SELECT * FROM pooling.locks WHERE resourceId = ? AND expirationTime >= ?");) {
+ {
+ selectStatement.setString(1, this.resourceId);
+ selectStatement.setLong(2, System.currentTimeMillis());
+ ResultSet result = selectStatement.executeQuery();
+
+ // This will return true if the
+ // query returned at least one row
+ return result.first();
+
+ }
+ } catch (SQLException e) {
+ logger.error("error in TargetLock.isActive()", e);
+ return false;
+ }
+ }
+
+}
diff --git a/feature-distributed-locking/src/main/resources/META-INF/services/org.onap.policy.drools.core.lock.PolicyResourceLockFeatureAPI b/feature-distributed-locking/src/main/resources/META-INF/services/org.onap.policy.drools.core.lock.PolicyResourceLockFeatureAPI
new file mode 100644
index 00000000..19bdf505
--- /dev/null
+++ b/feature-distributed-locking/src/main/resources/META-INF/services/org.onap.policy.drools.core.lock.PolicyResourceLockFeatureAPI
@@ -0,0 +1 @@
+org.onap.policy.distributed.locking.DistributedLockingFeature \ No newline at end of file
diff --git a/feature-distributed-locking/src/main/resources/META-INF/services/org.onap.policy.drools.features.PolicyEngineFeatureAPI b/feature-distributed-locking/src/main/resources/META-INF/services/org.onap.policy.drools.features.PolicyEngineFeatureAPI
new file mode 100644
index 00000000..19bdf505
--- /dev/null
+++ b/feature-distributed-locking/src/main/resources/META-INF/services/org.onap.policy.drools.features.PolicyEngineFeatureAPI
@@ -0,0 +1 @@
+org.onap.policy.distributed.locking.DistributedLockingFeature \ No newline at end of file
diff --git a/feature-distributed-locking/src/test/java/org/onap/policy/distributed/locking/test/DistributedLockingFeatureExceptionTest.java b/feature-distributed-locking/src/test/java/org/onap/policy/distributed/locking/test/DistributedLockingFeatureExceptionTest.java
new file mode 100644
index 00000000..ea53e522
--- /dev/null
+++ b/feature-distributed-locking/src/test/java/org/onap/policy/distributed/locking/test/DistributedLockingFeatureExceptionTest.java
@@ -0,0 +1,36 @@
+/*
+ * ============LICENSE_START=======================================================
+ * feature-distributed-locking
+ * ================================================================================
+ * Copyright (C) 2018 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.onap.policy.distributed.locking.test;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+import org.onap.policy.common.utils.test.ExceptionsTester;
+import org.onap.policy.distributed.locking.DistributedLockingFeatureException;
+
+public class DistributedLockingFeatureExceptionTest extends ExceptionsTester{
+
+ @Test
+ public void test() {
+ assertEquals(1, test(DistributedLockingFeatureException.class));
+ }
+
+}
diff --git a/feature-distributed-locking/src/test/java/org/onap/policy/distributed/locking/test/TargetLockTest.java b/feature-distributed-locking/src/test/java/org/onap/policy/distributed/locking/test/TargetLockTest.java
new file mode 100644
index 00000000..e624afb9
--- /dev/null
+++ b/feature-distributed-locking/src/test/java/org/onap/policy/distributed/locking/test/TargetLockTest.java
@@ -0,0 +1,220 @@
+/*
+ * ============LICENSE_START=======================================================
+ * feature-distributed-locking
+ * ================================================================================
+ * Copyright (C) 2018 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.onap.policy.distributed.locking.test;
+
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.onap.policy.distributed.locking.DistributedLockingFeature;
+import org.onap.policy.drools.persistence.SystemPersistence;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+
+public class TargetLockTest {
+ private static final Logger logger = LoggerFactory.getLogger(TargetLockTest.class);
+ private static final String DB_CONNECTION = "jdbc:h2:mem:pooling;INIT=CREATE SCHEMA IF NOT EXISTS pooling\\;SET SCHEMA pooling";
+ private static final String DB_USER = "user";
+ private static final String DB_PASSWORD = "password";
+ private static Connection conn = null;
+ private static DistributedLockingFeature distLockFeat;
+
+ @BeforeClass
+ public static void setup() {
+ getDBConnection();
+ createTable();
+ SystemPersistence.manager.setConfigurationDir("src/test/resources");
+ distLockFeat = new DistributedLockingFeature();
+ distLockFeat.afterStart(null);
+
+ }
+
+ @AfterClass
+ public static void cleanUp() {
+ distLockFeat.beforeShutdown(null);
+ try {
+ conn.close();
+ } catch (SQLException e) {
+ logger.error("Error in TargetLockTest.cleanUp()", e);
+ }
+ }
+
+ @Before
+ public void wipeDb() {
+
+ try (PreparedStatement lockDelete = conn.prepareStatement("DELETE FROM pooling.locks");){
+ lockDelete.executeUpdate();
+ } catch (SQLException e) {
+ logger.error("Error in TargetLockTest.wipeDb()", e);
+ throw new RuntimeException(e);
+ }
+
+ }
+
+ @Test
+ public void testGrabLockSuccess() throws InterruptedException, ExecutionException {
+ assertTrue(distLockFeat.beforeLock("resource1", "owner1", null).get());
+
+ //attempt to grab expiredLock
+ try (PreparedStatement updateStatement = conn.prepareStatement("UPDATE pooling.locks SET expirationTime = ? WHERE resourceId = ?");)
+ {
+ updateStatement.setLong(1, System.currentTimeMillis() - 1000);
+ updateStatement.setString(2, "resource1");
+ updateStatement.executeUpdate();
+
+ } catch (SQLException e) {
+ logger.error("Error in TargetLockTest.testGrabLockSuccess()", e);
+ throw new RuntimeException(e);
+ }
+
+ assertTrue(distLockFeat.beforeLock("resource1", "owner1", null).get());
+ }
+
+ @Test
+ public void testExpiredLocks() throws InterruptedException, ExecutionException {
+ CountDownLatch latch = new CountDownLatch(1);
+
+ distLockFeat.beforeLock("resource1", "owner1", null);
+
+ try {
+ latch.await(1000, TimeUnit.MILLISECONDS);
+ } catch (InterruptedException e) {
+ logger.error("Error in testExpiredLocks", e);
+ }
+
+ //Heartbeat should keep it active
+ assertFalse(distLockFeat.beforeLock("resource1", "owner1", null).get());
+ }
+
+ @Test
+ public void testGrabLockFail() throws InterruptedException, ExecutionException {
+ CountDownLatch latch = new CountDownLatch(1);
+
+ distLockFeat.beforeLock("resource1", "owner1", null);
+
+ try {
+ latch.await(10, TimeUnit.MILLISECONDS);
+ } catch (InterruptedException e) {
+ logger.error("Error in testExpiredLocks", e);
+ }
+ assertFalse(distLockFeat.beforeLock("resource1", "owner1", null).get());
+
+ }
+
+
+ @Test
+ public void testUnlock() throws InterruptedException, ExecutionException {
+ distLockFeat.beforeLock("resource1", "owner1", null);
+
+ assertTrue(distLockFeat.beforeUnlock("resource1", "owner1"));
+ assertTrue(distLockFeat.beforeLock("resource1", "owner1", null).get());
+ }
+
+ @Test
+ public void testIsActive() {
+ assertFalse(distLockFeat.beforeIsLockedBy("resource1", "owner1"));
+ distLockFeat.beforeLock("resource1", "owner1", null);
+ assertTrue(distLockFeat.beforeIsLockedBy("resource1", "owner1"));
+ assertFalse(distLockFeat.beforeIsLockedBy("resource1", "owner2"));
+
+ // isActive on expiredLock
+ try (PreparedStatement updateStatement = conn
+ .prepareStatement("UPDATE pooling.locks SET expirationTime = ? WHERE resourceId = ?");) {
+ updateStatement.setLong(1, System.currentTimeMillis() - 5000);
+ updateStatement.setString(2, "resource1");
+ updateStatement.executeUpdate();
+
+ } catch (SQLException e) {
+ logger.error("Error in TargetLockTest.testIsActive()", e);
+ throw new RuntimeException(e);
+ }
+
+ assertFalse(distLockFeat.beforeIsLockedBy("resource1", "owner1"));
+
+ distLockFeat.beforeLock("resource1", "owner1", null);
+ //Unlock record, next isActive attempt should fail
+ distLockFeat.beforeUnlock("resource1", "owner1");
+ assertFalse(distLockFeat.beforeIsLockedBy("resource1", "owner1"));
+
+ }
+
+ @Test
+ public void testHeartbeat() {
+ CountDownLatch latch = new CountDownLatch(1);
+
+ distLockFeat.beforeLock("resource1", "owner1", null);
+ try {
+ latch.await(1000, TimeUnit.MILLISECONDS);
+ } catch (InterruptedException e) {
+ logger.error("Error in testExpiredLocks", e);
+ }
+
+ // This test always returns true.
+ assertTrue(distLockFeat.beforeIsLocked("resource1"));
+ }
+
+ @Test
+ public void unlockBeforeLock() {
+ assertFalse(distLockFeat.beforeUnlock("resource1", "owner1"));
+ distLockFeat.beforeLock("resource1", "owner1", null);
+ assertTrue(distLockFeat.beforeUnlock("resource1", "owner1"));
+ assertFalse(distLockFeat.beforeUnlock("resource1", "owner1"));
+ }
+
+ @Test
+ public void testIsLocked() {
+ assertFalse(distLockFeat.beforeIsLocked("resource1"));
+ distLockFeat.beforeLock("resource1", "owner1", null);
+ assertTrue(distLockFeat.beforeIsLocked("resource1"));
+
+ }
+
+ private static void getDBConnection() {
+ try {
+ conn = DriverManager.getConnection(DB_CONNECTION, DB_USER, DB_PASSWORD);
+ } catch (SQLException e) {
+ logger.error("Error in TargetLockTest.getDBConnection()", e);
+ }
+ }
+
+ private static void createTable() {
+ String createString = "create table if not exists pooling.locks (resourceId VARCHAR(128), host VARCHAR(128), owner VARCHAR(128), expirationTime BIGINT, PRIMARY KEY (resourceId))";
+ try (PreparedStatement createStmt = conn.prepareStatement(createString);) {
+ createStmt.executeUpdate();
+
+ } catch (SQLException e) {
+ logger.error("Error in TargetLockTest.createTable()", e);
+ }
+ }
+
+
+}
diff --git a/feature-distributed-locking/src/test/resources/feature-distributed-locking.properties b/feature-distributed-locking/src/test/resources/feature-distributed-locking.properties
new file mode 100644
index 00000000..d1a07e82
--- /dev/null
+++ b/feature-distributed-locking/src/test/resources/feature-distributed-locking.properties
@@ -0,0 +1,26 @@
+###
+# ============LICENSE_START=======================================================
+ # feature-distributed-locking
+# ================================================================================
+# Copyright (C) 2018 AT&T Intellectual Property. All rights reserved.
+# ================================================================================
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# ============LICENSE_END=========================================================
+###
+
+javax.persistence.jdbc.driver=org.h2.Driver
+javax.persistence.jdbc.url=jdbc:h2:mem:pooling
+javax.persistence.jdbc.user=user
+javax.persistence.jdbc.password=password
+distributed.locking.lock.aging=150
+distributed.locking.heartbeat.interval=500 \ No newline at end of file
diff --git a/feature-eelf/src/main/feature/config/logback-eelf.xml b/feature-eelf/src/main/feature/config/logback-eelf.xml
index d76eb20b..4dafd45d 100644
--- a/feature-eelf/src/main/feature/config/logback-eelf.xml
+++ b/feature-eelf/src/main/feature/config/logback-eelf.xml
@@ -2,7 +2,7 @@
============LICENSE_START=======================================================
feature-eelf
================================================================================
- Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ Copyright (C) 2017-2018 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.
@@ -27,13 +27,13 @@
<property name="networkLogName" value="network" />
<property name="defaultPattern"
- value="%X{BeginTimestamp}|%X{EndTimestamp}|%X{RequestId}|%X{ServiceInstanceId}|%thread|%X{ServerName}|%X{ServiceName}|%X{PartnerName}|%X{TargetEntity}|%X{TargetServiceName}|%X{StatusCode}|%X{ResponseCode}|%X{ResponseDescription}|%X{InstanceUUID}|%.-5level|%X{AlertSeverity}|%X{ServerIPAddress}|%X{ElapsedTime}|%X{ServerFQDN}|%X{RemoteHost}|%X{ClassName}||%X{ProcessKey}|%X{TargetVirtualEntity}|%X{CustomField1}|%X{CustomField2}|%X{CustomField3}|%X{CustomField4}|%msg%n" />
+ value="%X{BeginTimestamp}|%X{EndTimestamp}|%X{RequestID}|%X{ServiceInstanceId}|%thread|%X{ServerName}|%X{ServiceName}|%X{PartnerName}|%X{TargetEntity}|%X{TargetServiceName}|%X{StatusCode}|%X{ResponseCode}|%X{ResponseDescription}|%X{InstanceUUID}|%.-5level|%X{AlertSeverity}|%X{ServerIPAddress}|%X{ElapsedTime}|%X{ServerFQDN}|%X{RemoteHost}|%X{ClassName}||%X{ProcessKey}|%X{TargetVirtualEntity}|%X{CustomField1}|%X{CustomField2}|%X{CustomField3}|%X{CustomField4}|%msg%n" />
<property name="defaultMetricPattern"
- value="%X{BeginTimestamp}|%X{EndTimestamp}|%X{RequestId}|%X{ServiceInstanceId}|%thread|%X{ServerName}|%X{ServiceName}|%X{PartnerName}|%X{TargetEntity}|%X{TargetServiceName}|%X{StatusCode}|%X{ResponseCode}|%X{ResponseDescription}|%X{InstanceUUID}|%.-5level|%X{AlertSeverity}|%X{ServerIPAddress}|%X{ElapsedTime}|%X{ServerFQDN}|%X{RemoteHost}|%X{ClassName}||%X{ProcessKey}|%X{TargetVirtualEntity}|%X{CustomField1}|%X{CustomField2}|%X{CustomField3}|%X{CustomField4}|%msg%n" />
+ value="%X{BeginTimestamp}|%X{EndTimestamp}|%X{RequestID}|%X{ServiceInstanceId}|%thread|%X{ServerName}|%X{ServiceName}|%X{PartnerName}|%X{TargetEntity}|%X{TargetServiceName}|%X{StatusCode}|%X{ResponseCode}|%X{ResponseDescription}|%X{InstanceUUID}|%.-5level|%X{AlertSeverity}|%X{ServerIPAddress}|%X{ElapsedTime}|%X{ServerFQDN}|%X{RemoteHost}|%X{ClassName}||%X{ProcessKey}|%X{TargetVirtualEntity}|%X{CustomField1}|%X{CustomField2}|%X{CustomField3}|%X{CustomField4}|%msg%n" />
<property name="defaultAuditPattern"
- value="%X{BeginTimestamp}|%X{EndTimestamp}|%X{RequestId}|%X{ServiceInstanceId}|%thread|%X{ServerName}|%X{ServiceName}|%X{PartnerName}|%X{StatusCode}|%X{ResponseCode}|%X{ResponseDescription}|%X{InstanceUUID}|%.-5level|%X{AlertSeverity}|%X{ServerIPAddress}|%X{ElapsedTime}|%X{ServerFQDN}|%X{RemoteHost}|%X{ClassName}||%X{ProcessKey}|%X{CustomField1}|%X{CustomField2}|%X{CustomField3}|%X{CustomField4}|%msg%n" />
+ value="%X{BeginTimestamp}|%X{EndTimestamp}|%X{RequestID}|%X{ServiceInstanceId}|%thread|%X{ServerName}|%X{ServiceName}|%X{PartnerName}|%X{StatusCode}|%X{ResponseCode}|%X{ResponseDescription}|%X{InstanceUUID}|%.-5level|%X{AlertSeverity}|%X{ServerIPAddress}|%X{ElapsedTime}|%X{ServerFQDN}|%X{RemoteHost}|%X{ClassName}||%X{ProcessKey}|%X{CustomField1}|%X{CustomField2}|%X{CustomField3}|%X{CustomField4}|%msg%n" />
<property name="defaultErrorPattern"
- value="%d{yyyy-MM-dd'T'HH:mm:ss.SSS+00:00, UTC}|%X{RequestId}|%thread|%X{ServiceName}|%X{PartnerName}|%X{TargetEntity}|%X{TargetServiceName}|%X{ErrorCategory}|%X{ErrorCode}|%X{ErrorDesciption}|%msg%replace(%xException){'\n',' - '}%nopex%n" />
+ value="%d{yyyy-MM-dd'T'HH:mm:ss.SSS+00:00, UTC}|%X{RequestID}|%thread|%X{ServiceName}|%X{PartnerName}|%X{TargetEntity}|%X{TargetServiceName}|%X{ErrorCategory}|%X{ErrorCode}|%X{ErrorDesciption}|%msg%replace(%xException){'\n',' - '}%nopex%n" />
<property name="networkPattern" value="[%d|%t]%m%n" />
<property name="debugPattern" value="[%date|%level|%logger{0}|%thread] %replace(%msg){'\n', ' '}%n" />
diff --git a/feature-simulators/src/test/java/org/onap/policy/drools/simulators/DMaaPSimulatorTest.java b/feature-simulators/src/test/java/org/onap/policy/drools/simulators/DMaaPSimulatorTest.java
index 415c5206..b16804e6 100644
--- a/feature-simulators/src/test/java/org/onap/policy/drools/simulators/DMaaPSimulatorTest.java
+++ b/feature-simulators/src/test/java/org/onap/policy/drools/simulators/DMaaPSimulatorTest.java
@@ -2,7 +2,7 @@
* ============LICENSE_START=======================================================
* feature-simulators
* ================================================================================
- * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * Copyright (C) 2017-2018 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.
@@ -37,7 +37,7 @@ import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.onap.policy.drools.http.server.HttpServletServer;
-import org.onap.policy.drools.utils.LoggerUtil;
+import org.onap.policy.drools.utils.logging.LoggerUtil;
import org.onap.policy.drools.utils.NetworkUtil;
public class DMaaPSimulatorTest {
@@ -361,4 +361,4 @@ public class DMaaPSimulatorTest {
this.b = b;
}
}
-} \ No newline at end of file
+}
diff --git a/packages/base/src/files/etc/profile.d/env.sh b/packages/base/src/files/etc/profile.d/env.sh
index be8e7471..97076606 100644
--- a/packages/base/src/files/etc/profile.d/env.sh
+++ b/packages/base/src/files/etc/profile.d/env.sh
@@ -2,7 +2,7 @@
# ============LICENSE_START=======================================================
# Base Package
# ================================================================================
-# Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+# Copyright (C) 2017-2018 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.
@@ -19,6 +19,7 @@
###
export POLICY_HOME=${{POLICY_HOME}}
+export POLICY_LOGS=${{POLICY_LOGS}}
export JAVA_HOME=${{JAVA_HOME}}
export ENGINE_MANAGEMENT_USER=${{ENGINE_MANAGEMENT_USER}}
export ENGINE_MANAGEMENT_PASSWORD=${{ENGINE_MANAGEMENT_PASSWORD}}
diff --git a/packages/docker/pom.xml b/packages/docker/pom.xml
index ff8ebadd..5d90809b 100644
--- a/packages/docker/pom.xml
+++ b/packages/docker/pom.xml
@@ -78,10 +78,10 @@
<artifactItems>
<artifactItem>
<groupId>org.onap.policy.drools-applications.controlloop.packages</groupId>
- <artifactId>apps</artifactId>
+ <artifactId>apps-controlloop</artifactId>
<version>${project.version}</version>
<type>zip</type>
- <destFileName>apps.zip</destFileName>
+ <destFileName>apps-controlloop.zip</destFileName>
</artifactItem>
</artifactItems>
</configuration>
diff --git a/packages/docker/src/main/docker/Dockerfile b/packages/docker/src/main/docker/Dockerfile
index d7af6be9..6d5c4ab7 100644
--- a/packages/docker/src/main/docker/Dockerfile
+++ b/packages/docker/src/main/docker/Dockerfile
@@ -2,11 +2,16 @@ FROM ubuntu:14.04
ARG HTTP_PROXY=${HTTP_PROXY}
ARG HTTPS_PROXY=${HTTPS_PROXY}
-ARG POLICY_LOGS=/var/log/ONAP/policy
+ARG POLICY_HOME=/opt/app/policy
+ARG POLICY_LOGS=/var/log/onap/policy/pdpd
+ARG POLICY_INSTALL=/tmp/policy-install
ENV http_proxy $HTTP_PROXY
ENV https_proxy $HTTPS_PROXY
+ENV POLICY_INSTALL ${POLICY_INSTALL}
+ENV POLICY_HOME ${POLICY_HOME}
ENV POLICY_LOGS ${POLICY_LOGS}
+ENV POLICY_DOCKER true
RUN \
apt-get clean && \
@@ -32,18 +37,23 @@ RUN \
apt-get install -y mariadb-client
RUN pip install http-prompt
-RUN mkdir -p /opt/app/policy/ /tmp/policy-install/ ${POLICY_LOGS} && \
- chown -R policy /opt/app/policy/ /tmp/policy-install/ ${POLICY_LOGS}
+RUN mkdir -p ${POLICY_HOME}/config ${POLICY_LOGS} ${POLICY_INSTALL}/config && \
+ chown -R policy:policy ${POLICY_HOME} ${POLICY_LOGS} ${POLICY_INSTALL}
-WORKDIR /tmp/policy-install
+WORKDIR ${POLICY_INSTALL}
-COPY install-drools.zip apps.zip docker-install.sh do-start.sh wait-for-port.sh ./
+COPY install-drools.zip apps-controlloop.zip docker-install.sh do-start.sh wait-for-port.sh ./
+
+VOLUME [ "${POLICY_INSTALL}/config", "${POLICY_HOME}/config" ]
RUN unzip -o install-drools.zip && \
- unzip -o apps.zip && \
- rm install-drools.zip apps.zip && \
- chown -R policy * && \
+ unzip -o apps-controlloop.zip && \
+ rm install-drools.zip apps-controlloop.zip && \
+ chown -R policy:policy * && \
chmod +x *.sh
+EXPOSE 9696 6969
+
USER policy
+
CMD ./do-start.sh
diff --git a/packages/docker/src/main/docker/do-start.sh b/packages/docker/src/main/docker/do-start.sh
index e1857441..5f156979 100644
--- a/packages/docker/src/main/docker/do-start.sh
+++ b/packages/docker/src/main/docker/do-start.sh
@@ -1,10 +1,12 @@
#!/bin/bash
# skip installation if build.info file is present (restarting an existing container)
-if [[ -f /opt/app/policy/etc/build.info ]]; then
+if [[ -f ${POLICY_HOME}/etc/build.info ]]; then
echo "Found existing installation, will not reinstall"
- . /opt/app/policy/etc/profile.d/env.sh
+ . ${POLICY_HOME}/etc/profile.d/env.sh
else
+ echo "installing .."
+
# replace conf files from installer with environment-specific files
# mounted from the hosting VM
if [[ -d config ]]; then
@@ -15,13 +17,22 @@ else
# needs to deploy some artifacts to the repo
./wait-for-port.sh nexus 8081
+ # remove broken symbolic links if any in data directory
+ if [[ -d ${POLICY_HOME}/config ]]; then
+ echo "removing dangling symbolic links"
+ find -L ${POLICY_HOME}/config -type l -exec rm -- {} +
+ fi
+
+ echo "docker install at ${PWD}"
+
./docker-install.sh
. /opt/app/policy/etc/profile.d/env.sh
# install policy keystore
- mkdir -p $POLICY_HOME/etc/ssl
- cp config/policy-keystore $POLICY_HOME/etc/ssl
+
+ mkdir -p ${POLICY_HOME}/etc/ssl
+ cp config/policy-keystore ${POLICY_HOME}/etc/ssl
if [[ -x config/drools-tweaks.sh ]] ; then
echo "Executing tweaks"
@@ -29,16 +40,10 @@ else
# argument to bash avoids needing execute perms.
bash config/drools-tweaks.sh
fi
-
- # wait for DB up
- ./wait-for-port.sh mariadb 3306
-
- # now that DB is up, invoke database upgrade:
- # sql provisioning scripts should be invoked here.
fi
echo "Starting processes"
policy start
-sleep 1000d
+tail -f /dev/null
diff --git a/packages/docker/src/main/docker/docker-install.sh b/packages/docker/src/main/docker/docker-install.sh
index e65329da..5ec25823 100644
--- a/packages/docker/src/main/docker/docker-install.sh
+++ b/packages/docker/src/main/docker/docker-install.sh
@@ -4,7 +4,7 @@
# ============LICENSE_START=======================================================
# Installation Package
# ================================================================================
-# Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+# Copyright (C) 2017-2018 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.
@@ -369,26 +369,32 @@ function install_base() {
fi
done
+ /bin/mkdir -p "${POLICY_HOME}/logs/" > /dev/null 2>&1
+
if [[ ! ( -d "$POLICY_HOME" && -w "$POLICY_HOME" ) ]]; then
echo "ERROR: Installation directory $POLICY_HOME does not exist or not writable"
exit 1
fi
- if ! /bin/rm -fr "${POLICY_HOME}"/* > /dev/null 2>&1; then
- echo "error: aborting base installation: cannot delete the underlying ${POLICY_HOME} files"
- exit 1
- fi
+ if [[ -z ${POLICY_DOCKER} ]]; then
+ if ! /bin/rm -fr "${POLICY_HOME}"/* > /dev/null 2>&1; then
+ echo "error: aborting base installation: cannot delete the underlying ${POLICY_HOME} files"
+ exit 1
+ fi
- POLICY_HOME_CONTENTS=$(ls -A "${POLICY_HOME}" 2> /dev/null)
- if [[ -n ${POLICY_HOME_CONTENTS} ]]; then
- echo "error: aborting base installation: ${POLICY_HOME} directory is not empty"
- exit 1
- fi
+ POLICY_HOME_CONTENTS=$(ls -A "${POLICY_HOME}" 2> /dev/null)
+ if [[ -n ${POLICY_HOME_CONTENTS} ]]; then
+ echo "error: aborting base installation: ${POLICY_HOME} directory is not empty"
+ exit 1
+ fi
- if ! /bin/mkdir -p "${POLICY_HOME}/logs/" > /dev/null 2>&1; then
- echo "error: aborting base installation: cannot create ${POLICY_HOME}/logs/"
- exit 1
- fi
+ if [[ -n ${POLICY_LOGS} ]]; then
+ if ! /bin/mkdir -p "${POLICY_LOGS}" > /dev/null 2>&1; then
+ echo "error: aborting base installation: cannot create ${POLICY_LOGS}"
+ exit 1
+ fi
+ fi
+ fi
BASE_TGZ=$(ls base-*.tar.gz)
if [ ! -r ${BASE_TGZ} ]; then
@@ -861,7 +867,7 @@ function do_install()
set -x
fi
- echo "Starting installation at $(date)"
+ echo "Starting installation at $(date) at ${PWD}"
echo
COMPONENT_TYPE=base
@@ -876,12 +882,12 @@ function do_install()
installArtifacts
- if [[ -f apps-installer ]]; then
+ if [[ -f apps-controlloop-installer ]]; then
# if exists, any customizations to the
# base drools installation from the drools apps
# is executed here
- ./apps-installer
+ ./apps-controlloop-installer
fi
echo
diff --git a/packages/install/src/files/base.conf b/packages/install/src/files/base.conf
index d92abed0..f1a37d0f 100644
--- a/packages/install/src/files/base.conf
+++ b/packages/install/src/files/base.conf
@@ -2,7 +2,7 @@
# ============LICENSE_START=======================================================
# ONAP POLICY
# ================================================================================
-# Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+# Copyright (C) 2017-2018 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.
@@ -21,6 +21,7 @@
# SYSTEM software configuration
POLICY_HOME=/opt/app/policy
+POLICY_LOGS=/opt/app/policy/logs
JAVA_HOME=/opt/jdk1.8.0_77
M2_HOME=/opt/app/policy/3rdparty/apache-maven-3.3.1
diff --git a/policy-core/src/main/java/org/onap/policy/drools/core/lock/LockRequestFuture.java b/policy-core/src/main/java/org/onap/policy/drools/core/lock/LockRequestFuture.java
new file mode 100644
index 00000000..46d1ff2d
--- /dev/null
+++ b/policy-core/src/main/java/org/onap/policy/drools/core/lock/LockRequestFuture.java
@@ -0,0 +1,261 @@
+/*
+ * ============LICENSE_START=======================================================
+ * ONAP
+ * ================================================================================
+ * Copyright (C) 2018 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.onap.policy.drools.core.lock;
+
+import java.util.concurrent.CancellationException;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+import java.util.concurrent.atomic.AtomicReference;
+import org.onap.policy.drools.core.lock.PolicyResourceLockFeatureAPI.Callback;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Future associated with a lock request.
+ */
+public class LockRequestFuture implements Future<Boolean> {
+
+ // messages used in exceptions
+ public static final String MSG_NULL_RESOURCE_ID = "null resourceId";
+ public static final String MSG_NULL_OWNER = "null owner";
+
+ private static Logger logger = LoggerFactory.getLogger(LockRequestFuture.class);
+
+ /**
+ * The resource on which the lock was requested.
+ */
+ private final String resourceId;
+
+ /**
+ * The owner for which the lock was requested.
+ */
+ private final String owner;
+
+ /**
+ * Possible states for this future.
+ */
+ private enum State {
+ WAITING, CANCELLED, ACQUIRED, DENIED
+ };
+
+ private AtomicReference<State> state;
+
+ /**
+ * Used to wait for the lock request to complete.
+ */
+ private CountDownLatch waiter = new CountDownLatch(1);
+
+ /**
+ * Callback to invoke once the lock is acquired (or denied). This is set to
+ * {@code null} once the callback has been invoked.
+ */
+ private final AtomicReference<Callback> callback;
+
+ /**
+ * Constructs a future that has already been completed.
+ *
+ * @param resourceId
+ * @param owner owner for which the lock was requested
+ * @param locked {@code true} if the lock has been acquired, {@code false} if the lock
+ * request has been denied
+ * @throws IllegalArgumentException if any of the arguments are {@code null}
+ */
+ public LockRequestFuture(String resourceId, String owner, boolean locked) {
+ if (resourceId == null) {
+ throw makeNullArgException(MSG_NULL_RESOURCE_ID);
+ }
+
+ if (owner == null) {
+ throw makeNullArgException(MSG_NULL_OWNER);
+ }
+
+ this.resourceId = resourceId;
+ this.owner = owner;
+ this.callback = new AtomicReference<>(null);
+ this.state = new AtomicReference<>(locked ? State.ACQUIRED : State.DENIED);
+
+ // indicate that it's already done
+ this.waiter.countDown();
+ }
+
+ /**
+ * Constructs a future that has not yet been completed.
+ *
+ * @param resourceId
+ * @param owner owner for which the lock was requested
+ * @param callback item to be wrapped
+ * @throws IllegalArgumentException if the resourceId or owner is {@code null}
+ */
+ public LockRequestFuture(String resourceId, String owner, Callback callback) {
+ if (resourceId == null) {
+ throw makeNullArgException(MSG_NULL_RESOURCE_ID);
+ }
+
+ if (owner == null) {
+ throw makeNullArgException(MSG_NULL_OWNER);
+ }
+
+ this.resourceId = resourceId;
+ this.owner = owner;
+ this.callback = new AtomicReference<>(callback);
+ this.state = new AtomicReference<>(State.WAITING);
+ }
+
+ public String getResourceId() {
+ return resourceId;
+ }
+
+ public String getOwner() {
+ return owner;
+ }
+
+ @Override
+ public boolean cancel(boolean mayInterruptIfRunning) {
+ boolean cancelled = state.compareAndSet(State.WAITING, State.CANCELLED);
+
+ if (cancelled) {
+ logger.info("resource {} owner {} cancelled lock request", resourceId, owner);
+ waiter.countDown();
+ }
+
+ return cancelled;
+ }
+
+ /**
+ * Indicates that the lock has been acquired or denied.
+ *
+ * @param locked {@code true} if the lock has been acquired, {@code false} if the lock
+ * request has been denied
+ *
+ * @return {@code true} if it was not already completed, {@code false} otherwise
+ */
+ protected boolean setLocked(boolean locked) {
+ State newState = (locked ? State.ACQUIRED : State.DENIED);
+ if (state.compareAndSet(State.WAITING, newState)) {
+ waiter.countDown();
+ return true;
+
+ } else {
+ return false;
+ }
+ }
+
+ @Override
+ public boolean isCancelled() {
+ return (state.get() == State.CANCELLED);
+ }
+
+ @Override
+ public boolean isDone() {
+ return (state.get() != State.WAITING);
+ }
+
+ /**
+ * Gets the current status of the lock.
+ *
+ * @return {@code true} if the lock has been acquired, {@code false} otherwise
+ */
+ public boolean isLocked() {
+ return (state.get() == State.ACQUIRED);
+ }
+
+ /**
+ * @return {@code true} if the lock was acquired, {@code false} if it was denied
+ */
+ @Override
+ public Boolean get() throws CancellationException, InterruptedException {
+ waiter.await();
+
+ switch (state.get()) {
+ case CANCELLED:
+ throw new CancellationException("lock request was cancelled");
+ case ACQUIRED:
+ return true;
+ default:
+ // should only be DENIED at this point
+ return false;
+ }
+ }
+
+ /**
+ * @return {@code true} if the lock was acquired, {@code false} if it was denied
+ */
+ @Override
+ public Boolean get(long timeout, TimeUnit unit)
+ throws CancellationException, InterruptedException, TimeoutException {
+
+ if (!waiter.await(timeout, unit)) {
+ throw new TimeoutException("lock request did not complete in time");
+ }
+
+ return get();
+ }
+
+ /**
+ * Invokes the callback, indicating whether or not the lock was acquired.
+ *
+ * @throws IllegalStateException if the request was previously cancelled, has not yet
+ * completed, or if the callback has already been invoked
+ */
+ protected void invokeCallback() {
+ boolean locked;
+
+ switch (state.get()) {
+ case ACQUIRED:
+ locked = true;
+ break;
+ case DENIED:
+ locked = false;
+ break;
+ case CANCELLED:
+ throw new IllegalStateException("cancelled lock request callback");
+ default:
+ // only other choice is WAITING
+ throw new IllegalStateException("incomplete lock request callback");
+ }
+
+ Callback cb = callback.get();
+ if (cb == null || !callback.compareAndSet(cb, null)) {
+ throw new IllegalStateException("already invoked lock request callback");
+ }
+
+
+ // notify the callback
+ try {
+ cb.set(locked);
+
+ } catch (RuntimeException e) {
+ logger.info("lock request callback for resource {} owner {} threw an exception", resourceId, owner, e);
+ }
+ }
+
+ /**
+ * Makes an exception for when an argument is {@code null}.
+ *
+ * @param msg exception message
+ * @return a new Exception
+ */
+ public static IllegalArgumentException makeNullArgException(String msg) {
+ return new IllegalArgumentException(msg);
+ }
+}
diff --git a/policy-core/src/main/java/org/onap/policy/drools/core/lock/PolicyResourceLockFeatureAPI.java b/policy-core/src/main/java/org/onap/policy/drools/core/lock/PolicyResourceLockFeatureAPI.java
new file mode 100644
index 00000000..718ed5e9
--- /dev/null
+++ b/policy-core/src/main/java/org/onap/policy/drools/core/lock/PolicyResourceLockFeatureAPI.java
@@ -0,0 +1,190 @@
+/*
+ * ============LICENSE_START=======================================================
+ * api-resource-locks
+ * ================================================================================
+ * Copyright (C) 2018 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.onap.policy.drools.core.lock;
+
+import java.util.concurrent.Future;
+import org.onap.policy.drools.utils.OrderedService;
+import org.onap.policy.drools.utils.OrderedServiceImpl;
+
+/**
+ * Resource locks. Each lock has an "owner", which is intended to be unique across a
+ * single instance of a running PolicyEngine.
+ * <p>
+ * This interface provides a way to invoke optional features at various points in the
+ * code. At appropriate points in the application, the code iterates through this list,
+ * invoking these optional methods.
+ * <p>
+ * Implementers may choose to implement a level of locking appropriate to the application.
+ * For instance, they may choose to implement an engine-wide locking scheme, or they may
+ * choose to implement a global locking scheme (e.g., through a shared DB).
+ */
+public interface PolicyResourceLockFeatureAPI extends OrderedService {
+
+ /**
+ * 'FeatureAPI.impl.getList()' returns an ordered list of objects implementing the
+ * 'FeatureAPI' interface.
+ */
+ public static OrderedServiceImpl<PolicyResourceLockFeatureAPI> impl =
+ new OrderedServiceImpl<>(PolicyResourceLockFeatureAPI.class);
+
+ /**
+ * Callback that an implementer invokes when a lock is acquired (or denied),
+ * asynchronously. The implementer invokes the method to indicate that the lock was
+ * acquired (or denied).
+ */
+ @FunctionalInterface
+ public static interface Callback {
+
+ /**
+ *
+ * @param locked {@code true} if the lock was acquired, {@code false} if the lock
+ * was denied
+ */
+ public void set(boolean locked);
+ }
+
+ /**
+ * This method is called before a lock is acquired on a resource. If a callback is
+ * provided, and the implementer is unable to acquire the lock immediately, then the
+ * implementer will invoke the callback once the lock is acquired. If the implementer
+ * handled the request, then it will return a future, which may be in one of three
+ * states:
+ * <dl>
+ * <dt>isDone()=true and get()=true</dt>
+ * <dd>the lock has been acquired; the callback may or may not have been invoked</dd>
+ * <dt>isDone()=true and get()=false</dt>
+ * <dd>the lock request has been denied; the callback may or may not have been
+ * invoked</dd>
+ * <dt>isDone()=false</dt>
+ * <dd>the lock was not immediately available and a callback was provided. The
+ * callback will be invoked once the lock is acquired (or denied). In this case, the
+ * future may be used to cancel the request</dd>
+ * </dl>
+ *
+ * @param resourceId
+ * @param owner
+ * @param callback function to invoke, if the requester wishes to wait for the lock to
+ * come available, {@code null} to provide immediate replies
+ * @return a future for the lock, if the implementer handled the request, {@code null}
+ * if additional locking logic should be performed
+ * @throws IllegalStateException if the owner already holds the lock or is already in
+ * the queue to get the lock
+ */
+ public default Future<Boolean> beforeLock(String resourceId, String owner, Callback callback) {
+ return null;
+ }
+
+ /**
+ * This method is called after a lock for a resource has been acquired or denied. This
+ * may be invoked immediately, if the status can be determined immediately, or it may
+ * be invoked asynchronously, once the status has been determined.
+ *
+ * @param resourceId
+ * @param owner
+ * @param locked {@code true} if the lock was acquired, {@code false} if it was denied
+ * @return {@code true} if the implementer handled the request, {@code false}
+ * otherwise
+ */
+ public default boolean afterLock(String resourceId, String owner, boolean locked) {
+ return false;
+ }
+
+ /**
+ * This method is called before a lock on a resource is released.
+ *
+ * @param resourceId
+ * @param owner
+ * <dt>true</dt>
+ * <dd>the implementer handled the request and found the resource to be locked
+ * by the given owner; the resource was unlocked and no additional locking
+ * logic should be performed</dd>
+ * <dt>false</dt>
+ * <dd>the implementer handled the request and found the resource was not
+ * locked by given the owner; no additional locking logic should be
+ * performed</dd>
+ * <dt>null</dt>
+ * <dd>the implementer did not handle the request; additional locking logic
+ * <i>should be</i> performed
+ * </dl>
+ */
+ public default Boolean beforeUnlock(String resourceId, String owner) {
+ return null;
+ }
+
+ /**
+ * This method is called after a lock on a resource is released.
+ *
+ * @param resourceId
+ * @param owner
+ * @param unlocked {@code true} if the lock was released, {@code false} if the owner
+ * did not have a lock on the resource
+ * @return {@code true} if the implementer handled the request, {@code false}
+ * otherwise
+ */
+ public default boolean afterUnlock(String resourceId, String owner, boolean unlocked) {
+ return false;
+ }
+
+ /**
+ * This method is called before a check is made to determine if a resource is locked.
+ *
+ * @param resourceId
+ * @return
+ * <dl>
+ * <dt>true</dt>
+ * <dd>the implementer handled the request and found the resource to be
+ * locked; no additional locking logic should be performed</dd>
+ * <dt>false</dt>
+ * <dd>the implementer handled the request and found the resource was not
+ * locked; no additional locking logic should be performed</dd>
+ * <dt>null</dt>
+ * <dd>the implementer did not handle the request; additional locking logic
+ * <i>should be</i> performed
+ * </dl>
+ */
+ public default Boolean beforeIsLocked(String resourceId) {
+ return null;
+ }
+
+ /**
+ * This method is called before a check is made to determine if a particular owner
+ * holds the lock on a resource.
+ *
+ * @param resourceId
+ * @param owner
+ * @return
+ * <dl>
+ * <dt>true</dt>
+ * <dd>the implementer handled the request and found the resource to be locked
+ * by the given owner; no additional locking logic should be performed</dd>
+ * <dt>false</dt>
+ * <dd>the implementer handled the request and found the resource was not
+ * locked by given the owner; no additional locking logic should be
+ * performed</dd>
+ * <dt>null</dt>
+ * <dd>the implementer did not handle the request; additional locking logic
+ * <i>should be</i> performed
+ * </dl>
+ */
+ public default Boolean beforeIsLockedBy(String resourceId, String owner) {
+ return null;
+ }
+}
diff --git a/policy-endpoints/src/main/java/org/onap/policy/drools/http/server/internal/JettyJerseyServer.java b/policy-endpoints/src/main/java/org/onap/policy/drools/http/server/internal/JettyJerseyServer.java
index f882c927..4f7c151e 100644
--- a/policy-endpoints/src/main/java/org/onap/policy/drools/http/server/internal/JettyJerseyServer.java
+++ b/policy-endpoints/src/main/java/org/onap/policy/drools/http/server/internal/JettyJerseyServer.java
@@ -2,7 +2,7 @@
* ============LICENSE_START=======================================================
* policy-endpoints
* ================================================================================
- * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * Copyright (C) 2017-2018 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.
@@ -129,12 +129,7 @@ public class JettyJerseyServer extends JettyServletServer {
String hostname = this.connector.getHost();
if (hostname == null || hostname.isEmpty() || hostname.equals(NetworkUtil.IPv4_WILDCARD_ADDRESS)) {
- try {
- hostname = InetAddress.getLocalHost().getHostName();
- } catch (UnknownHostException e) {
- logger.warn("{}: can't resolve connector's hostname: {}", this, hostname, e);
- hostname = "localhost";
- }
+ hostname = NetworkUtil.getHostname();
}
swaggerServlet.setInitParameter(SWAGGER_API_BASEPATH,
diff --git a/policy-management/src/main/java/org/onap/policy/drools/server/restful/RestManager.java b/policy-management/src/main/java/org/onap/policy/drools/server/restful/RestManager.java
index cd1edca5..15c97237 100644
--- a/policy-management/src/main/java/org/onap/policy/drools/server/restful/RestManager.java
+++ b/policy-management/src/main/java/org/onap/policy/drools/server/restful/RestManager.java
@@ -64,7 +64,7 @@ import org.onap.policy.drools.protocol.configuration.ControllerConfiguration;
import org.onap.policy.drools.protocol.configuration.PdpdConfiguration;
import org.onap.policy.drools.system.PolicyController;
import org.onap.policy.drools.system.PolicyEngine;
-import org.onap.policy.drools.utils.LoggerUtil;
+import org.onap.policy.drools.utils.logging.LoggerUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
diff --git a/policy-management/src/main/java/org/onap/policy/drools/system/Main.java b/policy-management/src/main/java/org/onap/policy/drools/system/Main.java
index 314bbc04..43216000 100644
--- a/policy-management/src/main/java/org/onap/policy/drools/system/Main.java
+++ b/policy-management/src/main/java/org/onap/policy/drools/system/Main.java
@@ -2,7 +2,7 @@
* ============LICENSE_START=======================================================
* policy-management
* ================================================================================
- * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * Copyright (C) 2017-2018 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.
@@ -20,14 +20,14 @@
package org.onap.policy.drools.system;
-import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Properties;
import org.onap.policy.drools.persistence.SystemPersistence;
import org.onap.policy.drools.properties.PolicyProperties;
-import org.onap.policy.drools.utils.LoggerUtil;
+import org.onap.policy.drools.utils.logging.LoggerUtil;
+import org.onap.policy.drools.utils.logging.MDCTransaction;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -56,7 +56,6 @@ public class Main {
* main
*
* @param args program arguments
- * @throws IOException
*/
public static void main(String[] args) {
@@ -110,16 +109,23 @@ public class Main {
/* 2. Start the Engine with the basic services only (no Policy Controllers) */
+ MDCTransaction trans =
+ MDCTransaction.newTransaction(null, null).setServiceName(Main.class.getSimpleName()).
+ setTargetEntity("engine").setTargetServiceName("start");
try {
final boolean success = PolicyEngine.manager.start();
if (!success) {
- logger.warn("Main: {} has been partially started", PolicyEngine.manager);
+ trans.setStatusCode(false).setResponseDescription("partial start").flush();
+ logger.warn(LoggerUtil.TRANSACTION_LOG_MARKER, "Main: {} has been partially started", PolicyEngine.manager);
+ } else {
+ trans.setStatusCode(true).transaction();
}
} catch (final IllegalStateException e) {
- logger.warn("Main: cannot start {} (bad state) because of {}", PolicyEngine.manager,
- e.getMessage(), e);
+ trans.setStatusCode(false).setResponseCode(e.getClass().getSimpleName()).setResponseDescription(e.getMessage()).flush();
+ logger.warn(LoggerUtil.TRANSACTION_LOG_MARKER, "Main: cannot start {} (bad state) because of {}", PolicyEngine.manager, e.getMessage(), e);
} catch (final Exception e) {
- logger.warn("Main: cannot start {} because of {}", PolicyEngine.manager, e.getMessage(), e);
+ trans.setStatusCode(false).setResponseCode(e.getClass().getSimpleName()).setResponseDescription(e.getMessage()).flush();
+ logger.warn(LoggerUtil.TRANSACTION_LOG_MARKER, "Main: cannot start {} because of {}", PolicyEngine.manager, e.getMessage(), e);
System.exit(1);
}
@@ -130,14 +136,24 @@ public class Main {
final String controllerName =
controllerProperties.getProperty(PolicyProperties.PROPERTY_CONTROLLER_NAME);
try {
+ trans =
+ MDCTransaction.newTransaction(null, null).setServiceName(Main.class.getSimpleName()).
+ setTargetEntity("controller:" + controllerName).setTargetServiceName("start");
+
final PolicyController controller =
PolicyEngine.manager.createPolicyController(controllerName, controllerProperties);
controller.start();
+
+ trans.setStatusCode(true).
+ setResponseDescription(controller.getDrools().getCanonicalSessionNames().toString()).
+ transaction();
} catch (final Exception e) {
- logger.error("Main: cannot instantiate policy-controller {} because of {}", controllerName,
- e.getMessage(), e);
+ trans.setStatusCode(false).setResponseCode(e.getClass().getSimpleName()).setResponseDescription(e.getMessage()).flush();
+ logger.error(LoggerUtil.TRANSACTION_LOG_MARKER, "Main: cannot instantiate policy-controller {} because of {}",
+ controllerName, e.getMessage(), e);
} catch (final LinkageError e) {
- logger.warn("Main: cannot instantiate policy-controller {} (linkage) because of {}",
+ trans.setStatusCode(false).setResponseCode(e.getClass().getSimpleName()).setResponseDescription(e.getMessage()).flush();
+ logger.warn(LoggerUtil.TRANSACTION_LOG_MARKER, "Main: cannot instantiate policy-controller {} (linkage) because of {}",
controllerName, e.getMessage(), e);
}
}
diff --git a/policy-management/src/main/java/org/onap/policy/drools/system/PolicyEngine.java b/policy-management/src/main/java/org/onap/policy/drools/system/PolicyEngine.java
index a1fee763..d7275578 100644
--- a/policy-management/src/main/java/org/onap/policy/drools/system/PolicyEngine.java
+++ b/policy-management/src/main/java/org/onap/policy/drools/system/PolicyEngine.java
@@ -44,6 +44,8 @@ import org.onap.policy.drools.protocol.coders.EventProtocolCoder;
import org.onap.policy.drools.protocol.configuration.ControllerConfiguration;
import org.onap.policy.drools.protocol.configuration.PdpdConfiguration;
import org.onap.policy.drools.server.restful.RestManager;
+import org.onap.policy.drools.utils.logging.LoggerUtil;
+import org.onap.policy.drools.utils.logging.MDCTransaction;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -139,7 +141,6 @@ public interface PolicyEngine extends Startable, Lockable, TopicListener {
/**
* registers a new Policy Controller with the Policy Engine initialized per properties.
*
- * @param controller name
* @param properties properties to initialize the Policy Controller
* @throws IllegalArgumentException when invalid or insufficient properties are provided
* @throws IllegalStateException when the engine is in a state where this operation is not
@@ -276,7 +277,6 @@ public interface PolicyEngine extends Startable, Lockable, TopicListener {
/**
* Attempts the dispatching of an "event" object over communication infrastructure "busType"
*
- * @param eventBus Communication infrastructure identifier
* @param topic topic
* @param event the event object to send
*
@@ -292,7 +292,6 @@ public interface PolicyEngine extends Startable, Lockable, TopicListener {
/**
* Attempts the dispatching of an "event" object over communication infrastructure "busType"
*
- * @param eventBus Communication infrastructure enum
* @param topic topic
* @param event the event object to send
*
@@ -308,7 +307,6 @@ public interface PolicyEngine extends Startable, Lockable, TopicListener {
/**
* Attempts delivering of an String over communication infrastructure "busType"
*
- * @param eventBus Communication infrastructure identifier
* @param topic topic
* @param event the event object to send
*
@@ -591,12 +589,22 @@ private static final String ENGINE_LOCKED_MSG = "Policy Engine is locked";
final String entity = config.getEntity();
+ MDCTransaction mdcTrans = MDCTransaction.newTransaction(config.getRequestID(), "brmsgw");
+ if (this.getSources().size() == 1) {
+ Topic topic = this.getSources().get(0);
+ mdcTrans.setServiceName(topic.getTopic()).setRemoteHost(topic.getServers().toString()).
+ setTargetEntity(config.getEntity());
+ }
+
switch (entity) {
- case PdpdConfiguration.CONFIG_ENTITY_CONTROLLER:
- return controllerConfig(config);
+ case PdpdConfiguration.CONFIG_ENTITY_CONTROLLER:
+ boolean success = controllerConfig(config);
+ mdcTrans.resetSubTransaction().setStatusCode(success).transaction();
+ return success;
default:
final String msg = "Configuration Entity is not supported: " + entity;
- logger.warn(msg);
+ mdcTrans.resetSubTransaction().setStatusCode(false).setResponseDescription(msg).flush();
+ logger.warn(LoggerUtil.TRANSACTION_LOG_MARKER_NAME, msg);
throw new IllegalArgumentException(msg);
}
}
@@ -613,11 +621,18 @@ private static final String ENGINE_LOCKED_MSG = "Policy Engine is locked";
}
for (final ControllerConfiguration configController : configControllers) {
+ MDCTransaction mdcTrans =
+ MDCTransaction.newSubTransaction(null).setTargetEntity(configController.getName()).
+ setTargetServiceName(configController.getOperation()).
+ setTargetVirtualEntity(configController.getDrools().toString());
try {
final PolicyController policyController = this.updatePolicyController(configController);
policyControllers.add(policyController);
+ mdcTrans.setStatusCode(true).transaction();
} catch (final Exception e) {
- logger.error("{}: cannot update-policy-controllers because of {}", this, e.getMessage(), e);
+ mdcTrans.setStatusCode(false).setResponseCode(e.getClass().getName()).
+ setResponseDescription(e.getMessage()).flush();
+ logger.error(LoggerUtil.TRANSACTION_LOG_MARKER_NAME, "{}: cannot update-policy-controllers because of {}", this, e.getMessage(), e);
}
}
@@ -1423,18 +1438,23 @@ private static final String ENGINE_LOCKED_MSG = "Policy Engine is locked";
/* only this one supported for now */
final List<ControllerConfiguration> configControllers = config.getControllers();
if (configControllers == null || configControllers.isEmpty()) {
- if (logger.isInfoEnabled())
- logger.info("No controller configuration provided: " + config);
+ logger.info("No controller configuration provided: {}" + config);
return false;
}
- final List<PolicyController> policyControllers =
- this.updatePolicyControllers(config.getControllers());
- if (policyControllers == null || policyControllers.isEmpty())
- return false;
- else if (policyControllers.size() == configControllers.size())
- return true;
- return false;
+ final List<PolicyController> policyControllers = this.updatePolicyControllers(config.getControllers());
+
+ boolean success;
+
+ if (policyControllers == null || policyControllers.isEmpty()) {
+ success = false;
+ } else if (policyControllers.size() == configControllers.size()) {
+ success = true;
+ } else {
+ success = false;
+ }
+
+ return success;
}
@Override
diff --git a/policy-management/src/main/server-gen/bin/policy-management-controller b/policy-management/src/main/server-gen/bin/policy-management-controller
index a9f8ce0d..cc6a8c7d 100644
--- a/policy-management/src/main/server-gen/bin/policy-management-controller
+++ b/policy-management/src/main/server-gen/bin/policy-management-controller
@@ -4,7 +4,7 @@
# ============LICENSE_START=======================================================
# ONAP POLICY
# ================================================================================
-# Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+# Copyright (C) 2017-2018 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.
@@ -42,11 +42,11 @@ function um_start() {
RETVAL=0
return
fi
- mkdir -p $_DIR/logs
- if [ -e $_DIR/logs/$PNAME.out.1 ]; then mv $_DIR/logs/$PNAME.out.1 $_DIR/logs/$PNAME.out.2; fi
- if [ -e $_DIR/logs/$PNAME.err.1 ]; then mv $_DIR/logs/$PNAME.err.1 $_DIR/logs/$PNAME.err.2; fi
- if [ -e $_DIR/logs/$PNAME.out ]; then mv $_DIR/logs/$PNAME.out $_DIR/logs/$PNAME.out.1; fi
- if [ -e $_DIR/logs/$PNAME.err ]; then mv $_DIR/logs/$PNAME.err $_DIR/logs/$PNAME.err.1; fi
+ mkdir -p $_LOGS
+ if [ -e $_LOGS/$PNAME.out.1 ]; then mv $_LOGS/$PNAME.out.1 $_LOGS/$PNAME.out.2; fi
+ if [ -e $_LOGS/$PNAME.err.1 ]; then mv $_LOGS/$PNAME.err.1 $_LOGS/$PNAME.err.2; fi
+ if [ -e $_LOGS/$PNAME.out ]; then mv $_LOGS/$PNAME.out $_LOGS/$PNAME.out.1; fi
+ if [ -e $_LOGS/$PNAME.err ]; then mv $_LOGS/$PNAME.err $_LOGS/$PNAME.err.1; fi
CP=$(ls $_DIR/lib/*.jar | xargs -I X printf ":%s" X)
# If 'system.properties' exists, convert it into JVM arguments.
@@ -66,7 +66,7 @@ function um_start() {
# to subprocesses
exec {cfg}>&-
fi
- nohup $JAVA_HOME/bin/java -Dkie.maven.settings.custom=$_DIR/config/kie_settings.xml -Dlog4j.configuration=file:$_DIR/config/log4j.properties -cp $_DIR/config:$_DIR/lib:$CP "${systemProperties[@]}" "$@" $CLASS > >( while read line; do echo "$(date): ${line}"; done > $_DIR/logs/$PNAME.out) 2> >( while read line; do echo "$(date): ${line}"; done > $_DIR/logs/$PNAME.err) &
+ nohup $JAVA_HOME/bin/java -Dkie.maven.settings.custom=$_DIR/config/kie_settings.xml -Dlog4j.configuration=file:$_DIR/config/log4j.properties -cp $_DIR/config:$_DIR/lib:$CP "${systemProperties[@]}" "$@" $CLASS > >( while read line; do echo "$(date): ${line}"; done > $_LOGS/$PNAME.out) 2> >( while read line; do echo "$(date): ${line}"; done > $_LOGS/$PNAME.err) &
_PID=$!
echo $_PID > $_PIDFILE
@@ -167,6 +167,12 @@ function update_monitor() {
# main
_DIR=${POLICY_HOME}
+_LOGS=${POLICY_LOGS}
+
+if [[ -z ${POLICY_LOGS} ]]; then
+ _LOGS="${POLICY_HOME}"/logs
+fi
+
CONTROLLER=policy-management-controller
RETVAL=0
diff --git a/policy-management/src/main/server/config/logback.xml b/policy-management/src/main/server/config/logback.xml
index 1801c43a..538fcf80 100644
--- a/policy-management/src/main/server/config/logback.xml
+++ b/policy-management/src/main/server/config/logback.xml
@@ -2,7 +2,7 @@
============LICENSE_START=======================================================
policy-management
================================================================================
- Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ Copyright (C) 2017-2018 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.
@@ -20,30 +20,33 @@
<configuration scan="true" scanPeriod="30 seconds" debug="false">
- <property name="logDir" value="logs" />
+ <property name="logDir" value="${POLICY_LOGS}" />
<property name="errorLog" value="error" />
<property name="debugLog" value="debug" />
<property name="networkLog" value="network" />
- <property name="debugPattern" value="[%date|%level|%logger{0}|%thread] %msg%n" />
+ <property name="metricLog" value="metric" />
+ <property name="transactionLog" value="audit" />
+
+ <property name="debugPattern" value="[%d{yyyy-MM-dd'T'HH:mm:ss.SSS+00:00, UTC}|%level|%logger{0}|%thread] %msg%n" />
<property name="errorPattern" value="${debugPattern}" />
- <property name="networkPattern" value="[%d|%t]%m%n" />
+ <property name="networkPattern" value="[%d{yyyy-MM-dd'T'HH:mm:ss.SSS+00:00, UTC}|%t]%m%n" />
+
+ <property name="metricPattern" value="%X{RequestID}|%X{InvocationID}|%X{ServiceName}|%X{PartnerName}|%X{BeginTimestamp}|%X{EndTimestamp}|%X{ElapsedTime}|%X{ServiceInstanceID}|%X{VirtualServerName}|%X{StatusCode}|%X{ResponseCode}|%X{ResponseDescription}|%X{InstanceUUID}|%X{Severity}|%X{TargetEntity}|%X{TargetServiceName}|%X{Server}|%X{ServerIPAddress}|%X{ServerFQDN}|%X{ClientIPAddress}|%X{ProcessKey}|%X{RemoteHost}|%X{AlertSeverity}|%X{TargetVirtualEntity}|%level|%thread| %msg%n"/>
+ <property name="transactionPattern" value="${metricPattern}" />
<appender name="ErrorOut" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${logDir}/${errorLog}.log</file>
- <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
- <fileNamePattern>${logDir}/${errorLog}.%i.log.zip</fileNamePattern>
- <minIndex>1</minIndex>
- <maxIndex>5</maxIndex>
+ <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
+ <fileNamePattern>${logDir}/${errorLog}.%d{yyyy-MM-dd}.%i.log.zip</fileNamePattern>
+ <maxFileSize>50MB</maxFileSize>
+ <maxHistory>30</maxHistory>
+ <totalSizeCap>10GB</totalSizeCap>
</rollingPolicy>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>WARN</level>
</filter>
- <triggeringPolicy
- class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
- <maxFileSize>15MB</maxFileSize>
- </triggeringPolicy>
<encoder>
<pattern>${errorPattern}</pattern>
</encoder>
@@ -55,14 +58,12 @@
<appender name="DebugOut" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${logDir}/${debugLog}.log</file>
- <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
- <fileNamePattern>${logDir}/${debugLog}.%i.log.zip</fileNamePattern>
- <minIndex>1</minIndex>
- <maxIndex>9</maxIndex>
+ <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
+ <fileNamePattern>${logDir}/${debugLog}.%d{yyyy-MM-dd}.%i.log.zip</fileNamePattern>
+ <maxFileSize>50MB</maxFileSize>
+ <maxHistory>30</maxHistory>
+ <totalSizeCap>10GB</totalSizeCap>
</rollingPolicy>
- <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
- <maxFileSize>20MB</maxFileSize>
- </triggeringPolicy>
<encoder>
<pattern>${debugPattern}</pattern>
</encoder>
@@ -74,14 +75,12 @@
<appender name="NetworkOut" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${logDir}/${networkLog}.log</file>
- <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
- <fileNamePattern>${logDir}/${networkLog}.%i.log.zip</fileNamePattern>
- <minIndex>1</minIndex>
- <maxIndex>9</maxIndex>
+ <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
+ <fileNamePattern>${logDir}/${networkLog}.%d{yyyy-MM-dd}.%i.log.zip</fileNamePattern>
+ <maxFileSize>50MB</maxFileSize>
+ <maxHistory>30</maxHistory>
+ <totalSizeCap>10GB</totalSizeCap>
</rollingPolicy>
- <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
- <maxFileSize>15MB</maxFileSize>
- </triggeringPolicy>
<encoder>
<pattern>${networkPattern}</pattern>
</encoder>
@@ -91,6 +90,42 @@
<appender-ref ref="NetworkOut" />
</appender>
+ <appender name="MetricOut" class="ch.qos.logback.core.rolling.RollingFileAppender">
+ <file>${logDir}/${metricLog}.log</file>
+ <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
+ <fileNamePattern>${logDir}/${metricLog}.%d{yyyy-MM-dd}.%i.log.zip</fileNamePattern>
+ <maxFileSize>50MB</maxFileSize>
+ <maxHistory>30</maxHistory>
+ <totalSizeCap>10GB</totalSizeCap>
+ </rollingPolicy>
+ <filter class="org.onap.policy.drools.utils.logging.LoggerMarkerFilter$MetricLoggerMarkerFilter" />
+ <encoder>
+ <pattern>${metricPattern}</pattern>
+ </encoder>
+ </appender>
+
+ <appender name="AsyncMetricOut" class="ch.qos.logback.classic.AsyncAppender">
+ <appender-ref ref="MetricOut" />
+ </appender>
+
+ <appender name="TransactionOut" class="ch.qos.logback.core.rolling.RollingFileAppender">
+ <file>${logDir}/${transactionLog}.log</file>
+ <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
+ <fileNamePattern>${logDir}/${transactionLog}.%d{yyyy-MM-dd}.%i.log.zip</fileNamePattern>
+ <maxFileSize>50MB</maxFileSize>
+ <maxHistory>30</maxHistory>
+ <totalSizeCap>10GB</totalSizeCap>
+ </rollingPolicy>
+ <filter class="org.onap.policy.drools.utils.logging.LoggerMarkerFilter$TransactionLoggerMarkerFilter" />
+ <encoder>
+ <pattern>${transactionPattern}</pattern>
+ </encoder>
+ </appender>
+
+ <appender name="AsyncTransactionOut" class="ch.qos.logback.classic.AsyncAppender">
+ <appender-ref ref="TransactionOut" />
+ </appender>
+
<logger name="network" level="INFO" additivity="false">
<appender-ref ref="AsyncNetworkOut" />
</logger>
@@ -102,6 +137,8 @@
<root level="INFO">
<appender-ref ref="AsyncDebugOut" />
<appender-ref ref="AsyncErrorOut" />
+ <appender-ref ref="AsyncMetricOut" />
+ <appender-ref ref="AsyncTransactionOut" />
</root>
</configuration>
diff --git a/policy-utils/src/main/java/org/onap/policy/drools/utils/LoggerUtil.java b/policy-utils/src/main/java/org/onap/policy/drools/utils/LoggerUtil.java
deleted file mode 100644
index 681a2b20..00000000
--- a/policy-utils/src/main/java/org/onap/policy/drools/utils/LoggerUtil.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*-
- * ============LICENSE_START=======================================================
- * ONAP
- * ================================================================================
- * 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.onap.policy.drools.utils;
-
-import org.slf4j.LoggerFactory;
-
-import ch.qos.logback.classic.LoggerContext;
-
-/**
- * Loger Utils
- */
-public class LoggerUtil {
-
- /**
- * Root logger
- */
- public static final String ROOT_LOGGER = "ROOT";
-
- private LoggerUtil() {
- // Empty constructor
- }
-
- /**
- * set the log level of a logger
- *
- * @param loggerName logger name
- * @param loggerLevel logger level
- */
- public static String setLevel(String loggerName, String loggerLevel) {
- if (!(LoggerFactory.getILoggerFactory() instanceof LoggerContext))
- throw new IllegalStateException("The SLF4J logger factory is not configured for logback");
-
- final LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory();
- final ch.qos.logback.classic.Logger logger = context.getLogger(loggerName);
- if (logger == null)
- throw new IllegalArgumentException("no logger " + loggerName);
-
- logger.setLevel(ch.qos.logback.classic.Level.toLevel(loggerLevel));
- return logger.getLevel().toString();
- }
-}
diff --git a/policy-utils/src/main/java/org/onap/policy/drools/utils/NetworkUtil.java b/policy-utils/src/main/java/org/onap/policy/drools/utils/NetworkUtil.java
index 6734226d..229927e5 100644
--- a/policy-utils/src/main/java/org/onap/policy/drools/utils/NetworkUtil.java
+++ b/policy-utils/src/main/java/org/onap/policy/drools/utils/NetworkUtil.java
@@ -2,7 +2,7 @@
* ============LICENSE_START=======================================================
* ONAP
* ================================================================================
- * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * Copyright (C) 2017-2018 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.
@@ -22,8 +22,10 @@ package org.onap.policy.drools.utils;
import java.io.IOException;
import java.net.ConnectException;
+import java.net.InetAddress;
import java.net.Socket;
+import java.net.UnknownHostException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -32,42 +34,80 @@ import org.slf4j.LoggerFactory;
*/
public class NetworkUtil {
- public static final Logger logger = LoggerFactory.getLogger(NetworkUtil.class.getName());
-
- /**
- * IPv4 Wildcard IP address
- */
- public static final String IPv4_WILDCARD_ADDRESS = "0.0.0.0";
-
- private NetworkUtil() {
- // Empty constructor
- }
-
- /**
- * try to connect to $host:$port $retries times while we are getting connection failures.
- *
- * @param host host
- * @param port port
- * @param retries number of attempts
- * @return true is port is open, false otherwise
- * @throws InterruptedException if execution has been interrupted
- */
- public static boolean isTcpPortOpen(String host, int port, int retries, long interval)
- throws InterruptedException, IOException {
- int retry = 0;
- while (retry < retries) {
- try (Socket s = new Socket(host, port)) {
- logger.debug("{}:{} connected - retries={} interval={}", host, port, retries, interval);
- return true;
- } catch (final ConnectException e) {
- retry++;
- logger.trace("{}:{} connected - retries={} interval={}", host, port, retries, interval, e);
- Thread.sleep(interval);
- }
+ public static final Logger logger = LoggerFactory.getLogger(NetworkUtil.class.getName());
+
+ /**
+ * IPv4 Wildcard IP address
+ */
+ public static final String IPv4_WILDCARD_ADDRESS = "0.0.0.0";
+
+ private NetworkUtil() {
+ // Empty constructor
+ }
+
+ /**
+ * try to connect to $host:$port $retries times while we are getting connection failures.
+ *
+ * @param host host
+ * @param port port
+ * @param retries number of attempts
+ * @return true is port is open, false otherwise
+ * @throws InterruptedException if execution has been interrupted
+ */
+ public static boolean isTcpPortOpen(String host, int port, int retries, long interval)
+ throws InterruptedException, IOException {
+ int retry = 0;
+ while (retry < retries) {
+ try (Socket s = new Socket(host, port)) {
+ logger.debug("{}:{} connected - retries={} interval={}", host, port, retries, interval);
+ return true;
+ } catch (final ConnectException e) {
+ retry++;
+ logger.trace("{}:{} connected - retries={} interval={}", host, port, retries, interval, e);
+ Thread.sleep(interval);
+ }
+ }
+
+ logger.warn("{}:{} closed = retries={} interval={}", host, port, retries, interval);
+ return false;
+ }
+
+ /**
+ * gets host name
+ *
+ * @return host name
+ */
+ public static String getHostname() {
+
+ String hostname = System.getenv("HOSTNAME");
+ if (hostname != null && !hostname.isEmpty()) {
+ return hostname;
+ }
+
+ try {
+ return InetAddress.getLocalHost().getHostName();
+ } catch (UnknownHostException e) {
+ logger.warn("cannot resolve local hostname", e);
+ /* continue */
+ }
+
+ return "localhost";
}
- logger.warn("{}:{} closed = retries={} interval={}", host, port, retries, interval);
- return false;
- }
+ /**
+ * gets host's IP
+ *
+ * @return host IP
+ */
+ public static String getHostIp() {
+
+ try {
+ return InetAddress.getLocalHost().getHostAddress();
+ } catch (UnknownHostException e) {
+ logger.warn("cannot resolve local hostname", e);
+ /* continue */
+ }
+ return "127.0.0.1";
+ }
}
diff --git a/policy-utils/src/main/java/org/onap/policy/drools/utils/logging/LoggerMarkerFilter.java b/policy-utils/src/main/java/org/onap/policy/drools/utils/logging/LoggerMarkerFilter.java
new file mode 100644
index 00000000..19414d31
--- /dev/null
+++ b/policy-utils/src/main/java/org/onap/policy/drools/utils/logging/LoggerMarkerFilter.java
@@ -0,0 +1,77 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP
+ * ================================================================================
+ * Copyright (C) 2017-2018 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.onap.policy.drools.utils.logging;
+
+import ch.qos.logback.classic.spi.ILoggingEvent;
+import ch.qos.logback.core.filter.AbstractMatcherFilter;
+import ch.qos.logback.core.spi.FilterReply;
+import org.slf4j.Marker;
+
+/**
+ * Logger Marker Filters to be used in logback.xml configuration
+ * to accept/deny metric or transaction (audit) events
+ */
+public abstract class LoggerMarkerFilter extends AbstractMatcherFilter<ILoggingEvent> {
+
+ protected final Marker marker;
+
+ public LoggerMarkerFilter(Marker marker) {
+ this.marker = marker;
+ }
+
+ @Override
+ public FilterReply decide(ILoggingEvent event) {
+
+ if (this.marker == null || !isStarted()) {
+ return FilterReply.DENY;
+ }
+
+ if (event == null || event.getMarker() == null) {
+ return FilterReply.DENY;
+ }
+
+ if (event.getMarker().equals(marker)) {
+ return FilterReply.ACCEPT;
+ } else {
+ return FilterReply.DENY;
+ }
+ }
+
+ /**
+ * Metric Logger Marker Filter
+ */
+ public static class MetricLoggerMarkerFilter extends LoggerMarkerFilter {
+
+ public MetricLoggerMarkerFilter() {
+ super(LoggerUtil.METRIC_LOG_MARKER);
+ }
+
+ }
+
+ /**
+ * Transaction Logger Marker Filter
+ */
+ public static class TransactionLoggerMarkerFilter extends LoggerMarkerFilter {
+
+ public TransactionLoggerMarkerFilter() {
+ super(LoggerUtil.TRANSACTION_LOG_MARKER);
+ }
+ }
+}
diff --git a/policy-utils/src/main/java/org/onap/policy/drools/utils/logging/LoggerUtil.java b/policy-utils/src/main/java/org/onap/policy/drools/utils/logging/LoggerUtil.java
new file mode 100644
index 00000000..26b35702
--- /dev/null
+++ b/policy-utils/src/main/java/org/onap/policy/drools/utils/logging/LoggerUtil.java
@@ -0,0 +1,83 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP
+ * ================================================================================
+ * Copyright (C) 2017-2018 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.onap.policy.drools.utils.logging;
+
+import org.slf4j.LoggerFactory;
+
+import ch.qos.logback.classic.LoggerContext;
+import org.slf4j.Marker;
+import org.slf4j.MarkerFactory;
+
+/**
+ * Loger Utils
+ */
+public class LoggerUtil {
+
+ /**
+ * Root logger
+ */
+ public static final String ROOT_LOGGER = "ROOT";
+
+ /**
+ * Metric Log Marker Name
+ */
+ public static final String METRIC_LOG_MARKER_NAME = "metric";
+
+ /**
+ * Transaction Log Marker Name
+ */
+ public static final String TRANSACTION_LOG_MARKER_NAME = "transaction";
+
+ /**
+ * Marks a logging record as a metric
+ */
+ public static final Marker METRIC_LOG_MARKER = MarkerFactory.getMarker(METRIC_LOG_MARKER_NAME);
+
+ /**
+ * Marks a logging record as an end-to-end transaction
+ */
+ public static final Marker TRANSACTION_LOG_MARKER = MarkerFactory.getMarker(TRANSACTION_LOG_MARKER_NAME);
+
+
+ private LoggerUtil() {
+ // Empty constructor
+ }
+
+ /**
+ * set the log level of a logger
+ *
+ * @param loggerName logger name
+ * @param loggerLevel logger level
+ */
+ public static String setLevel(String loggerName, String loggerLevel) {
+ if (!(LoggerFactory.getILoggerFactory() instanceof LoggerContext)) {
+ throw new IllegalStateException("The SLF4J logger factory is not configured for logback");
+ }
+
+ final LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory();
+ final ch.qos.logback.classic.Logger logger = context.getLogger(loggerName);
+ if (logger == null) {
+ throw new IllegalArgumentException("no logger " + loggerName);
+ }
+
+ logger.setLevel(ch.qos.logback.classic.Level.toLevel(loggerLevel));
+ return logger.getLevel().toString();
+ }
+}
diff --git a/policy-utils/src/main/java/org/onap/policy/drools/utils/logging/MDCTransaction.java b/policy-utils/src/main/java/org/onap/policy/drools/utils/logging/MDCTransaction.java
new file mode 100644
index 00000000..1a27dde6
--- /dev/null
+++ b/policy-utils/src/main/java/org/onap/policy/drools/utils/logging/MDCTransaction.java
@@ -0,0 +1,1194 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * policy-utils
+ * ================================================================================
+ * Copyright (C) 2018 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.
+ */
+
+package org.onap.policy.drools.utils.logging;
+
+import java.text.SimpleDateFormat;
+import java.time.Duration;
+import java.time.Instant;
+import java.util.Date;
+import java.util.UUID;
+import org.onap.policy.drools.utils.NetworkUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.slf4j.MDC;
+
+/**
+ * MDC Transaction Utility Class.
+ *
+ * There is an implicit 2-level tree of Transactions in ONAP: transactions
+ * and subtransactions.
+ *
+ * 1. The top level transaction relates to the overarching transaction
+ * id (ie. RequestId) and should be made available to subtransactions
+ * for reuse in the ThreadLocal MDC structure.
+ *
+ * This is the data to be inherited and common to all subtransactions
+ * (not a common case but could be modified by subtransactions):
+ *
+ * Request ID
+ * Virtual Server Name
+ * Partner Name
+ * Server
+ * Server IP Address
+ * Server FQDN
+ *
+ * 2. The second level at the leaves is formed by subtransactions and the key
+ * identifier is the invocation id.
+ *
+ * Begin Timestamp
+ * End Timestamp
+ * Elapsed Time
+ * Service Instance ID
+ * Service Name
+ * Status Code
+ * Response Code
+ * Response Description
+ * Instance UUID
+ * Severity
+ * Target Entity
+ * Target Service Name
+ * Server
+ * Server IP Address
+ * Server FQDN
+ * Client IP Address
+ * Process Key
+ * Remote Host
+ * Alert Severity
+ * Target Virtual Entity
+ *
+ *
+ * The naming convention for the fields must match the naming given at
+ *
+ * https://wiki.onap.org/pages/viewpage.action?pageId=20087036
+ */
+public interface MDCTransaction {
+ /*
+ * The fields must match the naming given at
+ * https://wiki.onap.org/pages/viewpage.action?pageId=20087036
+ */
+
+ /**
+ * End to end transaction ID. Subtransactions will inherit this value from the transaction.
+ */
+ String REQUEST_ID = "RequestID";
+
+ /**
+ * Invocation ID, ie. SubTransaction ID.
+ */
+ String INVOCATION_ID = "InvocationID";
+
+ /**
+ * Service Name. Both transactions and subtransactions will have its own copy.
+ */
+ String SERVICE_NAME = "ServiceName";
+
+ /**
+ * Partner Name Subtransactions will inherit this value from the transaction.
+ */
+ String PARTNER_NAME = "PartnerName";
+
+ /**
+ * Start Timestamp. Both transactions and subtransactions will have its own copy.
+ */
+ String BEGIN_TIMESTAMP = "BeginTimestamp";
+
+ /**
+ * End Timestamp. Both transactions and subtransactions will have its own copy.
+ */
+ String END_TIMESTAMP = "EndTimestamp";
+
+ /**
+ * Elapsed Time. Both transactions and subtransactions will have its own copy.
+ */
+ String ELAPSED_TIME = "ElapsedTime";
+
+ /**
+ * Elapsed Time. Both transactions and subtransactions will have its own copy.
+ */
+ String SERVICE_INSTANCE_ID = "ServiceInstanceID";
+
+ /**
+ * Virtual Server Name. Subtransactions will inherit this value from the transaction.
+ */
+ String VIRTUAL_SERVER_NAME = "VirtualServerName";
+
+ /**
+ * Status Code Both transactions and subtransactions will have its own copy.
+ */
+ String STATUS_CODE = "StatusCode";
+
+ /**
+ * Response Code Both transactions and subtransactions will have its own copy.
+ */
+ String RESPONSE_CODE = "ResponseCode";
+
+ /**
+ * Response Description Both transactions and subtransactions will have its own copy.
+ */
+ String RESPONSE_DESCRIPTION = "ResponseDescription";
+
+ /**
+ * Instance UUID Both transactions and subtransactions will have its own copy.
+ */
+ String INSTANCE_UUID = "InstanceUUID";
+
+ /**
+ * Severity Both transactions and subtransactions will have its own copy.
+ */
+ String SEVERITY = "Severity";
+
+ /**
+ * Target Entity Both transactions and subtransactions will have its own copy.
+ */
+ String TARGET_ENTITY = "TargetEntity";
+
+ /**
+ * Target Service Name Both transactions and subtransactions will have its own copy.
+ */
+ String TARGET_SERVICE_NAME = "TargetServiceName";
+
+ /**
+ * Server Subtransactions inherit this value. if (this.getSources().size() == 1)
+ this.getSources().get(0).getTopic();
+ */
+ String SERVER = "Server";
+
+ /**
+ * Server IP Address Subtransactions inherit this value.
+ */
+ String SERVER_IP_ADDRESS = "ServerIpAddress";
+
+ /**
+ * Server FQDN Subtransactions inherit this value.
+ */
+ String SERVER_FQDN = "ServerFQDN";
+
+ /**
+ * Client IP Address Both transactions and subtransactions will have its own copy.
+ */
+ String CLIENT_IP_ADDRESS = "ClientIPAddress";
+
+ /**
+ * Process Key Both transactions and subtransactions will have its own copy.
+ */
+ String PROCESS_KEY = "ProcessKey";
+
+ /**
+ * Remote Host Both transactions and subtransactions will have its own copy.
+ */
+ String REMOTE_HOST = "RemoteHost";
+
+ /**
+ * Alert Severity Both transactions and subtransactions will have its own copy.
+ */
+ String ALERT_SEVERITY = "AlertSeverity";
+
+ /**
+ * Target Virtual Entity Both transactions and subtransactions will have its own copy.
+ */
+ String TARGET_VIRTUAL_ENTITY = "TargetVirtualEntity";
+
+ /**
+ * Default Service Name
+ */
+ String DEFAULT_SERVICE_NAME = "PDP-D";
+
+ /**
+ * Default Host Name
+ */
+ String DEFAULT_HOSTNAME = NetworkUtil.getHostname();
+
+ /**
+ * Default Host IP
+ */
+ String DEFAULT_HOSTIP = NetworkUtil.getHostIp();
+
+ /**
+ * Status Code Complete
+ */
+ String STATUS_CODE_COMPLETE = "COMPLETE";
+
+ /**
+ * Status Code Error
+ */
+ String STATUS_CODE_FAILURE = "ERROR";
+
+ /**
+ * reset subtransaction data
+ */
+ MDCTransaction resetSubTransaction();
+
+ /**
+ * resets transaction data
+ */
+ MDCTransaction resetTransaction();
+
+ /**
+ * flush to MDC structure
+ */
+ MDCTransaction flush();
+
+ /**
+ * convenience method to log a metric. Alternatively caller
+ * could call flush() and the logging statement directly for
+ * further granularity.
+ */
+ MDCTransaction metric();
+
+ /**
+ * convenience method to log a transaction record. Alternatively caller
+ * could call flush() and the logging statement directly for
+ * further granularity.
+ */
+ MDCTransaction transaction();
+
+ /**
+ * get invocation id
+ */
+ MDCTransaction setInvocationId(String invocationId);
+
+ /**
+ * set start time
+ */
+ MDCTransaction setStartTime(Instant startTime);
+
+ /**
+ * set service name
+ */
+ MDCTransaction setServiceName(String serviceName);
+
+ /**
+ * set status code
+ */
+ MDCTransaction setStatusCode(String statusCode);
+
+ /**
+ * set status code
+ */
+ MDCTransaction setStatusCode(boolean success);
+
+ /**
+ * sets response code
+ */
+ MDCTransaction setResponseCode(String responseCode);
+
+ /**
+ * sets response description
+ */
+ MDCTransaction setResponseDescription(String responseDescription);
+
+ /**
+ * sets instance uuid
+ */
+ MDCTransaction setInstanceUUID(String instanceUUID);
+
+ /**
+ * set severity
+ */
+ MDCTransaction setSeverity(String severity);
+
+ /**
+ * set target entity
+ */
+ MDCTransaction setTargetEntity(String targetEntity);
+
+ /**
+ * set target service name
+ */
+ MDCTransaction setTargetServiceName(String targetServiceName);
+
+ /**
+ * set target virtual entity
+ */
+ MDCTransaction setTargetVirtualEntity(String targetVirtualEntity);
+
+ /**
+ * set request id
+ */
+ MDCTransaction setRequestId(String requestId);
+
+ /**
+ * set partner
+ */
+ MDCTransaction setPartner(String partner);
+
+ /**
+ * set server
+ */
+ MDCTransaction setServer(String server);
+
+ /**
+ * set server ip address
+ */
+ MDCTransaction setServerIpAddress(String serverIpAddress);
+
+ /**
+ * set server fqdn
+ */
+ MDCTransaction setServerFqdn(String serverFqdn);
+
+ /**
+ * set virtual server
+ */
+ MDCTransaction setVirtualServerName(String virtualServerName);
+ /**
+ * sets end time
+ */
+ MDCTransaction setEndTime(Instant endTime);
+
+ /**
+ * sets elapsed time
+ */
+ MDCTransaction setElapsedTime(Long elapsedTime);
+
+ /**
+ * sets service instance id
+ */
+ MDCTransaction setServiceInstanceId(String serviceInstanceId);
+
+ /**
+ * sets process key
+ */
+ MDCTransaction setProcessKey(String processKey);
+
+ /**
+ * sets alert severity
+ */
+ MDCTransaction setAlertSeverity(String alertSeverity);
+
+ /**
+ * sets client ip address
+ */
+ MDCTransaction setClientIpAddress(String clientIpAddress);
+
+ /**
+ * sets remote host
+ */
+ MDCTransaction setRemoteHost(String remoteHost);
+
+ /**
+ * get start time
+ */
+ Instant getStartTime();
+
+ /**
+ * get server
+ */
+ String getServer();
+
+ /**
+ * get end time
+ */
+ Instant getEndTime();
+
+ /**
+ * get elapsed time
+ */
+ Long getElapsedTime();
+
+ /**
+ * get remote host
+ */
+ String getRemoteHost();
+
+ /**
+ * get client ip address
+ */
+ String getClientIpAddress();
+
+ /**
+ * get alert severity
+ */
+ String getAlertSeverity();
+
+ /**
+ * get process key
+ */
+ String getProcessKey();
+
+ /**
+ * get service instance id
+ */
+ String getServiceInstanceId();
+
+ /**
+ * get invocation id
+ */
+ String getInvocationId();
+
+ /**
+ * get service name
+ */
+ String getServiceName();
+
+ /**
+ * get status code
+ */
+ String getStatusCode();
+
+ /**
+ * get response description
+ */
+ String getResponseDescription();
+
+ /**
+ * get instance uuid
+ */
+ String getInstanceUUID();
+
+ /**
+ * get severity
+ */
+ String getSeverity();
+
+ /**
+ * get target entity
+ */
+ String getTargetEntity();
+
+ /**
+ * get service name
+ */
+ String getTargetServiceName();
+
+ /**
+ * get target virtual entity
+ */
+ String getTargetVirtualEntity();
+
+ /**
+ * get response code
+ */
+ String getResponseCode();
+
+ /**
+ * get request id
+ */
+ String getRequestId();
+
+ /**
+ * get partner
+ */
+ String getPartner();
+
+ /**
+ * get server fqdn
+ */
+ String getServerFqdn();
+
+ /**
+ * get virtual server name
+ */
+ String getVirtualServerName();
+
+ /**
+ * get server ip
+ */
+ String getServerIpAddress();
+
+ /**
+ * generate timestamp used for logging
+ */
+ String timestamp(Instant time);
+
+ /**
+ * create new MDC Transaction
+ *
+ * @param requestId transaction Id
+ * @param partner requesting partner
+ *
+ * @return MDC Transaction
+ */
+ static MDCTransaction newTransaction(String requestId, String partner) {
+ return new MDCTransactionImpl(requestId, partner);
+ }
+
+ /**
+ * create new MDC Transaction
+ */
+ static MDCTransaction newTransaction() {
+ return new MDCTransactionImpl();
+ }
+
+ /**
+ * create new subtransaction
+ *
+ * @param invocationId sub-transaction od
+ * @return MDC Transaction
+ */
+ static MDCTransaction newSubTransaction(String invocationId) {
+ return new MDCTransactionImpl(invocationId);
+ }
+
+ /**
+ * create transaction from an existing one
+ *
+ * @param transaction transaction
+ * @return MDC Transaction
+ */
+ static MDCTransaction fromTransaction(MDCTransaction transaction) {
+ return new MDCTransactionImpl(transaction);
+ }
+
+}
+
+class MDCTransactionImpl implements MDCTransaction {
+
+ private final static Logger logger = LoggerFactory.getLogger(MDCTransactionImpl.class.getName());
+
+ /**
+ * Logging Format for Timestamps
+ */
+
+ private static final String DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSS+00:00";
+
+ /* transaction inheritable fields */
+
+ private String requestId;
+ private String partner;
+
+ private String invocationId;
+ private String virtualServerName;
+ private String server;
+ private String serverIpAddress;
+ private String serverFqdn;
+
+ private String serviceName;
+
+ private Instant startTime;
+ private Instant endTime;
+ private Long elapsedTime;
+
+ private String serviceInstanceId;
+ private String instanceUUID;
+ private String processKey;
+
+ private String statusCode;
+ private String responseCode;
+ private String responseDescription;
+ private String severity;
+ private String alertSeverity;
+
+ private String targetEntity;
+ private String targetServiceName;
+ private String targetVirtualEntity;
+ private String clientIpAddress;
+ private String remoteHost;
+
+ /**
+ * Transaction with no information set
+ */
+ public MDCTransactionImpl() {
+ MDC.clear();
+ }
+
+ /**
+ * MDC Transaction
+ *
+ * @param requestId transaction id
+ * @param partner transaction origin
+ */
+ public MDCTransactionImpl(String requestId, String partner) {
+ MDC.clear();
+
+ this.setRequestId(requestId);
+ this.setPartner(partner);
+
+ this.setServiceName(DEFAULT_SERVICE_NAME);
+ this.setServer(DEFAULT_HOSTNAME);
+ this.setServerIpAddress(DEFAULT_HOSTIP);
+ this.setServerFqdn(DEFAULT_HOSTNAME);
+ this.setVirtualServerName(DEFAULT_HOSTNAME);
+
+ this.setStartTime(Instant.now());
+ }
+
+ /**
+ * create subtransaction
+ *
+ * @param invocationId subtransaction id
+ */
+ public MDCTransactionImpl(String invocationId) {
+ this.resetSubTransaction();
+
+ this.setRequestId(MDC.get(REQUEST_ID));
+ this.setPartner(MDC.get(PARTNER_NAME));
+ this.setServiceName(MDC.get(SERVICE_NAME));
+ this.setServer(MDC.get(SERVER));
+ this.setServerIpAddress(MDC.get(SERVER_IP_ADDRESS));
+ this.setServerFqdn(MDC.get(SERVER_FQDN));
+ this.setVirtualServerName(MDC.get(VIRTUAL_SERVER_NAME));
+
+ this.setStartTime(Instant.now());
+ this.setInvocationId(invocationId);
+ }
+
+ /**
+ * copy constructor transaction/subtransaction
+ *
+ * @param transaction
+ */
+ public MDCTransactionImpl(MDCTransaction transaction) {
+ MDC.clear();
+ this.setAlertSeverity(transaction.getAlertSeverity());
+ this.setClientIpAddress(transaction.getClientIpAddress());
+ this.setElapsedTime(transaction.getElapsedTime());
+ this.setEndTime(transaction.getEndTime());
+ this.setInstanceUUID(transaction.getInstanceUUID());
+ this.setInvocationId(transaction.getInvocationId());
+ this.setPartner(transaction.getPartner());
+ this.setProcessKey(transaction.getProcessKey());
+ this.setRemoteHost(transaction.getRemoteHost());
+ this.setRequestId(transaction.getRequestId());
+ this.setResponseCode(transaction.getResponseCode());
+ this.setResponseDescription(transaction.getResponseDescription());
+ this.setServer(transaction.getServer());
+ this.setServerFqdn(transaction.getServerFqdn());
+ this.setServerIpAddress(transaction.getServerIpAddress());
+ this.setServiceInstanceId(transaction.getServiceInstanceId());
+ this.setServiceName(transaction.getServiceName());
+ this.setSeverity(transaction.getSeverity());
+ this.setStartTime(transaction.getStartTime());
+ this.setStatusCode(transaction.getStatusCode());
+ this.setTargetEntity(transaction.getTargetEntity());
+ this.setTargetServiceName(transaction.getTargetServiceName());
+ this.setTargetVirtualEntity(transaction.getTargetVirtualEntity());
+ this.setVirtualServerName(transaction.getVirtualServerName());
+ }
+
+ /**
+ * reset subtransaction portion
+ *
+ * @return MDCTransaction
+ */
+ @Override
+ public MDCTransaction resetSubTransaction() {
+ MDC.remove(INVOCATION_ID);
+ MDC.remove(BEGIN_TIMESTAMP);
+ MDC.remove(END_TIMESTAMP);
+ MDC.remove(ELAPSED_TIME);
+ MDC.remove(SERVICE_INSTANCE_ID);
+ MDC.remove(STATUS_CODE);
+ MDC.remove(RESPONSE_CODE);
+ MDC.remove(RESPONSE_DESCRIPTION);
+ MDC.remove(INSTANCE_UUID);
+ MDC.remove(TARGET_ENTITY);
+ MDC.remove(TARGET_SERVICE_NAME);
+ MDC.remove(PROCESS_KEY);
+ MDC.remove(CLIENT_IP_ADDRESS);
+ MDC.remove(REMOTE_HOST);
+ MDC.remove(ALERT_SEVERITY);
+ MDC.remove(TARGET_VIRTUAL_ENTITY);
+
+ return this;
+ }
+
+ @Override
+ public MDCTransaction resetTransaction() {
+ MDC.clear();
+ return this;
+ }
+
+ /**
+ * flush transaction to MDC
+ */
+ @Override
+ public MDCTransaction flush() {
+ if (this.requestId != null && !this.requestId.isEmpty())
+ MDC.put(REQUEST_ID, this.requestId);
+
+ if (this.invocationId != null && !this.invocationId.isEmpty())
+ MDC.put(INVOCATION_ID, this.invocationId);
+
+ if (this.partner != null)
+ MDC.put(PARTNER_NAME, this.partner);
+
+ if (this.virtualServerName != null)
+ MDC.put(VIRTUAL_SERVER_NAME, this.virtualServerName);
+
+ if (this.server != null)
+ MDC.put(SERVER, this.server);
+
+ if (this.serverIpAddress != null)
+ MDC.put(SERVER_IP_ADDRESS, this.serverIpAddress);
+
+ if (this.serverFqdn != null)
+ MDC.put(SERVER_FQDN, this.serverFqdn);
+
+ if (this.serviceName != null)
+ MDC.put(SERVICE_NAME, this.serviceName);
+
+ if (this.startTime != null)
+ MDC.put(BEGIN_TIMESTAMP, timestamp(this.startTime));
+
+ if (this.endTime != null) {
+ MDC.put(END_TIMESTAMP, timestamp(this.endTime));
+ } else {
+ this.setEndTime(null);
+ MDC.put(END_TIMESTAMP, timestamp(this.endTime));
+ }
+
+ if (this.elapsedTime != null) {
+ MDC.put(ELAPSED_TIME, String.valueOf(this.elapsedTime));
+ } else {
+ if (endTime != null && startTime != null) {
+ this.elapsedTime = Duration.between(startTime, endTime).toMillis();
+ MDC.put(ELAPSED_TIME, String.valueOf(this.elapsedTime));
+ }
+ }
+
+ if (this.serviceInstanceId != null)
+ MDC.put(SERVICE_INSTANCE_ID, this.serviceInstanceId);
+
+ if (this.instanceUUID != null)
+ MDC.put(INSTANCE_UUID, this.instanceUUID);
+
+ if (this.processKey != null)
+ MDC.put(PROCESS_KEY, this.processKey);
+
+ if (this.statusCode != null)
+ MDC.put(STATUS_CODE, this.statusCode);
+
+ if (this.responseCode != null)
+ MDC.put(RESPONSE_CODE, this.responseCode);
+
+ if (this.responseDescription != null)
+ MDC.put(RESPONSE_DESCRIPTION, this.responseDescription);
+
+ if (this.severity != null)
+ MDC.put(SEVERITY, this.severity);
+
+ if (this.alertSeverity != null)
+ MDC.put(ALERT_SEVERITY, this.alertSeverity);
+
+ if (this.targetEntity != null)
+ MDC.put(TARGET_ENTITY, this.targetEntity);
+
+ if (this.targetServiceName != null)
+ MDC.put(TARGET_SERVICE_NAME, this.targetServiceName);
+
+ if (this.targetVirtualEntity != null)
+ MDC.put(TARGET_VIRTUAL_ENTITY, this.targetVirtualEntity);
+
+ if (this.clientIpAddress != null)
+ MDC.put(CLIENT_IP_ADDRESS, this.clientIpAddress);
+
+ if (this.remoteHost != null)
+ MDC.put(REMOTE_HOST, this.remoteHost);
+
+ return this;
+ }
+
+ @Override
+ public MDCTransaction metric() {
+ this.flush();
+ logger.info(LoggerUtil.METRIC_LOG_MARKER, "");
+ return this;
+ }
+
+ @Override
+ public MDCTransaction transaction() {
+ this.flush();
+ logger.info(LoggerUtil.TRANSACTION_LOG_MARKER, "");
+ return this;
+ }
+
+ @Override
+ public MDCTransaction setEndTime(Instant endTime) {
+ if (endTime == null) {
+ this.endTime = Instant.now();
+ } else {
+ this.endTime = endTime;
+ }
+ return this;
+ }
+
+ @Override
+ public MDCTransaction setElapsedTime(Long elapsedTime) {
+ this.elapsedTime = elapsedTime;
+ return this;
+ }
+
+ @Override
+ public MDCTransaction setServiceInstanceId(String serviceInstanceId) {
+ this.serviceInstanceId = serviceInstanceId;
+ return this;
+ }
+
+ @Override
+ public MDCTransaction setProcessKey(String processKey) {
+ this.processKey = processKey;
+ return this;
+ }
+
+ @Override
+ public MDCTransaction setAlertSeverity(String alertSeverity) {
+ this.alertSeverity = alertSeverity;
+ return this;
+ }
+
+ @Override
+ public MDCTransaction setClientIpAddress(String clientIpAddress) {
+ this.clientIpAddress = clientIpAddress;
+ return this;
+ }
+
+ @Override
+ public MDCTransaction setRemoteHost(String remoteHost) {
+ this.remoteHost = remoteHost;
+ return this;
+ }
+
+ @Override
+ public Instant getStartTime() {
+ return this.startTime;
+ }
+
+ @Override
+ public String getServer() {
+ return this.server;
+ }
+
+ @Override
+ public Instant getEndTime() {
+ return this.endTime;
+ }
+
+ @Override
+ public Long getElapsedTime() {
+ return this.elapsedTime;
+ }
+
+ @Override
+ public String getRemoteHost() {
+ return this.remoteHost;
+ }
+
+ @Override
+ public String getClientIpAddress() {
+ return this.clientIpAddress;
+ }
+
+ @Override
+ public String getAlertSeverity() {
+ return this.alertSeverity;
+ }
+
+ @Override
+ public String getProcessKey() {
+ return this.processKey;
+ }
+
+ @Override
+ public String getServiceInstanceId() {
+ return this.serviceInstanceId;
+ }
+
+ /* transaction and subtransaction fields */
+
+ @Override
+ public MDCTransaction setInvocationId(String invocationId) {
+ if (invocationId == null) {
+ this.invocationId = UUID.randomUUID().toString();
+ } else {
+ this.invocationId = invocationId;
+ }
+
+ MDC.put(INVOCATION_ID, this.invocationId);
+
+ return this;
+ }
+
+ @Override
+ public MDCTransaction setStartTime(Instant startTime) {
+ if (startTime == null) {
+ this.startTime = Instant.now();
+ } else {
+ this.startTime = startTime;
+ }
+
+ MDC.put(BEGIN_TIMESTAMP, this.timestamp(this.startTime));
+
+ return this;
+ }
+
+ @Override
+ public MDCTransaction setServiceName(String serviceName) {
+ if (serviceName == null || serviceName.isEmpty()) {
+ this.serviceName = DEFAULT_SERVICE_NAME;
+ } else {
+ this.serviceName = serviceName;
+ }
+
+ MDC.put(SERVICE_NAME, this.serviceName);
+
+ return this;
+ }
+
+ @Override
+ public MDCTransaction setStatusCode(String statusCode) {
+ this.statusCode = statusCode;
+ return this;
+ }
+
+ @Override
+ public MDCTransaction setStatusCode(boolean success) {
+ if (success) {
+ this.statusCode = STATUS_CODE_COMPLETE;
+ } else {
+ this.statusCode = STATUS_CODE_FAILURE;
+ }
+ return this;
+ }
+
+ @Override
+ public MDCTransaction setResponseCode(String responseCode) {
+ this.responseCode = responseCode;
+ return this;
+ }
+
+ @Override
+ public MDCTransaction setResponseDescription(String responseDescription) {
+ this.responseDescription = responseDescription;
+ return this;
+ }
+
+ @Override
+ public MDCTransaction setInstanceUUID(String instanceUUID) {
+ if (instanceUUID == null) {
+ this.instanceUUID = UUID.randomUUID().toString();
+ } else {
+ this.instanceUUID = instanceUUID;
+ }
+
+ MDC.put(INSTANCE_UUID, this.instanceUUID);
+ return this;
+ }
+
+ @Override
+ public MDCTransaction setSeverity(String severity) {
+ this.severity = severity;
+ return this;
+ }
+
+ @Override
+ public MDCTransaction setTargetEntity(String targetEntity) {
+ this.targetEntity = targetEntity;
+ return this;
+ }
+
+ @Override
+ public MDCTransaction setTargetServiceName(String targetServiceName) {
+ this.targetServiceName = targetServiceName;
+ return this;
+ }
+
+ @Override
+ public MDCTransaction setTargetVirtualEntity(String targetVirtualEntity) {
+ this.targetVirtualEntity = targetVirtualEntity;
+ return this;
+ }
+
+ @Override
+ public String getInvocationId() {
+ return invocationId;
+ }
+
+ @Override
+ public String getServiceName() {
+ return serviceName;
+ }
+
+ @Override
+ public String getStatusCode() {
+ return statusCode;
+ }
+
+ @Override
+ public String getResponseDescription() {
+ return responseDescription;
+ }
+
+ @Override
+ public String getInstanceUUID() {
+ return instanceUUID;
+ }
+
+ @Override
+ public String getSeverity() {
+ return severity;
+ }
+
+ @Override
+ public String getTargetEntity() {
+ return targetEntity;
+ }
+
+ @Override
+ public String getTargetServiceName() {
+ return targetServiceName;
+ }
+
+ @Override
+ public String getTargetVirtualEntity() {
+ return targetVirtualEntity;
+ }
+
+ @Override
+ public String getResponseCode() {
+ return responseCode;
+ }
+
+ /* inheritable fields by subtransactions via MDC */
+
+ @Override
+ public MDCTransaction setRequestId(String requestId) {
+ if (requestId == null || requestId.isEmpty()) {
+ this.requestId = UUID.randomUUID().toString();
+ } else {
+ this.requestId = requestId;
+ }
+
+ MDC.put(REQUEST_ID, this.requestId);
+ return this;
+ }
+
+ @Override
+ public MDCTransaction setPartner(String partner) {
+ if (partner == null || partner.isEmpty()) {
+ this.partner = DEFAULT_SERVICE_NAME;
+ } else {
+ this.partner = partner;
+ }
+
+ MDC.put(PARTNER_NAME, this.partner);
+ return this;
+ }
+
+ @Override
+ public MDCTransaction setServer(String server) {
+ if (server == null || server.isEmpty()) {
+ this.server = DEFAULT_HOSTNAME;
+ } else {
+ this.server = server;
+ }
+
+ MDC.put(SERVER, this.server);
+ return this;
+ }
+
+ @Override
+ public MDCTransaction setServerIpAddress(String serverIpAddress) {
+ if (serverIpAddress == null || serverIpAddress.isEmpty()) {
+ this.serverIpAddress = DEFAULT_HOSTIP;
+ } else {
+ this.serverIpAddress = serverIpAddress;
+ }
+
+ MDC.put(SERVER_IP_ADDRESS, this.serverIpAddress);
+ return this;
+ }
+
+ @Override
+ public MDCTransaction setServerFqdn(String serverFqdn) {
+ if (serverFqdn == null || serverFqdn.isEmpty()) {
+ this.serverFqdn = DEFAULT_HOSTNAME;
+ } else {
+ this.serverFqdn = serverFqdn;
+ }
+
+ MDC.put(SERVER_FQDN, this.serverFqdn);
+ return this;
+ }
+
+ @Override
+ public MDCTransaction setVirtualServerName(String virtualServerName) {
+ if (virtualServerName == null || virtualServerName.isEmpty()) {
+ this.virtualServerName = DEFAULT_HOSTNAME;
+ } else {
+ this.virtualServerName = virtualServerName;
+ }
+
+ MDC.put(VIRTUAL_SERVER_NAME, this.virtualServerName);
+ return this;
+ }
+
+ @Override
+ public String getRequestId() {
+ return requestId;
+ }
+
+ @Override
+ public String getPartner() {
+ return partner;
+ }
+
+ @Override
+ public String getServerFqdn() {
+ return serverFqdn;
+ }
+
+ @Override
+ public String getVirtualServerName() {
+ return virtualServerName;
+ }
+
+ @Override
+ public String getServerIpAddress() {
+ return serverIpAddress;
+ }
+
+ @Override
+ public String timestamp(Instant time) {
+ return new SimpleDateFormat(DATE_FORMAT).format(Date.from(time));
+ }
+
+ @Override
+ public String toString() {
+ final StringBuilder sb = new StringBuilder("MDCTransaction{");
+ sb.append("requestId='").append(requestId).append('\'');
+ sb.append(", partner='").append(partner).append('\'');
+ sb.append(", invocationId='").append(invocationId).append('\'');
+ sb.append(", virtualServerName='").append(virtualServerName).append('\'');
+ sb.append(", server='").append(server).append('\'');
+ sb.append(", serverIpAddress='").append(serverIpAddress).append('\'');
+ sb.append(", serverFqdn='").append(serverFqdn).append('\'');
+ sb.append(", serviceName='").append(serviceName).append('\'');
+ sb.append(", startTime=").append(startTime);
+ sb.append(", endTime=").append(endTime);
+ sb.append(", elapsedTime=").append(elapsedTime);
+ sb.append(", serviceInstanceId='").append(serviceInstanceId).append('\'');
+ sb.append(", instanceUUID='").append(instanceUUID).append('\'');
+ sb.append(", processKey='").append(processKey).append('\'');
+ sb.append(", statusCode='").append(statusCode).append('\'');
+ sb.append(", responseCode='").append(responseCode).append('\'');
+ sb.append(", responseDescription='").append(responseDescription).append('\'');
+ sb.append(", severity='").append(severity).append('\'');
+ sb.append(", alertSeverity='").append(alertSeverity).append('\'');
+ sb.append(", targetEntity='").append(targetEntity).append('\'');
+ sb.append(", targetServiceName='").append(targetServiceName).append('\'');
+ sb.append(", targetVirtualEntity='").append(targetVirtualEntity).append('\'');
+ sb.append(", clientIpAddress='").append(clientIpAddress).append('\'');
+ sb.append(", remoteHost='").append(remoteHost).append('\'');
+ sb.append('}');
+ return sb.toString();
+ }
+
+}
diff --git a/policy-utils/src/test/java/org/onap/policy/drools/utils/NetworkUtilTest.java b/policy-utils/src/test/java/org/onap/policy/drools/utils/NetworkUtilTest.java
index c8b7735b..406cdae9 100644
--- a/policy-utils/src/test/java/org/onap/policy/drools/utils/NetworkUtilTest.java
+++ b/policy-utils/src/test/java/org/onap/policy/drools/utils/NetworkUtilTest.java
@@ -32,6 +32,8 @@ public class NetworkUtilTest {
public void test() throws InterruptedException, IOException {
assertNotNull(NetworkUtil.IPv4_WILDCARD_ADDRESS);
assertFalse(NetworkUtil.isTcpPortOpen("localhost", 8080, 1, 5));
+ assertNotNull(NetworkUtil.getHostname());
+ assertNotNull(NetworkUtil.getHostIp());
}
}
diff --git a/policy-utils/src/test/java/org/onap/policy/drools/utils/logging/LoggerUtilTest.java b/policy-utils/src/test/java/org/onap/policy/drools/utils/logging/LoggerUtilTest.java
new file mode 100644
index 00000000..d773b265
--- /dev/null
+++ b/policy-utils/src/test/java/org/onap/policy/drools/utils/logging/LoggerUtilTest.java
@@ -0,0 +1,56 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * policy-utils
+ * ================================================================================
+ * Copyright (C) 2018 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.onap.policy.drools.utils.logging;
+
+import static org.junit.Assert.*;
+
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class LoggerUtilTest {
+
+ @Test
+ public void test() {
+
+ Logger logger = LoggerFactory.getLogger(LoggerUtilTest.class);
+
+ assertTrue(logger.isInfoEnabled());
+
+ logger.info("line 1");
+ logger.info(LoggerUtil.METRIC_LOG_MARKER, "line 1 Metric");
+ logger.info(LoggerUtil.TRANSACTION_LOG_MARKER, "line 1 Transaction");
+
+ LoggerUtil.setLevel(LoggerUtil.ROOT_LOGGER, "warn");
+ logger.info("line 2");
+ logger.info(LoggerUtil.METRIC_LOG_MARKER, "line 2 Metric");
+ logger.info(LoggerUtil.TRANSACTION_LOG_MARKER, "line 2 Transaction");
+
+ assertFalse(logger.isInfoEnabled());
+
+ LoggerUtil.setLevel(LoggerUtil.ROOT_LOGGER, "debug");
+ logger.debug("line 3");
+ logger.debug(LoggerUtil.METRIC_LOG_MARKER, "line 3 Metric");
+ logger.debug(LoggerUtil.TRANSACTION_LOG_MARKER, "line 3 Transaction");
+
+ assertTrue(logger.isDebugEnabled());
+ }
+
+}
diff --git a/policy-utils/src/test/java/org/onap/policy/drools/utils/logging/MDCTransactionTest.java b/policy-utils/src/test/java/org/onap/policy/drools/utils/logging/MDCTransactionTest.java
new file mode 100644
index 00000000..f6c48daf
--- /dev/null
+++ b/policy-utils/src/test/java/org/onap/policy/drools/utils/logging/MDCTransactionTest.java
@@ -0,0 +1,265 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * policy-utils
+ * ================================================================================
+ * Copyright (C) 2018 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.
+ */
+package org.onap.policy.drools.utils.logging;
+
+import static org.junit.Assert.*;
+
+import java.time.Duration;
+import java.time.Instant;
+import org.junit.Test;
+import org.slf4j.MDC;
+
+public class MDCTransactionTest {
+
+ @Test
+ public void resetSubTransaction() {
+ MDCTransaction trans =
+ MDCTransaction.newTransaction(null, null).resetSubTransaction();
+
+ assertNotNull(trans.getRequestId());
+ assertNotNull(trans.getPartner());
+ assertNotNull(trans.getServiceName());
+ assertNotNull(trans.getServer());
+ assertNotNull(trans.getServerIpAddress());
+ assertNotNull(trans.getServerFqdn());
+ assertNotNull(trans.getVirtualServerName());
+ assertNotNull(trans.getStartTime());
+
+ assertNullSubTransactionFields(trans);
+
+ assertNotNull(MDC.get(MDCTransaction.REQUEST_ID));
+ assertNotNull(MDC.get(MDCTransaction.PARTNER_NAME));
+ assertNotNull(MDC.get(MDCTransaction.VIRTUAL_SERVER_NAME));
+ assertNotNull(MDC.get(MDCTransaction.SERVER));
+ assertNotNull(MDC.get(MDCTransaction.SERVER_IP_ADDRESS));
+ assertNotNull(MDC.get(MDCTransaction.SERVER_FQDN));
+ assertNotNull(MDC.get(MDCTransaction.SERVICE_NAME));
+
+ assertNull(MDC.get(MDCTransaction.INVOCATION_ID));
+ assertNull(MDC.get(MDCTransaction.BEGIN_TIMESTAMP));
+ assertNull(MDC.get(MDCTransaction.END_TIMESTAMP));
+ assertNull(MDC.get(MDCTransaction.ELAPSED_TIME));
+ assertNull(MDC.get(MDCTransaction.SERVICE_INSTANCE_ID));
+ assertNull(MDC.get(MDCTransaction.INSTANCE_UUID));
+ assertNull(MDC.get(MDCTransaction.PROCESS_KEY));
+ assertNull(MDC.get(MDCTransaction.STATUS_CODE));
+ assertNull(MDC.get(MDCTransaction.RESPONSE_CODE));
+ assertNull(MDC.get(MDCTransaction.RESPONSE_DESCRIPTION));
+ assertNull(MDC.get(MDCTransaction.SEVERITY));
+ assertNull(MDC.get(MDCTransaction.ALERT_SEVERITY));
+ assertNull(MDC.get(MDCTransaction.TARGET_ENTITY));
+ assertNull(MDC.get(MDCTransaction.TARGET_SERVICE_NAME));
+ assertNull(MDC.get(MDCTransaction.TARGET_VIRTUAL_ENTITY));
+ assertNull(MDC.get(MDCTransaction.CLIENT_IP_ADDRESS));
+ assertNull(MDC.get(MDCTransaction.REMOTE_HOST));
+
+ assertEquals(trans.getRequestId(), MDC.get(MDCTransaction.REQUEST_ID));
+ assertEquals(trans.getPartner(), MDC.get(MDCTransaction.PARTNER_NAME));
+ assertEquals(trans.getVirtualServerName(), MDC.get(MDCTransaction.VIRTUAL_SERVER_NAME));
+ assertEquals(trans.getServer(), MDC.get(MDCTransaction.SERVER));
+ assertEquals(trans.getServerIpAddress(), MDC.get(MDCTransaction.SERVER_IP_ADDRESS));
+ assertEquals(trans.getServerFqdn(), MDC.get(MDCTransaction.SERVER_FQDN));
+ assertEquals(trans.getServiceName(), MDC.get(MDCTransaction.SERVICE_NAME));
+ }
+
+ private void assertNullSubTransactionFields(MDCTransaction trans) {
+ assertNull(trans.getInvocationId());
+ assertNullSubTransactionFieldsButInvocationId(trans);
+ }
+
+ private void assertNullSubTransactionFieldsButInvocationId(MDCTransaction trans) {
+ assertNull(trans.getEndTime());
+ assertNull(trans.getElapsedTime());
+ assertNull(trans.getServiceInstanceId());
+ assertNull(trans.getStatusCode());
+ assertNull(trans.getResponseCode());
+ assertNull(trans.getResponseDescription());
+ assertNull(trans.getInstanceUUID());
+ assertNull(trans.getTargetEntity());
+ assertNull(trans.getTargetServiceName());
+ assertNull(trans.getProcessKey());
+ assertNull(trans.getClientIpAddress());
+ assertNull(trans.getRemoteHost());
+ assertNull(trans.getAlertSeverity());
+ assertNull(trans.getTargetVirtualEntity());
+ }
+
+ protected void assertTransactionFields(MDCTransaction trans) {
+ assertEquals(trans.getRequestId(), MDC.get(MDCTransaction.REQUEST_ID));
+ assertEquals(trans.getPartner(), MDC.get(MDCTransaction.PARTNER_NAME));
+ assertEquals(trans.getVirtualServerName(), MDC.get(MDCTransaction.VIRTUAL_SERVER_NAME));
+ assertEquals(trans.getServer(), MDC.get(MDCTransaction.SERVER));
+ assertEquals(trans.getServerIpAddress(), MDC.get(MDCTransaction.SERVER_IP_ADDRESS));
+ assertEquals(trans.getServerFqdn(), MDC.get(MDCTransaction.SERVER_FQDN));
+ assertEquals(trans.getServiceName(), MDC.get(MDCTransaction.SERVICE_NAME));
+
+ }
+
+ @Test
+ public void flush() {
+ MDCTransaction trans =
+ MDCTransaction.newTransaction().
+ setRequestId(null).
+ setInvocationId(null).
+ setPartner(null).
+ setVirtualServerName(null).
+ setServer(null).
+ setServerIpAddress(null).
+ setServerFqdn(null).
+ setServiceName(null).
+ setStartTime(null).
+ setEndTime(null).
+ setServiceInstanceId("service-instance-id").
+ setInstanceUUID(null).
+ setProcessKey("process-key").
+ setStatusCode("status-code").
+ setResponseCode("response-code").
+ setResponseDescription("response-description").
+ setSeverity("severity").
+ setAlertSeverity("alert-severity").
+ setTargetEntity("target-entity").
+ setTargetServiceName("target-service-name").
+ setTargetVirtualEntity("target-virtual-entity").
+ setClientIpAddress("client-ip-address").
+ setRemoteHost("remote-host").
+ flush();
+
+ assertTransactionFields(trans);
+
+ assertNotNull(MDC.get(MDCTransaction.INVOCATION_ID));
+ assertNotNull(MDC.get(MDCTransaction.BEGIN_TIMESTAMP));
+ assertNotNull(MDC.get(MDCTransaction.END_TIMESTAMP));
+ assertNotNull(MDC.get(MDCTransaction.ELAPSED_TIME));
+ assertNotNull(MDC.get(MDCTransaction.SERVICE_INSTANCE_ID));
+ assertNotNull(MDC.get(MDCTransaction.INSTANCE_UUID));
+ assertNotNull(MDC.get(MDCTransaction.PROCESS_KEY));
+ assertNotNull(MDC.get(MDCTransaction.STATUS_CODE));
+ assertNotNull(MDC.get(MDCTransaction.RESPONSE_CODE));
+ assertNotNull(MDC.get(MDCTransaction.RESPONSE_DESCRIPTION));
+ assertNotNull(MDC.get(MDCTransaction.SEVERITY));
+ assertNotNull(MDC.get(MDCTransaction.ALERT_SEVERITY));
+ assertNotNull(MDC.get(MDCTransaction.TARGET_ENTITY));
+ assertNotNull(MDC.get(MDCTransaction.TARGET_SERVICE_NAME));
+ assertNotNull(MDC.get(MDCTransaction.TARGET_VIRTUAL_ENTITY));
+ assertNotNull(MDC.get(MDCTransaction.CLIENT_IP_ADDRESS));
+ assertNotNull(MDC.get(MDCTransaction.REMOTE_HOST));
+
+ assertEquals(trans.getInvocationId(), MDC.get(MDCTransaction.INVOCATION_ID));
+ assertEquals(trans.timestamp(trans.getStartTime()), MDC.get(MDCTransaction.BEGIN_TIMESTAMP));
+ assertEquals(trans.timestamp(trans.getEndTime()), MDC.get(MDCTransaction.END_TIMESTAMP));
+ assertNotEquals(trans.getElapsedTime(), MDC.get(MDCTransaction.ELAPSED_TIME));
+ assertEquals(String.valueOf(Duration.between(trans.getStartTime(), trans.getEndTime()).toMillis()),
+ MDC.get(MDCTransaction.ELAPSED_TIME));
+ assertEquals(trans.getServiceInstanceId(), MDC.get(MDCTransaction.SERVICE_INSTANCE_ID));
+ assertEquals(trans.getInstanceUUID(), MDC.get(MDCTransaction.INSTANCE_UUID));
+ assertEquals(trans.getProcessKey(),MDC.get(MDCTransaction.PROCESS_KEY));
+ assertEquals(trans.getStatusCode(), MDC.get(MDCTransaction.STATUS_CODE));
+ assertEquals(trans.getResponseCode(), MDC.get(MDCTransaction.RESPONSE_CODE));
+ assertEquals(trans.getResponseDescription(), MDC.get(MDCTransaction.RESPONSE_DESCRIPTION));
+ assertEquals(trans.getSeverity(), MDC.get(MDCTransaction.SEVERITY));
+ assertEquals(trans.getAlertSeverity(), MDC.get(MDCTransaction.ALERT_SEVERITY));
+ assertEquals(trans.getTargetEntity(), MDC.get(MDCTransaction.TARGET_ENTITY));
+ assertEquals(trans.getTargetServiceName(), MDC.get(MDCTransaction.TARGET_SERVICE_NAME));
+ assertEquals(trans.getTargetVirtualEntity(), MDC.get(MDCTransaction.TARGET_VIRTUAL_ENTITY));
+ assertEquals(trans.getClientIpAddress(), MDC.get(MDCTransaction.CLIENT_IP_ADDRESS));
+ assertEquals(trans.getRemoteHost(), MDC.get(MDCTransaction.REMOTE_HOST));
+
+ assertEquals(trans.getServiceInstanceId(),"service-instance-id");
+ assertEquals(trans.getProcessKey(),"process-key");
+ assertEquals(trans.getStatusCode(),"status-code");
+ assertEquals(trans.getResponseCode(),"response-code");
+ assertEquals(trans.getResponseDescription(),"response-description");
+ assertEquals(trans.getSeverity(),"severity");
+ assertEquals(trans.getAlertSeverity(),"alert-severity");
+ assertEquals(trans.getTargetEntity(),"target-entity");
+ assertEquals(trans.getTargetServiceName(),"target-service-name");
+ assertEquals(trans.getTargetVirtualEntity(),"target-virtual-entity");
+ assertEquals(trans.getClientIpAddress(),"client-ip-address");
+ assertEquals(trans.getRemoteHost(),"remote-host");
+ }
+
+ @Test
+ public void metric() {
+ MDCTransaction trans =
+ MDCTransaction.newTransaction(null, null).metric();
+
+ assertTransactionFields(trans);
+ }
+
+ @Test
+ public void transaction() {
+ MDCTransaction trans =
+ MDCTransaction.newTransaction(null, null).transaction();
+
+ assertTransactionFields(trans);
+ }
+
+ @Test
+ public void subTransaction() {
+ MDCTransaction trans =
+ MDCTransaction.newTransaction(null, "partner");
+
+ MDCTransaction subTrans = MDCTransaction.newSubTransaction(null);
+
+ assertTransactionFields(trans);
+ assertTransactionFields(subTrans);
+
+ assertEquals(trans.getRequestId(), trans.getRequestId());
+ assertEquals(trans.getPartner(), trans.getPartner());
+ assertEquals(trans.getVirtualServerName(), trans.getVirtualServerName());
+ assertEquals(trans.getServer(), trans.getServer());
+ assertEquals(trans.getServerIpAddress(), trans.getServerIpAddress());
+ assertEquals(trans.getServerFqdn(), trans.getServerFqdn());
+ assertEquals(trans.getServiceName(), trans.getServiceName());
+
+ assertNotEquals(trans.getInvocationId(), subTrans.getInvocationId());
+ assertNull(trans.getInvocationId());
+ assertNotNull(subTrans.getInvocationId());
+
+ assertNotNull(subTrans.getStartTime());
+ assertNullSubTransactionFieldsButInvocationId(trans);
+
+ subTrans.setServiceInstanceId("service-instance-id").
+ setInstanceUUID(null).
+ setProcessKey("process-key").
+ setStatusCode("status-code").
+ setResponseCode("response-code").
+ setResponseDescription("response-description").
+ setSeverity("severity").
+ setAlertSeverity("alert-severity").
+ setTargetEntity("target-entity").
+ setTargetServiceName("target-service-name").
+ setTargetVirtualEntity("target-virtual-entity").
+ setClientIpAddress("client-ip-address").
+ setRemoteHost("remote-host").
+ setEndTime(Instant.now());
+
+ subTrans.setStatusCode(false).setResponseCode("400");
+
+ MDCTransaction subTrans2 = MDCTransaction.fromTransaction(subTrans);
+
+ assertEquals(subTrans.toString(), subTrans2.toString());
+
+ subTrans.metric();
+ subTrans2.setStatusCode("202").setProcessKey("junit").metric();
+
+ trans.resetSubTransaction().setStatusCode(true).setResponseCode("200").metric();
+ }
+
+} \ No newline at end of file
diff --git a/policy-utils/src/test/resources/logback-test.xml b/policy-utils/src/test/resources/logback-test.xml
new file mode 100644
index 00000000..366a5f67
--- /dev/null
+++ b/policy-utils/src/test/resources/logback-test.xml
@@ -0,0 +1,36 @@
+<!--
+ ============LICENSE_START=======================================================
+ ONAP
+ ================================================================================
+ Copyright (C) 2018 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>
+
+ <property name="pattern" value="%X{RequestID}|%X{InvocationID}|%X{ServiceName}|%X{PartnerName}|%X{BeginTimestamp}|%X{EndTimestamp}|%X{ElapsedTime}|%X{ServiceInstanceID}|%X{VirtualServerName}|%X{StatusCode}|%X{ResponseCode}|%X{ResponseDescription}|%X{InstanceUUID}|%X{Severity}|%X{TargetEntity}|%X{TargetServiceName}|%X{Server}|%X{ServerIPAddress}|%X{ServerFQDN}|%X{ClientIPAddress}|%X{ProcessKey}|%X{RemoteHost}|%X{AlertSeverity}|%X{TargetVirtualEntity}|%level|%logger{0}|%thread| %msg%n"/>
+
+ <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+ <filter class="org.onap.policy.drools.utils.logging.LoggerMarkerFilter$MetricLoggerMarkerFilter" />
+ <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
+ <Pattern>${pattern}</Pattern>
+ </encoder>
+ </appender>
+
+ <root level="INFO">
+ <appender-ref ref="STDOUT"/>
+ </root>
+
+</configuration>
diff --git a/pom.xml b/pom.xml
index 78a87108..a8d8fab8 100644
--- a/pom.xml
+++ b/pom.xml
@@ -61,7 +61,7 @@
<cambria.version>0.0.1</cambria.version>
<jersey.version>2.25.1</jersey.version>
<jersey.swagger.version>1.5.18</jersey.swagger.version>
- <jackson.version>2.9.4</jackson.version>
+ <jackson.version>2.9.5</jackson.version>
<http.client.version>4.5.5</http.client.version>
<http.core.version>4.4.4</http.core.version>
<logback.version>1.2.3</logback.version>
@@ -90,6 +90,7 @@
<module>api-active-standby-management</module>
<module>feature-active-standby-management</module>
<module>feature-simulators</module>
+ <module>feature-distributed-locking</module>
<module>packages</module>
</modules>