summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/api/AuditData.java190
-rw-r--r--openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/api/StatusCode.java27
-rw-r--r--openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/test/java/org/openecomp/sdc/logging/api/AuditDataTest.java59
-rw-r--r--openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/test/java/org/openecomp/sdc/logging/api/LoggerFactoryTest.java2
-rw-r--r--openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/test/java/org/openecomp/sdc/logging/api/SpyAuditData.java63
-rw-r--r--openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-core/pom.xml3
-rw-r--r--openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-core/src/main/java/org/openecomp/sdc/logging/slf4j/SLF4JLoggerWrapper.java89
-rw-r--r--openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-core/src/main/java/org/openecomp/sdc/logging/slf4j/SLF4JLoggingServiceProvider.java8
-rw-r--r--openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-core/src/test/java/org/openecomp/sdc/logging/LogFileCreationTest.java55
-rw-r--r--openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-core/src/test/java/org/openecomp/sdc/logging/slf4j/SLF4JLoggerWrapperTest.java190
10 files changed, 510 insertions, 176 deletions
diff --git a/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/api/AuditData.java b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/api/AuditData.java
index 7292762474..fdef45a57f 100644
--- a/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/api/AuditData.java
+++ b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/api/AuditData.java
@@ -17,34 +17,186 @@
package org.openecomp.sdc.logging.api;
/**
- * @author KATYR
+ * Builder to populate audit data for logging according to
+ * <a href="https://wiki.onap.org/download/attachments/1015849/ONAP%20application%20logging%20guidelines.pdf?api=v2>
+ * ONAP application logging guidelines</a>. This includes only data known to an application, and not otherwise available
+ * to the logging framework.
+ *
+ * @author KATYR, evitaliy
* @since February 15, 2018
- * This interface defines part of the Audit log application is responsible to provide.
- * Fields list is according to ONAP application logging guidelines
- * (https://wiki.onap.org/download/attachments/1015849/ONAP%20application%20logging%20guidelines.pdf?api=v2)
- * StartTime -> BeginTimestamp (Date-time that processing for the activities begins)
- * EndTime-> EndTimestamp (Date-time that processing for the activities being logged ends)
- * StatusCode -> StatusCode (indicate high level success or failure of the operation activities that is invoked)
- * ResponseCode -> ResponseCode(application-specific response code returned by the operation activities)
- * ResponseDescription - > ResponseDescription (human readable description of the response code)
- * ClientIpAddress -> ClientIpAddress (Requesting remote client application’s IP address)
*/
+public class AuditData {
+
+ // A concrete implementation interface was chosen over an interface to enable to gracefully
+ // add new fields without affecting client code
+
+ private final long startTime;
+ private final long endTime;
+ private final StatusCode statusCode;
+ private final String responseCode;
+ private final String responseDescription;
+ private final String clientIpAddress;
-public interface AuditData {
+ AuditData(final AuditDataBuilder builder) {
+ this.startTime = builder.startTime;
+ this.endTime = builder.endTime;
+ this.statusCode = builder.statusCode;
+ this.responseCode = builder.responseCode;
+ this.responseDescription = builder.responseDescription;
+ this.clientIpAddress = builder.clientIpAddress;
+ }
+
+ /**
+ * Begin timestamp of an API invocation
+ *
+ * @return timestamp
+ */
+ public long getStartTime() {
+ return startTime;
+ }
- enum StatusCode {
- COMPLETE, ERROR
+ /**
+ * End timestamp of an API invocation
+ *
+ * @return timestamp
+ */
+ public long getEndTime() {
+ return endTime;
}
- long getStartTime();
+ /**
+ * Result status of an API invocation
+ *
+ * @return protocol and application agnostic status code
+ */
+ public StatusCode getStatusCode() {
+ return statusCode;
+ }
- long getEndTime();
+ /**
+ * Application/protocol specific response status of an API invocation
+ *
+ * @return response code
+ */
+ public String getResponseCode() {
+ return responseCode;
+ }
- StatusCode getStatusCode();
+ /**
+ * Application/protocol specific response in a human-friendly way
+ *
+ * @return human-friendly response description
+ */
+ public String getResponseDescription() {
+ return responseDescription;
+ }
- String getResponseCode();
+ /**
+ * IP address of the invoking client when available
+ *
+ * @return IP address
+ */
+ public String getClientIpAddress() {
+ return clientIpAddress;
+ }
- String getResponseDescription();
+ @Override
+ public String toString() {
+ return "AuditData{startTime=" + startTime + ", endTime=" + endTime + ", statusCode=" + statusCode +
+ ", responseCode='" + responseCode + ", responseDescription=" + responseDescription + ", clientIpAddress="
+ + clientIpAddress + '}';
+ }
- String getClientIpAddress();
+ public static AuditDataBuilder builder() {
+ return new AuditDataBuilder();
+ }
+
+ public static class AuditDataBuilder {
+
+ private long startTime;
+ private long endTime;
+ private StatusCode statusCode;
+ private String responseCode;
+ private String responseDescription;
+ private String clientIpAddress;
+
+ AuditDataBuilder() { /* package-private default constructor to hide the public one */ }
+
+ /**
+ * Begin timestamp of an activity being audited
+ *
+ * @param startTime local timestamp, usually received from {@link System#currentTimeMillis()}
+ * @return this builder for fluent API
+ */
+ public AuditDataBuilder startTime(final long startTime) {
+ this.startTime = startTime;
+ return this;
+ }
+
+ /**
+ * End timestamp of an activity being audited
+ *
+ * @param endTime local timestamp, usually received from {@link System#currentTimeMillis()}
+ * @return this builder for fluent API
+ */
+ public AuditDataBuilder endTime(final long endTime) {
+ this.endTime = endTime;
+ return this;
+ }
+
+ /**
+ * Indicate whether an invocation was successful. It is up the the application to decide if a particular result
+ * must be treated as a success or a failure.
+ *
+ * @param statusCode invocation status success/failure
+ * @return this builder for fluent API
+ */
+ public AuditDataBuilder statusCode(final StatusCode statusCode) {
+ this.statusCode = statusCode;
+ return this;
+ }
+
+ /**
+ * Application/protocol specific response code. For a Web API, it is likely a standard HTTP response code.
+ *
+ * @param responseCode response code that depends on application and invocation protocol
+ * @return this builder for fluent API
+ */
+ public AuditDataBuilder responseCode(final String responseCode) {
+ this.responseCode = responseCode;
+ return this;
+ }
+
+ /**
+ * Response description that explains {@link #responseCode(String)} in a human-friendly way. For a Web API, it
+ * is likely to be a standard HTTP response phrase.
+ *
+ * @param responseDescription human-friendly response description
+ * @return this builder for fluent API
+ */
+ public AuditDataBuilder responseDescription(final String responseDescription) {
+ this.responseDescription = responseDescription;
+ return this;
+ }
+
+ /**
+ * IP address of an invoking client.
+ *
+ * @param clientIpAddress IP address
+ * @return this builder for fluent API
+ */
+ public AuditDataBuilder clientIpAddress(final String clientIpAddress) {
+ this.clientIpAddress = clientIpAddress;
+ return this;
+ }
+
+ /**
+ * Create an instance of {@link AuditData}
+ *
+ * @return a populated instance of audit data
+ */
+ public AuditData build() {
+ return new AuditData(this);
+ }
+ }
}
diff --git a/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/api/StatusCode.java b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/api/StatusCode.java
new file mode 100644
index 0000000000..dd8bd57dcc
--- /dev/null
+++ b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/api/StatusCode.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright © 2016-2018 European Support Limited
+ *
+ * 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.openecomp.sdc.logging.api;
+
+/**
+ * Protocol-agnostic status codes to indicate the result status (success, failure) of an API invocation.
+ *
+ * @author EVITALIY
+ * @since 04 Mar 18
+ */
+public enum StatusCode {
+ COMPLETE, ERROR
+}
diff --git a/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/test/java/org/openecomp/sdc/logging/api/AuditDataTest.java b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/test/java/org/openecomp/sdc/logging/api/AuditDataTest.java
new file mode 100644
index 0000000000..08ce5089b7
--- /dev/null
+++ b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/test/java/org/openecomp/sdc/logging/api/AuditDataTest.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright © 2016-2018 European Support Limited
+ *
+ * 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.openecomp.sdc.logging.api;
+
+import static org.testng.Assert.*;
+
+import org.testng.annotations.Test;
+
+/**
+ * @author EVITALIY
+ * @since 04 Mar 18
+ */
+public class AuditDataTest {
+
+ @Test
+ public void allPropertiesReadWhenPopulated() {
+
+ final long start = System.currentTimeMillis();
+ final long end = start + 100;
+ final String responseCode = "Response-Code";
+ final String responseDescription = "Response-Description";
+ final String ipAddress = "10.56.20.70";
+
+ AuditData data = AuditData.builder().startTime(start).endTime(end).statusCode(StatusCode.COMPLETE)
+ .responseCode(responseCode).responseDescription(responseDescription).clientIpAddress(ipAddress).build();
+
+ assertEquals(data.getClientIpAddress(), ipAddress);
+ assertEquals(data.getEndTime(), end);
+ assertEquals(data.getStartTime(), start);
+ assertEquals(data.getResponseCode(), responseCode);
+ assertEquals(data.getResponseDescription(), responseDescription);
+ assertEquals(data.getStatusCode(), StatusCode.COMPLETE);
+ }
+
+ @Test
+ public void allPropertiesEmptyWhenUnpopulated() {
+ AuditData data = AuditData.builder().build();
+ assertEquals(data.getStartTime(), 0);
+ assertEquals(data.getEndTime(), 0);
+ assertNull(data.getClientIpAddress());
+ assertNull(data.getResponseCode());
+ assertNull(data.getResponseDescription());
+ assertNull(data.getStatusCode());
+ }
+} \ No newline at end of file
diff --git a/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/test/java/org/openecomp/sdc/logging/api/LoggerFactoryTest.java b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/test/java/org/openecomp/sdc/logging/api/LoggerFactoryTest.java
index e174a32271..1889f3e172 100644
--- a/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/test/java/org/openecomp/sdc/logging/api/LoggerFactoryTest.java
+++ b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/test/java/org/openecomp/sdc/logging/api/LoggerFactoryTest.java
@@ -70,7 +70,7 @@ public class LoggerFactoryTest {
logger.warn("");
logger.info("");
logger.debug("");
- logger.audit(new SpyAuditData());
+ logger.audit(null);
logger.metrics("");
}
}
diff --git a/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/test/java/org/openecomp/sdc/logging/api/SpyAuditData.java b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/test/java/org/openecomp/sdc/logging/api/SpyAuditData.java
deleted file mode 100644
index 8766f2598b..0000000000
--- a/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/test/java/org/openecomp/sdc/logging/api/SpyAuditData.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright © 2016-2018 European Support Limited
- *
- * 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.openecomp.sdc.logging.api;
-
-import java.util.HashSet;
-import java.util.Set;
-
-public class SpyAuditData implements AuditData{
- private final Set<String> calledMethods = new HashSet<>();
-
- @Override
- public long getStartTime() {
- calledMethods.add("getStartTime");
- return 0;
- }
-
- @Override
- public long getEndTime() {
- calledMethods.add("getEndTime");
- return 0;
- }
-
- @Override
- public AuditData.StatusCode getStatusCode() {
- calledMethods.add("getEndTime");
- return null;
- }
-
- @Override
- public String getResponseCode() {
- calledMethods.add("getResponseCode");
- return null;
- }
-
- @Override
- public String getResponseDescription() {
- calledMethods.add("getResponseDescription");
- return null;
- }
-
- @Override
- public String getClientIpAddress() {
- calledMethods.add("getClientIpAddress");
- return null;
- }
-
- public boolean wasCalled(String method) {
- return calledMethods.contains(method);
- }
-}
diff --git a/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-core/pom.xml b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-core/pom.xml
index c6f2578129..2bbd0d2d01 100644
--- a/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-core/pom.xml
+++ b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-core/pom.xml
@@ -22,6 +22,7 @@
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>${aspectj.version}</version>
+ <scope>provided</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
@@ -32,11 +33,13 @@
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>${logback.version}</version>
+ <scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>${servlet.version}</version>
+ <scope>provided</scope>
</dependency>
<!-- for testing -->
diff --git a/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-core/src/main/java/org/openecomp/sdc/logging/slf4j/SLF4JLoggerWrapper.java b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-core/src/main/java/org/openecomp/sdc/logging/slf4j/SLF4JLoggerWrapper.java
index 416af8fff1..a8ada8777f 100644
--- a/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-core/src/main/java/org/openecomp/sdc/logging/slf4j/SLF4JLoggerWrapper.java
+++ b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-core/src/main/java/org/openecomp/sdc/logging/slf4j/SLF4JLoggerWrapper.java
@@ -16,40 +16,50 @@
package org.openecomp.sdc.logging.slf4j;
+import java.text.Format;
+import java.text.SimpleDateFormat;
import org.openecomp.sdc.logging.api.AuditData;
import org.openecomp.sdc.logging.api.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-
-import static org.openecomp.sdc.logging.slf4j.SLF4JLoggingServiceProvider.PREFIX;
-
/**
* @author EVITALIY
* @since 08 Jan 18
*/
class SLF4JLoggerWrapper implements Logger {
- private static final String BEGIN_TIMESTAMP = PREFIX + "BeginTimestamp";
- private static final String END_TIMESTAMP = PREFIX + "EndTimestamp";
- private static final String ELAPSED_TIME = PREFIX + "ElapsedTime";
- private static final String STATUS_CODE = PREFIX + "StatusCode";
- private static final String RESPONSE_CODE = PREFIX + "ResponseCode";
- private static final String RESPONSE_DESCRIPTION = PREFIX + "ResponsDescription";
- private static final String CLIENT_IP_ADDRESS = PREFIX + "ClientIpAddress";
-
//The specified format presents time in UTC formatted per ISO 8601, as required by ONAP logging guidelines
- private final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
+
+ private static final String DATE_TIME_PATTERN = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX";
+ private static final String PREFIX = "";
+
+ static final String BEGIN_TIMESTAMP = PREFIX + "BeginTimestamp";
+ static final String END_TIMESTAMP = PREFIX + "EndTimestamp";
+ static final String ELAPSED_TIME = PREFIX + "ElapsedTime";
+ static final String STATUS_CODE = PREFIX + "StatusCode";
+ static final String RESPONSE_CODE = PREFIX + "ResponseCode";
+ static final String RESPONSE_DESCRIPTION = PREFIX + "ResponseDescription";
+ static final String CLIENT_IP_ADDRESS = PREFIX + "ClientIpAddress";
+
+ private static final String[] ALL_MDC_FIELDS = {
+ BEGIN_TIMESTAMP, END_TIMESTAMP, ELAPSED_TIME, STATUS_CODE,
+ RESPONSE_CODE, RESPONSE_DESCRIPTION, CLIENT_IP_ADDRESS
+ };
+
private final org.slf4j.Logger logger;
+ SLF4JLoggerWrapper(org.slf4j.Logger delegate) {
+ this.logger = delegate;
+ }
+
+ // May cause http://www.slf4j.org/codes.html#loggerNameMismatch
SLF4JLoggerWrapper(Class<?> clazz) {
- logger = LoggerFactory.getLogger(clazz);
+ this(LoggerFactory.getLogger(clazz));
}
SLF4JLoggerWrapper(String className) {
- logger = LoggerFactory.getLogger(className);
+ this(LoggerFactory.getLogger(className));
}
@Override
@@ -96,42 +106,41 @@ class SLF4JLoggerWrapper implements Logger {
public void audit(AuditData data) {
if (data == null) {
- return;
+ return; // not failing if null
}
- MDC.put(BEGIN_TIMESTAMP, DATE_FORMAT.format(new Date(data.getStartTime())));
- MDC.put(END_TIMESTAMP, DATE_FORMAT.format(new Date(data.getEndTime())));
- MDC.put(ELAPSED_TIME, String.valueOf(data.getEndTime() - data.getStartTime()));
+ putTimes(data);
+ putIfNotNull(RESPONSE_CODE, data.getResponseCode());
+ putIfNotNull(RESPONSE_DESCRIPTION, data.getResponseDescription());
+ putIfNotNull(CLIENT_IP_ADDRESS, data.getClientIpAddress());
if (data.getStatusCode() != null) {
- MDC.put(STATUS_CODE, data.getStatusCode() == AuditData.StatusCode.COMPLETE ? "COMPLETE" : "ERROR");
- }
-
- if (data.getResponseCode() != null) {
- MDC.put(RESPONSE_CODE, data.getResponseCode());
- }
-
- if (data.getResponseDescription() != null) {
- MDC.put(RESPONSE_DESCRIPTION, data.getResponseDescription());
- }
-
- if (data.getClientIpAddress() != null) {
- MDC.put(CLIENT_IP_ADDRESS, data.getClientIpAddress());
+ MDC.put(STATUS_CODE, data.getStatusCode().name());
}
try {
logger.info(Markers.AUDIT, "");
} finally {
- MDC.remove(BEGIN_TIMESTAMP);
- MDC.remove(END_TIMESTAMP);
- MDC.remove(ELAPSED_TIME);
- MDC.remove(STATUS_CODE);
- MDC.remove(RESPONSE_CODE);
- MDC.remove(RESPONSE_DESCRIPTION);
- MDC.remove(CLIENT_IP_ADDRESS);
+ for (String k : ALL_MDC_FIELDS) {
+ MDC.remove(k);
+ }
}
}
+ private void putIfNotNull(String key, String value) {
+ if (value != null) {
+ MDC.put(key, value);
+ }
+ }
+
+ private void putTimes(AuditData data) {
+ // SimpleDateFormat is not thread-safe and cannot be a constant
+ Format dateTimeFormat = new SimpleDateFormat(DATE_TIME_PATTERN);
+ MDC.put(BEGIN_TIMESTAMP, dateTimeFormat.format(data.getStartTime()));
+ MDC.put(END_TIMESTAMP, dateTimeFormat.format(data.getEndTime()));
+ MDC.put(ELAPSED_TIME, String.valueOf(data.getEndTime() - data.getStartTime()));
+ }
+
@Override
public boolean isDebugEnabled() {
return logger.isDebugEnabled();
diff --git a/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-core/src/main/java/org/openecomp/sdc/logging/slf4j/SLF4JLoggingServiceProvider.java b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-core/src/main/java/org/openecomp/sdc/logging/slf4j/SLF4JLoggingServiceProvider.java
index 86b2297371..fbda93cf61 100644
--- a/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-core/src/main/java/org/openecomp/sdc/logging/slf4j/SLF4JLoggingServiceProvider.java
+++ b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-core/src/main/java/org/openecomp/sdc/logging/slf4j/SLF4JLoggingServiceProvider.java
@@ -28,13 +28,7 @@ import org.slf4j.MDC;
*/
public class SLF4JLoggingServiceProvider implements LoggingServiceProvider {
- public static final String PREFIX = "";
private static final String KEY_CANNOT_BE_NULL = "Key cannot be null";
- private static final String REQUEST_ID = PREFIX + "RequestId";
- private static final String SERVICE_NAME = PREFIX + "ServiceName";
- private static final String PARTNER_NAME = PREFIX + "PartnerName";
-
- private static final String[] ALL_FIELDS = { REQUEST_ID, SERVICE_NAME, PARTNER_NAME };
@Override
public Logger getLogger(String className) {
@@ -74,14 +68,12 @@ public class SLF4JLoggingServiceProvider implements LoggingServiceProvider {
@Override
public Runnable copyToRunnable(Runnable runnable) {
Objects.requireNonNull(runnable, "Runnable cannot be null");
- // TODO: Copy only the fields this service is responsible for
return new MDCRunnableWrapper(runnable);
}
@Override
public <V> Callable<V> copyToCallable(Callable<V> callable) {
Objects.requireNonNull(callable, "Runnable cannot be null");
- // TODO: Copy only the fields this service is responsible for
return new MDCCallableWrapper<>(callable);
}
diff --git a/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-core/src/test/java/org/openecomp/sdc/logging/LogFileCreationTest.java b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-core/src/test/java/org/openecomp/sdc/logging/LogFileCreationTest.java
index 4595e567c8..14dab13c9e 100644
--- a/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-core/src/test/java/org/openecomp/sdc/logging/LogFileCreationTest.java
+++ b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-core/src/test/java/org/openecomp/sdc/logging/LogFileCreationTest.java
@@ -21,8 +21,17 @@ import org.openecomp.sdc.logging.api.Logger;
import org.openecomp.sdc.logging.api.LoggerFactory;
import org.testng.annotations.Test;
+/**
+ * This is only for manual testing to make sure that a log file is created as expected.
+ * To run change {@link #ENABLED} to 'true'
+ *
+ * @author evitaliy
+ * @since 13/09/2016.
+ */
public class LogFileCreationTest {
+
private static final boolean ENABLED = false; // for manual testing change to 'true'
+
private static final Logger LOGGER = LoggerFactory.getLogger(LogFileCreationTest.class);
@Test(enabled = ENABLED)
@@ -32,8 +41,7 @@ public class LogFileCreationTest {
@Test(enabled = ENABLED)
public void testAudit() {
- SpyAuditData auditData = new SpyAuditData();
- LOGGER.audit(auditData);
+ LOGGER.audit(AuditData.builder().build());
}
@Test(enabled = ENABLED)
@@ -55,47 +63,4 @@ public class LogFileCreationTest {
public void testError() {
LOGGER.error("This is error");
}
-
- private class SpyAuditData implements AuditData {
- @Override
- public long getStartTime() {
-
- return 0;
-
- }
-
- @Override
- public long getEndTime(){
-
- return 0;
- }
-
- @Override
- public StatusCode getStatusCode(){
-
- return null;
-
- }
-
- @Override
- public String getResponseCode(){
-
- return null;
-
- }
-
- @Override
- public String getResponseDescription(){
-
- return null;
-
- }
-
- @Override
- public String getClientIpAddress(){
-
- return null;
-
- }
- }
}
diff --git a/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-core/src/test/java/org/openecomp/sdc/logging/slf4j/SLF4JLoggerWrapperTest.java b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-core/src/test/java/org/openecomp/sdc/logging/slf4j/SLF4JLoggerWrapperTest.java
new file mode 100644
index 0000000000..a4a5e5c72c
--- /dev/null
+++ b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-core/src/test/java/org/openecomp/sdc/logging/slf4j/SLF4JLoggerWrapperTest.java
@@ -0,0 +1,190 @@
+/*
+ * Copyright © 2016-2018 European Support Limited
+ *
+ * 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.openecomp.sdc.logging.slf4j;
+
+import static org.openecomp.sdc.logging.slf4j.SLF4JLoggerWrapper.BEGIN_TIMESTAMP;
+import static org.openecomp.sdc.logging.slf4j.SLF4JLoggerWrapper.CLIENT_IP_ADDRESS;
+import static org.openecomp.sdc.logging.slf4j.SLF4JLoggerWrapper.ELAPSED_TIME;
+import static org.openecomp.sdc.logging.slf4j.SLF4JLoggerWrapper.END_TIMESTAMP;
+import static org.openecomp.sdc.logging.slf4j.SLF4JLoggerWrapper.RESPONSE_CODE;
+import static org.openecomp.sdc.logging.slf4j.SLF4JLoggerWrapper.RESPONSE_DESCRIPTION;
+import static org.openecomp.sdc.logging.slf4j.SLF4JLoggerWrapper.STATUS_CODE;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertNull;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.util.Arrays;
+import java.util.Map;
+import org.openecomp.sdc.logging.api.AuditData;
+import org.openecomp.sdc.logging.api.StatusCode;
+import org.slf4j.Logger;
+import org.slf4j.MDC;
+import org.testng.annotations.Test;
+
+/**
+ * @author EVITALIY
+ * @since 05 Mar 18
+ */
+public class SLF4JLoggerWrapperTest {
+
+ @Test
+ public void auditDoesNotFailWhenInputNull() {
+ new SLF4JLoggerWrapper(this.getClass()).audit(null);
+ }
+
+ @Test
+ public void beginTimeAvailableWhenPassed() {
+ SpyLogger spy = createSpy();
+ long start = System.currentTimeMillis();
+ new SLF4JLoggerWrapper(spy).audit(AuditData.builder().startTime(start).build());
+ assertNotNull(spy.mdc().get(BEGIN_TIMESTAMP));
+ }
+
+ @Test
+ public void entTimeAvailableWhenPassed() {
+ SpyLogger spy = createSpy();
+ long end = System.currentTimeMillis();
+ new SLF4JLoggerWrapper(spy).audit(AuditData.builder().endTime(end).build());
+ assertNotNull(spy.mdc().get(END_TIMESTAMP));
+ }
+
+ @Test
+ public void elapsedTimeAvailableWhenPassed() {
+ SpyLogger spy = createSpy();
+ long start = System.currentTimeMillis();
+ new SLF4JLoggerWrapper(spy).audit(AuditData.builder()
+ .startTime(start).endTime(start).build());
+ assertNotNull(spy.mdc().get(ELAPSED_TIME));
+ }
+
+ @Test
+ public void statusCodeAvailableWhenPassed() {
+ SpyLogger spy = createSpy();
+ new SLF4JLoggerWrapper(spy).audit(AuditData.builder().statusCode(StatusCode.COMPLETE).build());
+ assertEquals(spy.mdc().get(STATUS_CODE), StatusCode.COMPLETE.name());
+ }
+
+ @Test
+ public void statusCodeEmptyWhenNotPassed() {
+ SpyLogger spy = createSpy();
+ new SLF4JLoggerWrapper(spy).audit(AuditData.builder().build());
+ assertNull(spy.mdc().get(STATUS_CODE));
+ }
+
+ @Test
+ public void responseCodeAvailableWhenPassed() {
+ final String responseCode = "SpyResponse";
+ SpyLogger spy = createSpy();
+ new SLF4JLoggerWrapper(spy).audit(AuditData.builder().responseCode(responseCode).build());
+ assertEquals(spy.mdc().get(RESPONSE_CODE), responseCode);
+ }
+
+ @Test
+ public void responseCodeEmptyWhenNotPassed() {
+ SpyLogger spy = createSpy();
+ new SLF4JLoggerWrapper(spy).audit(AuditData.builder().build());
+ assertNull(spy.mdc().get(RESPONSE_CODE));
+ }
+
+ @Test
+ public void responseDescriptionAvailableWhenPassed() {
+ final String responseDescription = "SpyDescription";
+ SpyLogger spy = createSpy();
+ new SLF4JLoggerWrapper(spy).audit(AuditData.builder().responseDescription(responseDescription).build());
+ assertEquals(spy.mdc().get(RESPONSE_DESCRIPTION), responseDescription);
+ }
+
+ @Test
+ public void responseDescriptionEmptyWhenNotPassed() {
+ SpyLogger spy = createSpy();
+ new SLF4JLoggerWrapper(spy).audit(AuditData.builder().build());
+ assertNull(spy.mdc().get(RESPONSE_DESCRIPTION));
+ }
+
+ @Test
+ public void clientIpAddressAvailableWhenPassed() {
+ final String ipAddress = "10.56.20.20";
+ SpyLogger spy = createSpy();
+ new SLF4JLoggerWrapper(spy).audit(AuditData.builder().clientIpAddress(ipAddress).build());
+ assertEquals(spy.mdc().get(CLIENT_IP_ADDRESS), ipAddress);
+ }
+
+ @Test
+ public void clientIpAddressEmptyWhenNotPassed() {
+ SpyLogger spy = createSpy();
+ new SLF4JLoggerWrapper(spy).audit(AuditData.builder().build());
+ assertNull(spy.mdc().get(CLIENT_IP_ADDRESS));
+ }
+
+ @Test
+ public void elapsedTimeEqualsDifferenceBetweenStartAndEnd() {
+ SpyLogger spy = createSpy();
+ final long diff = 1024;
+ long start = System.currentTimeMillis();
+ long end = start + diff;
+ new SLF4JLoggerWrapper(spy).audit(AuditData.builder().startTime(start).endTime(end).build());
+ assertEquals(spy.mdc().get(ELAPSED_TIME), Long.toString(diff));
+ }
+
+ interface SpyLogger extends Logger {
+
+ Map<String, String> mdc();
+ }
+
+ /**
+ * Creates a in instance of Logger that can be used to track MDC changes as part of an invocation of
+ * Logger.audit().
+ *
+ * @return object that implements {@link SpyLogger}
+ */
+ private static SpyLogger createSpy() {
+
+ // build a dynamic proxy to avoid implementing the long list of Logger methods
+ // when we actually need just Logger.info() with the audit marker
+ ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
+ return SpyLogger.class.cast(
+ Proxy.newProxyInstance(classLoader, new Class<?>[]{SpyLogger.class}, new SpyingInvocationHandler()));
+ }
+
+ private static class SpyingInvocationHandler implements InvocationHandler {
+
+ private Map<String, String> mdc;
+
+ @Override
+ public Object invoke(Object proxy, Method method, Object[] args) {
+
+ // return the remembered MDC for spying
+ if (method.getName().equals("mdc")) {
+ return mdc;
+ }
+
+ // filter out everything that's not related to audit
+ if (!method.getName().equals("info") || args.length == 0 || !args[0].equals(Markers.AUDIT)) {
+ throw new UnsupportedOperationException("Method " + method.getName() + " with arguments " +
+ Arrays.toString(args) + " wasn't supposed to be called");
+ }
+
+ // remember the MDC that was active during the invocation
+ mdc = MDC.getCopyOfContextMap();
+
+ return null;
+ }
+ }
+} \ No newline at end of file