aboutsummaryrefslogtreecommitdiffstats
path: root/reference/logging-slf4j-demo
diff options
context:
space:
mode:
Diffstat (limited to 'reference/logging-slf4j-demo')
-rw-r--r--reference/logging-slf4j-demo/README.md50
-rw-r--r--reference/logging-slf4j-demo/pom.xml141
-rw-r--r--reference/logging-slf4j-demo/src/main/java/org/onap/logging/ref/slf4j/demo/SLF4JRefApplication.java54
-rw-r--r--reference/logging-slf4j-demo/src/main/java/org/onap/logging/ref/slf4j/demo/bean/AbstractBean.java96
-rw-r--r--reference/logging-slf4j-demo/src/main/java/org/onap/logging/ref/slf4j/demo/bean/Request.java64
-rw-r--r--reference/logging-slf4j-demo/src/main/java/org/onap/logging/ref/slf4j/demo/bean/Response.java63
-rw-r--r--reference/logging-slf4j-demo/src/main/java/org/onap/logging/ref/slf4j/demo/bean/package-info.java26
-rw-r--r--reference/logging-slf4j-demo/src/main/java/org/onap/logging/ref/slf4j/demo/component/AbstractComponent.java278
-rw-r--r--reference/logging-slf4j-demo/src/main/java/org/onap/logging/ref/slf4j/demo/component/alpha/ComponentAlpha.java53
-rw-r--r--reference/logging-slf4j-demo/src/main/java/org/onap/logging/ref/slf4j/demo/component/alpha/package-info.java26
-rw-r--r--reference/logging-slf4j-demo/src/main/java/org/onap/logging/ref/slf4j/demo/component/beta/ComponentBeta.java53
-rw-r--r--reference/logging-slf4j-demo/src/main/java/org/onap/logging/ref/slf4j/demo/component/beta/package-info.java26
-rw-r--r--reference/logging-slf4j-demo/src/main/java/org/onap/logging/ref/slf4j/demo/component/delta/ComponentDelta.java53
-rw-r--r--reference/logging-slf4j-demo/src/main/java/org/onap/logging/ref/slf4j/demo/component/delta/package-info.java26
-rw-r--r--reference/logging-slf4j-demo/src/main/java/org/onap/logging/ref/slf4j/demo/component/gamma/ComponentGamma.java53
-rw-r--r--reference/logging-slf4j-demo/src/main/java/org/onap/logging/ref/slf4j/demo/component/gamma/package-info.java26
-rw-r--r--reference/logging-slf4j-demo/src/main/java/org/onap/logging/ref/slf4j/demo/component/package-info.java26
-rw-r--r--reference/logging-slf4j-demo/src/main/java/org/onap/logging/ref/slf4j/demo/package-info.java30
-rw-r--r--reference/logging-slf4j-demo/src/main/resources/logback.xml35
-rw-r--r--reference/logging-slf4j-demo/src/main/webapp/WEB-INF/web.xml2
-rw-r--r--reference/logging-slf4j-demo/src/test/java/org/onap/logging/ref/slf4j/CallGraphTest.java207
-rw-r--r--reference/logging-slf4j-demo/src/test/java/org/onap/logging/ref/slf4j/analysis/CallGraphAnalyzer.java114
-rw-r--r--reference/logging-slf4j-demo/src/test/java/org/onap/logging/ref/slf4j/analysis/CallGraphReportWriter.java111
-rw-r--r--reference/logging-slf4j-demo/src/test/java/org/onap/logging/ref/slf4j/analysis/LogEntry.java238
-rw-r--r--reference/logging-slf4j-demo/src/test/java/org/onap/logging/ref/slf4j/analysis/LogEntryTest.java71
-rw-r--r--reference/logging-slf4j-demo/src/test/java/org/onap/logging/ref/slf4j/demo/SLF4JRefApplicationTest.java47
-rw-r--r--reference/logging-slf4j-demo/src/test/java/org/onap/logging/ref/slf4j/demo/bean/RequestTest.java64
-rw-r--r--reference/logging-slf4j-demo/src/test/java/org/onap/logging/ref/slf4j/demo/bean/ResponseTest.java61
-rw-r--r--reference/logging-slf4j-demo/src/test/java/org/onap/logging/ref/slf4j/demo/component/AbstractComponentTest.java29
-rw-r--r--reference/logging-slf4j-demo/src/test/java/org/onap/logging/ref/slf4j/demo/component/alpha/ComponentAlphaTest.java45
-rw-r--r--reference/logging-slf4j-demo/src/test/java/org/onap/logging/ref/slf4j/demo/component/beta/ComponentBetaTest.java45
-rw-r--r--reference/logging-slf4j-demo/src/test/java/org/onap/logging/ref/slf4j/demo/component/delta/ComponentDeltaTest.java45
-rw-r--r--reference/logging-slf4j-demo/src/test/java/org/onap/logging/ref/slf4j/demo/component/gamma/ComponentGammaTest.java45
-rw-r--r--reference/logging-slf4j-demo/src/test/java/testng.xml8
34 files changed, 2311 insertions, 0 deletions
diff --git a/reference/logging-slf4j-demo/README.md b/reference/logging-slf4j-demo/README.md
new file mode 100644
index 0000000..4434964
--- /dev/null
+++ b/reference/logging-slf4j-demo/README.md
@@ -0,0 +1,50 @@
+# README - slf4j-reference
+
+This project gives an example of ONAP-compliant logging using SLF4J logging.
+
+## Adapter
+
+In ```org.onap.logging.ref.slf4j.common```, there are TWO classes:
+1. ```org.onap.logging.ref.slf4j.common.ONAPLogConstants```, providing declarations of standard ONAP Markers, MDCs and HTTP headers.
+2. ```org.onap.logging.ref.slf4j.common.ONAPLogAdapter```, providing a lightweight, compliant implementation of the ONAP logging spec.
+
+The adapter provides:
+1. A loosely-coupled SLF4j logging wrapper:
+ * To be used for logging ONAP ```entry```, ```exit``` and ```invoke``` behavior.
+ * Devolving all *application* logging to the component, via the regular SLF4J ```Logger``` facade.
+2. Customization options:
+ * *Cheap*, by way of bean properties. This is suited to most Use Cases.
+ * *Sophisticated*:
+ * By OPTIONALLY implementing one of a number of adapters:
+ * ```RequestAdapter``` to read incoming headers.
+ * ```ServiceDescriptor``` for reporting attributes of the current service.
+ * ```ResponseDescriptor``` for reporting outcomes.
+ * ```RequestBuilder``` for setting southbound request headers.
+ * By OPTIONALLY overriding methods like ```ONAPLogAdapter#setMDCs(RequestAdapter)```.
+
+Note that:
+* The adapter implementation uses static inner classes in order to fit in a single source file. This was an objective.
+
+## WAR
+
+Building produces a simple (spring-boot](https://projects.spring.io/spring-boot/) example WAR, which can be launched from this directory with:
+
+```bash
+$ java -war target/*war
+```
+
+The WAR publishes four web services:
+1. ```services/alpha```
+2. ```services/beta```
+3. ```services/gamma```
+4. ```services/delta```
+
+... each of which can invoke the others.
+
+The purpose of this WAR is to demonstrate minimalist ONAP-compliant logging for web components, but a secondary purpose is to demonstrate that the call graph can be generated for a (mostly) representative set of interacting REST services.
+
+## Tests
+
+Tests for:
+1. Code in the (potentially) reusable ``common`` package.
+2. Validating that emitted logs can be used to generate an unambiguous call graph.
diff --git a/reference/logging-slf4j-demo/pom.xml b/reference/logging-slf4j-demo/pom.xml
new file mode 100644
index 0000000..c4542b3
--- /dev/null
+++ b/reference/logging-slf4j-demo/pom.xml
@@ -0,0 +1,141 @@
+<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.logging-analytics</groupId>
+ <artifactId>logging-reference</artifactId>
+ <version>1.2.0-SNAPSHOT</version>
+ <relativePath>..</relativePath>
+ </parent>
+ <artifactId>logging-slf4j-demo</artifactId>
+ <name>logging-slf4j-demo</name>
+ <packaging>war</packaging>
+ <version>1.2.0-SNAPSHOT</version>
+
+ <properties>
+ <springframework.boot.version>1.5.10.RELEASE</springframework.boot.version>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>logging-slf4j</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-web</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-lang3</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>ch.qos.logback</groupId>
+ <artifactId>logback-classic</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.mashape.unirest</groupId>
+ <artifactId>unirest-java</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.google.code.gson</groupId>
+ <artifactId>gson</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-test</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.testng</groupId>
+ <artifactId>testng</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.hamcrest</groupId>
+ <artifactId>hamcrest-all</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-dependencies</artifactId>
+ <version>${springframework.boot.version}</version>
+ <type>pom</type>
+ <scope>import</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-lang3</artifactId>
+ <version>3.4</version>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ <version>1.7.25</version>
+ </dependency>
+ <dependency>
+ <groupId>ch.qos.logback</groupId>
+ <artifactId>logback-classic</artifactId>
+ <version>1.2.3</version>
+ </dependency>
+ <dependency>
+ <groupId>com.mashape.unirest</groupId>
+ <artifactId>unirest-java</artifactId>
+ <version>1.4.9</version>
+ </dependency>
+ <dependency>
+ <groupId>org.testng</groupId>
+ <artifactId>testng</artifactId>
+ <version>6.8.5</version>
+ </dependency>
+ <dependency>
+ <groupId>org.hamcrest</groupId>
+ <artifactId>hamcrest-all</artifactId>
+ <version>1.3</version>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-test</artifactId>
+ <version>5.0.5.RELEASE</version>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-war-plugin</artifactId>
+ <configuration/>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>3.7.0</version>
+ <configuration>
+ <source>1.8</source>
+ <target>1.8</target>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-maven-plugin</artifactId>
+ <version>${springframework.boot.version}</version>
+ <executions>
+ <execution>
+ <goals>
+ <goal>repackage</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
diff --git a/reference/logging-slf4j-demo/src/main/java/org/onap/logging/ref/slf4j/demo/SLF4JRefApplication.java b/reference/logging-slf4j-demo/src/main/java/org/onap/logging/ref/slf4j/demo/SLF4JRefApplication.java
new file mode 100644
index 0000000..146f66b
--- /dev/null
+++ b/reference/logging-slf4j-demo/src/main/java/org/onap/logging/ref/slf4j/demo/SLF4JRefApplication.java
@@ -0,0 +1,54 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.logging
+ * ================================================================================
+ * Copyright © 2018 Amdocs
+ * 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.logging.ref.slf4j.demo;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+/**
+ * Spring launcher, for testing invocations via REST.
+ */
+@SpringBootApplication
+public class SLF4JRefApplication {
+
+ /** System property override, read by embedded Logback configuration. */
+ public static final String SLF4J_OUTPUT_DIRECTORY = "SLF4J_OUTPUT_DIRECTORY";
+
+ /**
+ * Launch from CLI.
+ * @param args command-line args.
+ * @throws Exception launch error.
+ */
+ public static void main(final String[] args) throws Exception {
+ initOutputDirectory();
+ SpringApplication.run(SLF4JRefApplication.class, args);
+ }
+
+ /**
+ * Make sure the output directory has a default value. (It'll be
+ * overridden by tests, but not in services.)
+ */
+ static void initOutputDirectory() {
+ System.getProperties().setProperty(SLF4J_OUTPUT_DIRECTORY,
+ System.getProperty(SLF4J_OUTPUT_DIRECTORY, "."));
+ }
+} \ No newline at end of file
diff --git a/reference/logging-slf4j-demo/src/main/java/org/onap/logging/ref/slf4j/demo/bean/AbstractBean.java b/reference/logging-slf4j-demo/src/main/java/org/onap/logging/ref/slf4j/demo/bean/AbstractBean.java
new file mode 100644
index 0000000..6c6060d
--- /dev/null
+++ b/reference/logging-slf4j-demo/src/main/java/org/onap/logging/ref/slf4j/demo/bean/AbstractBean.java
@@ -0,0 +1,96 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.logging
+ * ================================================================================
+ * Copyright © 2018 Amdocs
+ * 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.logging.ref.slf4j.demo.bean;
+
+import org.json.JSONObject;
+
+/**
+ * Base class for {@link Request} and {@link Response} beans, since
+ * they're almost the same thing.
+ */
+public abstract class AbstractBean {
+
+ /** Bean property. */
+ private String mService;
+
+ /** Bean property. */
+ private String mCode;
+
+ /** Bean property. */
+ private String mSeverity;
+
+ /**
+ * Getter.
+ * @return bean property.
+ */
+ public String getService() {
+ return this.mService;
+ }
+
+ /**
+ * Setter.
+ * @param service bean property.
+ */
+ public void setService(final String service) {
+ this.mService = service;
+ }
+
+ /**
+ * Getter.
+ * @return bean property.
+ */
+ public String getCode() {
+ return this.mCode;
+ }
+
+ /**
+ * Setter.
+ * @param code bean property.
+ */
+ public void setCode(final String code) {
+ this.mCode = code;
+ }
+
+ /**
+ * Getter.
+ * @return bean property.
+ */
+ public String getSeverity() {
+ return this.mSeverity;
+ }
+
+ /**
+ * Setter.
+ * @param severity bean property.
+ */
+ public void setSeverity(final String severity) {
+ this.mSeverity = severity;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String toString() {
+ return new JSONObject(this).toString(4);
+ }
+}
diff --git a/reference/logging-slf4j-demo/src/main/java/org/onap/logging/ref/slf4j/demo/bean/Request.java b/reference/logging-slf4j-demo/src/main/java/org/onap/logging/ref/slf4j/demo/bean/Request.java
new file mode 100644
index 0000000..5318333
--- /dev/null
+++ b/reference/logging-slf4j-demo/src/main/java/org/onap/logging/ref/slf4j/demo/bean/Request.java
@@ -0,0 +1,64 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.logging
+ * ================================================================================
+ * Copyright © 2018 Amdocs
+ * 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.logging.ref.slf4j.demo.bean;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.json.JSONArray;
+import org.json.JSONObject;
+
+/**
+ * Test class, describing a request to be executed.
+ */
+public class Request extends AbstractBean {
+
+ /** Subrequests to be executed. */
+ private final List<Request> mRequests = new ArrayList<>();
+
+ /**
+ * Get subrequests.
+ * @return subrequests.
+ */
+ public List<Request> getRequests() {
+ return mRequests;
+ }
+
+ /**
+ * Parse from serialized form.
+ * @param in JSON.
+ * @return parsed.
+ */
+ public static Request fromJSON(final JSONObject in) {
+ final Request request = new Request();
+ request.setService(in.optString("service"));
+ request.setCode(in.optString("code"));
+ request.setSeverity(in.optString("severity"));
+ final JSONArray requests = in.optJSONArray("requests");
+ if (requests != null) {
+ for (int i = 0 ; i < requests.length() ; i++) {
+ request.getRequests().add(Request.fromJSON(requests.getJSONObject(i)));
+ }
+ }
+ return request;
+ }
+}
diff --git a/reference/logging-slf4j-demo/src/main/java/org/onap/logging/ref/slf4j/demo/bean/Response.java b/reference/logging-slf4j-demo/src/main/java/org/onap/logging/ref/slf4j/demo/bean/Response.java
new file mode 100644
index 0000000..b0c6a4a
--- /dev/null
+++ b/reference/logging-slf4j-demo/src/main/java/org/onap/logging/ref/slf4j/demo/bean/Response.java
@@ -0,0 +1,63 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.logging
+ * ================================================================================
+ * Copyright © 2018 Amdocs
+ * 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.logging.ref.slf4j.demo.bean;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.json.JSONArray;
+import org.json.JSONObject;
+
+/**
+ * Test class, describing an outcome that should be reported.
+ */
+public class Response extends AbstractBean {
+
+ /** Delegate responses. */
+ private final List<Response> mResponses = new ArrayList<>();
+
+ /**
+ * Get delegate responses.
+ * @return responses.
+ */
+ public List<Response> getResponses() {
+ return mResponses;
+ }
+
+ /**
+ * Parse from serialized form.
+ * @param in JSON.
+ * @return parsed.
+ */
+ public static Response fromJSON(final JSONObject in) {
+ final Response request = new Response();
+ request.setCode(in.optString("code"));
+ request.setSeverity(in.optString("severity"));
+ final JSONArray responses = in.optJSONArray("responses");
+ if (responses != null) {
+ for (int i = 0 ; i < responses.length() ; i++) {
+ request.getResponses().add(Response.fromJSON(responses.getJSONObject(i)));
+ }
+ }
+ return request;
+ }
+}
diff --git a/reference/logging-slf4j-demo/src/main/java/org/onap/logging/ref/slf4j/demo/bean/package-info.java b/reference/logging-slf4j-demo/src/main/java/org/onap/logging/ref/slf4j/demo/bean/package-info.java
new file mode 100644
index 0000000..2364f9f
--- /dev/null
+++ b/reference/logging-slf4j-demo/src/main/java/org/onap/logging/ref/slf4j/demo/bean/package-info.java
@@ -0,0 +1,26 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.logging
+ * ================================================================================
+ * Copyright © 2018 Amdocs
+ * 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.logging.ref.slf4j.demo.bean;
+
+/**
+ * Simple request/responses beans for testcases.
+ */ \ No newline at end of file
diff --git a/reference/logging-slf4j-demo/src/main/java/org/onap/logging/ref/slf4j/demo/component/AbstractComponent.java b/reference/logging-slf4j-demo/src/main/java/org/onap/logging/ref/slf4j/demo/component/AbstractComponent.java
new file mode 100644
index 0000000..b6a2c95
--- /dev/null
+++ b/reference/logging-slf4j-demo/src/main/java/org/onap/logging/ref/slf4j/demo/component/AbstractComponent.java
@@ -0,0 +1,278 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.logging
+ * ================================================================================
+ * Copyright © 2018 Amdocs
+ * 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.logging.ref.slf4j.demo.component;
+
+import java.util.Locale;
+import java.util.Map;
+import java.util.UUID;
+
+import javax.servlet.http.HttpServletRequest;
+
+import com.mashape.unirest.http.HttpResponse;
+import com.mashape.unirest.http.JsonNode;
+import com.mashape.unirest.http.Unirest;
+import com.mashape.unirest.http.exceptions.UnirestException;
+import org.apache.commons.lang3.StringUtils;
+import org.json.JSONObject;
+import org.onap.logging.ref.slf4j.ONAPLogAdapter;
+import org.onap.logging.ref.slf4j.ONAPLogConstants;
+import org.onap.logging.ref.slf4j.demo.bean.Request;
+import org.onap.logging.ref.slf4j.demo.bean.Response;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.slf4j.MDC;
+import org.springframework.http.MediaType;
+import org.springframework.mock.web.MockHttpServletRequest;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * Base class for <tt>Alpha</tt>, <tt>Beta</tt> and <tt>Gamma</tt>
+ * and <tt>Delta</tt> controllers, implementing all the actual logic.
+ *
+ * <p>(The subclasses provide nothing but identifiers to allow them
+ * to be distinguished from one another, for the purposes of addressing
+ * requests and generating the call graph from their logger output.)</p>
+ */
+@RestController
+public abstract class AbstractComponent {
+
+ /**
+ * Test switch, routing invocations between components in-process,
+ * rather than via REST over HTTP.
+ */
+ private static boolean sInProcess;
+
+ /**
+ * Get service identifier, used to derive {@link #getServiceName()},
+ * <tt>PartnerName</tt>, etc.
+ * @return <tt>alpha</tt>, <tt>beta</tt>, <tt>gamma</tt>.
+ */
+ protected abstract String getId();
+
+ /**
+ * Get component UUID.
+ * @return globally unique ID string.
+ */
+ protected abstract String getInstanceUUID();
+
+ /**
+ * Execute REST request.
+ * @param request request data.
+ * @param http HTTP request.
+ * @return response data.
+ * @throws UnirestException REST error.
+ */
+ @RequestMapping(value = "/invoke",
+ method = RequestMethod.POST,
+ consumes = MediaType.APPLICATION_JSON_VALUE,
+ produces = MediaType.APPLICATION_JSON_VALUE)
+ public Response execute(final Request request,
+ final HttpServletRequest http) throws UnirestException {
+
+ final ONAPLogAdapter adapter = new ONAPLogAdapter(this.getLogger());
+
+ try {
+
+ adapter.entering(new ONAPLogAdapter.HttpServletRequestAdapter(http));
+
+ final Response response = new Response();
+ response.setService(request.getService());
+ final String code = StringUtils.defaultString(request.getCode(), "OK").toUpperCase();
+ response.setCode(this.getId() + "." + code);
+ response.setSeverity(StringUtils.defaultString(request.getSeverity(), "INFO"));
+
+ for (final Request target : request.getRequests()) {
+ final Response targetResponse = this.executeDelegate(target, http, adapter);
+ response.getResponses().add(targetResponse);
+ }
+
+ return response;
+ }
+ finally {
+ adapter.exiting();
+ }
+ }
+
+ /**
+ * Set in-process mode, for unit testing.
+ */
+ static void setInProcess() {
+ sInProcess = true;
+ }
+
+ /**
+ * Execute request.
+ * @param request to be executed.
+ * @param http incoming HTTP request.
+ * @param logger logging adapter.
+ * @return response
+ */
+ private Response executeDelegate(final Request request,
+ final HttpServletRequest http,
+ final ONAPLogAdapter logger) {
+
+
+ notNull(request);
+ notNull(http);
+
+ // Downstream call.
+
+ try {
+
+ if (sInProcess) {
+ return this.executeInProcess(request, logger);
+ }
+
+ return this.executeREST(request, http, logger);
+ }
+ catch (final UnirestException | ReflectiveOperationException e) {
+ logger.unwrap().error("Execute error", e);
+ final Response response = new Response();
+ response.setCode((this.getServiceName() + ".INVOKE_ERROR").toUpperCase(Locale.getDefault()));
+ response.setSeverity("ERROR");
+ return response;
+ }
+ }
+
+ /**
+ * Execute invocation over REST.
+ * @param request mock request to be executed.
+ * @param http HTTP request, used (only) to address the outgoing request.
+ * @param logger logger adapter.
+ * @return invocation response.
+ * @throws UnirestException REST error.
+ */
+ private Response executeREST(final Request request,
+ final HttpServletRequest http,
+ final ONAPLogAdapter logger) throws UnirestException {
+ // Otherwise via REST.
+
+ logger.unwrap().info("Sending:\n{}", request);
+ final StringBuilder url = new StringBuilder();
+ url.append(http.getProtocol()).append("://");
+ url.append(http.getServerName()).append(':');
+ url.append(http.getServerPort()).append("/services/").append(request.getService());
+
+ final UUID invocationID = logger.invoke(ONAPLogConstants.InvocationMode.SYNCHRONOUS);
+ final HttpResponse<JsonNode> response =
+ Unirest.post(url.toString())
+ .header(ONAPLogConstants.Headers.REQUEST_ID, MDC.get(ONAPLogConstants.MDCs.REQUEST_ID))
+ .header(ONAPLogConstants.Headers.INVOCATION_ID, invocationID.toString())
+ .header(ONAPLogConstants.Headers.PARTNER_NAME, this.getServiceName())
+ .header("Accept", MediaType.APPLICATION_JSON_VALUE)
+ .header("Content-Type", MediaType.APPLICATION_JSON_VALUE)
+ .body(request)
+ .asJson();
+
+ // Parse response.
+
+ final JSONObject responseJSON = response.getBody().getObject();
+ logger.unwrap().info("Received:\n{}", responseJSON);
+ return Response.fromJSON(responseJSON);
+ }
+
+ /**
+ * Execute request in-process.
+ * @param request mock request to be executed.
+ * @param logger logger adapter.
+ * @return invocation response.
+ * @throws ReflectiveOperationException error loading target class.
+ * @throws UnirestException REST error.
+ */
+ private Response executeInProcess(final Request request,
+ final ONAPLogAdapter logger) throws ReflectiveOperationException, UnirestException {
+
+ logger.unwrap().info("Executing in-process:\n{}", request);
+
+ // Derive the name of the delegate class.
+
+ final String delegateClass
+ = AbstractComponent.class.getPackage().getName() + "." + request.getService()
+ + ".Component" + request.getService().substring(0, 1).toUpperCase()
+ + request.getService().substring(1);
+ logger.unwrap().info("Invoking in-process [{}].", delegateClass);
+ final AbstractComponent component = (AbstractComponent)Class.forName(delegateClass).newInstance();
+
+ // Using Spring mock since we're not *actually* going over HTTP.
+
+ final MockHttpServletRequest mock = new MockHttpServletRequest();
+
+ // Generate INVOCATION_ID, and set MDCs aside for safekeeping.
+ // (This is because when mocking, everything happens in the same thread.)
+
+ final UUID invocationID = logger.invoke(ONAPLogConstants.InvocationMode.SYNCHRONOUS);
+ final String requestID = MDC.get(ONAPLogConstants.MDCs.REQUEST_ID);
+ final Map<String, String> safekeeping = MDC.getCopyOfContextMap();
+
+ // Set headers.
+
+ mock.addHeader(ONAPLogConstants.Headers.REQUEST_ID, StringUtils.defaultString(requestID));
+ mock.addHeader(ONAPLogConstants.Headers.INVOCATION_ID, invocationID.toString());
+ mock.addHeader(ONAPLogConstants.Headers.PARTNER_NAME, this.getServiceName());
+
+ try {
+
+ MDC.clear();
+
+ // Execute.
+
+ return component.execute(request, mock);
+ }
+ finally {
+
+ // Restore MDCs.
+
+ safekeeping.forEach((k, v) -> MDC.put(k, v));
+ }
+ }
+
+ /**
+ * Ensure non-nullness.
+ * @param in to be checked.
+ * @param <T> type.
+ * @return input value, not null.
+ */
+ private static <T> T notNull(final T in) {
+ if (in == null) {
+ throw new AssertionError("");
+ }
+ return in;
+ }
+
+ /**
+ * Get service name, with default.
+ * @return service name, suitable for logging as MDC.
+ */
+ private String getServiceName() {
+ return "service." + StringUtils.defaultString(this.getId(), "unnamed");
+ }
+
+ /**
+ * Get logger instance.
+ * @return logger.
+ */
+ private Logger getLogger() {
+ return LoggerFactory.getLogger(this.getClass());
+ }
+}
diff --git a/reference/logging-slf4j-demo/src/main/java/org/onap/logging/ref/slf4j/demo/component/alpha/ComponentAlpha.java b/reference/logging-slf4j-demo/src/main/java/org/onap/logging/ref/slf4j/demo/component/alpha/ComponentAlpha.java
new file mode 100644
index 0000000..d5cf182
--- /dev/null
+++ b/reference/logging-slf4j-demo/src/main/java/org/onap/logging/ref/slf4j/demo/component/alpha/ComponentAlpha.java
@@ -0,0 +1,53 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.logging
+ * ================================================================================
+ * Copyright © 2018 Amdocs
+ * 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.logging.ref.slf4j.demo.component.alpha;
+
+import java.util.UUID;
+
+import org.onap.logging.ref.slf4j.demo.component.AbstractComponent;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+/**
+ * Discrete service, identical to the others but with its own identifiers.
+ */
+@RequestMapping("/services/alpha")
+public class ComponentAlpha extends AbstractComponent {
+
+ /** Component instance UUID constant. */
+ private static final String INSTANCE_UUID = UUID.randomUUID().toString();
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected String getId() {
+ return "alpha";
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected String getInstanceUUID() {
+ return INSTANCE_UUID;
+ }
+}
diff --git a/reference/logging-slf4j-demo/src/main/java/org/onap/logging/ref/slf4j/demo/component/alpha/package-info.java b/reference/logging-slf4j-demo/src/main/java/org/onap/logging/ref/slf4j/demo/component/alpha/package-info.java
new file mode 100644
index 0000000..4fa0fbc
--- /dev/null
+++ b/reference/logging-slf4j-demo/src/main/java/org/onap/logging/ref/slf4j/demo/component/alpha/package-info.java
@@ -0,0 +1,26 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.logging
+ * ================================================================================
+ * Copyright © 2018 Amdocs
+ * 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.logging.ref.slf4j.demo.component.alpha;
+
+/**
+ * Example service.
+ */ \ No newline at end of file
diff --git a/reference/logging-slf4j-demo/src/main/java/org/onap/logging/ref/slf4j/demo/component/beta/ComponentBeta.java b/reference/logging-slf4j-demo/src/main/java/org/onap/logging/ref/slf4j/demo/component/beta/ComponentBeta.java
new file mode 100644
index 0000000..9a4e6eb
--- /dev/null
+++ b/reference/logging-slf4j-demo/src/main/java/org/onap/logging/ref/slf4j/demo/component/beta/ComponentBeta.java
@@ -0,0 +1,53 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.logging
+ * ================================================================================
+ * Copyright © 2018 Amdocs
+ * 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.logging.ref.slf4j.demo.component.beta;
+
+import java.util.UUID;
+
+import org.onap.logging.ref.slf4j.demo.component.AbstractComponent;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+/**
+ * Discrete service, identical to the others but with its own identifiers.
+ */
+@RequestMapping("/services/beta")
+public class ComponentBeta extends AbstractComponent {
+
+ /** Component instance UUID constant. */
+ private static final String INSTANCE_UUID = UUID.randomUUID().toString();
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected String getId() {
+ return "beta";
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected String getInstanceUUID() {
+ return INSTANCE_UUID;
+ }
+}
diff --git a/reference/logging-slf4j-demo/src/main/java/org/onap/logging/ref/slf4j/demo/component/beta/package-info.java b/reference/logging-slf4j-demo/src/main/java/org/onap/logging/ref/slf4j/demo/component/beta/package-info.java
new file mode 100644
index 0000000..68d7f74
--- /dev/null
+++ b/reference/logging-slf4j-demo/src/main/java/org/onap/logging/ref/slf4j/demo/component/beta/package-info.java
@@ -0,0 +1,26 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.logging
+ * ================================================================================
+ * Copyright © 2018 Amdocs
+ * 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.logging.ref.slf4j.demo.component.beta;
+
+/**
+ * Example service.
+ */ \ No newline at end of file
diff --git a/reference/logging-slf4j-demo/src/main/java/org/onap/logging/ref/slf4j/demo/component/delta/ComponentDelta.java b/reference/logging-slf4j-demo/src/main/java/org/onap/logging/ref/slf4j/demo/component/delta/ComponentDelta.java
new file mode 100644
index 0000000..d63d80a
--- /dev/null
+++ b/reference/logging-slf4j-demo/src/main/java/org/onap/logging/ref/slf4j/demo/component/delta/ComponentDelta.java
@@ -0,0 +1,53 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.logging
+ * ================================================================================
+ * Copyright © 2018 Amdocs
+ * 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.logging.ref.slf4j.demo.component.delta;
+
+import java.util.UUID;
+
+import org.onap.logging.ref.slf4j.demo.component.AbstractComponent;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+/**
+ * Discrete service, identical to the others but with its own identifiers.
+ */
+@RequestMapping("/services/delta")
+public class ComponentDelta extends AbstractComponent {
+
+ /** Component instance UUID constant. */
+ private static final String INSTANCE_UUID = UUID.randomUUID().toString();
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected String getId() {
+ return "delta";
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected String getInstanceUUID() {
+ return INSTANCE_UUID;
+ }
+}
diff --git a/reference/logging-slf4j-demo/src/main/java/org/onap/logging/ref/slf4j/demo/component/delta/package-info.java b/reference/logging-slf4j-demo/src/main/java/org/onap/logging/ref/slf4j/demo/component/delta/package-info.java
new file mode 100644
index 0000000..4b02ab4
--- /dev/null
+++ b/reference/logging-slf4j-demo/src/main/java/org/onap/logging/ref/slf4j/demo/component/delta/package-info.java
@@ -0,0 +1,26 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.logging
+ * ================================================================================
+ * Copyright © 2018 Amdocs
+ * 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.logging.ref.slf4j.demo.component.delta;
+
+/**
+ * Example service.
+ */ \ No newline at end of file
diff --git a/reference/logging-slf4j-demo/src/main/java/org/onap/logging/ref/slf4j/demo/component/gamma/ComponentGamma.java b/reference/logging-slf4j-demo/src/main/java/org/onap/logging/ref/slf4j/demo/component/gamma/ComponentGamma.java
new file mode 100644
index 0000000..9294743
--- /dev/null
+++ b/reference/logging-slf4j-demo/src/main/java/org/onap/logging/ref/slf4j/demo/component/gamma/ComponentGamma.java
@@ -0,0 +1,53 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.logging
+ * ================================================================================
+ * Copyright © 2018 Amdocs
+ * 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.logging.ref.slf4j.demo.component.gamma;
+
+import java.util.UUID;
+
+import org.onap.logging.ref.slf4j.demo.component.AbstractComponent;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+/**
+ * Discrete service, identical to the others but with its own identifiers.
+ */
+@RequestMapping("/services/gamma")
+public class ComponentGamma extends AbstractComponent {
+
+ /** Component instance UUID constant. */
+ private static final String INSTANCE_UUID = UUID.randomUUID().toString();
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected String getId() {
+ return "gamma";
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected String getInstanceUUID() {
+ return INSTANCE_UUID;
+ }
+}
diff --git a/reference/logging-slf4j-demo/src/main/java/org/onap/logging/ref/slf4j/demo/component/gamma/package-info.java b/reference/logging-slf4j-demo/src/main/java/org/onap/logging/ref/slf4j/demo/component/gamma/package-info.java
new file mode 100644
index 0000000..7f5e30a
--- /dev/null
+++ b/reference/logging-slf4j-demo/src/main/java/org/onap/logging/ref/slf4j/demo/component/gamma/package-info.java
@@ -0,0 +1,26 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.logging
+ * ================================================================================
+ * Copyright © 2018 Amdocs
+ * 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.logging.ref.slf4j.demo.component.gamma;
+
+/**
+ * Example service.
+ */ \ No newline at end of file
diff --git a/reference/logging-slf4j-demo/src/main/java/org/onap/logging/ref/slf4j/demo/component/package-info.java b/reference/logging-slf4j-demo/src/main/java/org/onap/logging/ref/slf4j/demo/component/package-info.java
new file mode 100644
index 0000000..c650948
--- /dev/null
+++ b/reference/logging-slf4j-demo/src/main/java/org/onap/logging/ref/slf4j/demo/component/package-info.java
@@ -0,0 +1,26 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.logging
+ * ================================================================================
+ * Copyright © 2018 Amdocs
+ * 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.logging.ref.slf4j.demo.component;
+
+/**
+ * Components that demonstrate usage and participate in the test.
+ */ \ No newline at end of file
diff --git a/reference/logging-slf4j-demo/src/main/java/org/onap/logging/ref/slf4j/demo/package-info.java b/reference/logging-slf4j-demo/src/main/java/org/onap/logging/ref/slf4j/demo/package-info.java
new file mode 100644
index 0000000..feb5e85
--- /dev/null
+++ b/reference/logging-slf4j-demo/src/main/java/org/onap/logging/ref/slf4j/demo/package-info.java
@@ -0,0 +1,30 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.logging
+ * ================================================================================
+ * Copyright © 2018 Amdocs
+ * 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.logging.ref.slf4j.demo;
+
+/**
+ * Minimal, spring-boot refernce example.
+ *
+ * <p>Code that exists for testing can have whatever dependencies
+ * it likes, but take care with the contents of <tt>common</tt>,
+ * since it may be useful elsewhere.</p>
+ */ \ No newline at end of file
diff --git a/reference/logging-slf4j-demo/src/main/resources/logback.xml b/reference/logging-slf4j-demo/src/main/resources/logback.xml
new file mode 100644
index 0000000..554d712
--- /dev/null
+++ b/reference/logging-slf4j-demo/src/main/resources/logback.xml
@@ -0,0 +1,35 @@
+<configuration>
+
+ <property name="p_tim" value="%d{&quot;yyyy-MM-dd'T'HH:mm:ss.SSSXXX&quot;, UTC}"/>
+ <property name="p_lvl" value="%level"/>
+ <property name="p_log" value="%logger"/>
+ <property name="p_mdc" value="%replace(%replace(%mdc){'\t','\\\\t'}){'\n', '\\\\n'}"/>
+ <property name="p_msg" value="%replace(%replace(%msg){'\t', '\\\\t'}){'\n','\\\\n'}"/>
+ <property name="p_exc" value="%replace(%replace(%rootException){'\t', '\\\\t'}){'\n','\\\\n'}"/>
+ <property name="p_mak" value="%replace(%replace(%marker){'\t', '\\\\t'}){'\n','\\\\n'}"/>
+ <property name="p_thr" value="%thread"/>
+ <property name="pattern" value="%nopexception${p_tim}\t${p_thr}\t${p_lvl}\t${p_log}\t${p_mdc}\t${p_msg}\t${p_exc}\t${p_mak}\t%n"/>
+
+ <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+ <encoder>
+ <pattern>${pattern}</pattern>
+ </encoder>
+ </appender>
+
+ <appender name="FILE" class="ch.qos.logback.core.FileAppender">
+ <file>${SLF4J_OUTPUT_DIRECTORY}/output.log</file>
+ <encoder>
+ <pattern>${pattern}</pattern>
+ </encoder>
+ </appender>
+
+ <logger level="debug" name="org.onap.logging.ref.slf4j" additivity="false">
+ <appender-ref ref="STDOUT" />
+ <appender-ref ref="FILE" />
+ </logger>
+
+ <root level="error">
+ <appender-ref ref="STDOUT" />
+ </root>
+
+</configuration>
diff --git a/reference/logging-slf4j-demo/src/main/webapp/WEB-INF/web.xml b/reference/logging-slf4j-demo/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 0000000..91a632c
--- /dev/null
+++ b/reference/logging-slf4j-demo/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="slf4j-reference" version="3.0"/>
diff --git a/reference/logging-slf4j-demo/src/test/java/org/onap/logging/ref/slf4j/CallGraphTest.java b/reference/logging-slf4j-demo/src/test/java/org/onap/logging/ref/slf4j/CallGraphTest.java
new file mode 100644
index 0000000..3d123e0
--- /dev/null
+++ b/reference/logging-slf4j-demo/src/test/java/org/onap/logging/ref/slf4j/CallGraphTest.java
@@ -0,0 +1,207 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.logging
+ * ================================================================================
+ * Copyright © 2018 Amdocs
+ * 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.logging.ref.slf4j;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.nio.file.Files;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.onap.logging.ref.slf4j.analysis.CallGraphAnalyzer;
+import org.onap.logging.ref.slf4j.analysis.CallGraphReportWriter;
+import org.onap.logging.ref.slf4j.analysis.LogEntry;
+import org.onap.logging.ref.slf4j.demo.bean.Request;
+import org.onap.logging.ref.slf4j.demo.bean.Response;
+import org.onap.logging.ref.slf4j.demo.component.AbstractComponentTest;
+import org.onap.logging.ref.slf4j.demo.component.alpha.ComponentAlpha;
+import org.slf4j.LoggerFactory;
+import org.springframework.mock.web.MockHttpServletRequest;
+import org.testng.Assert;
+import org.testng.annotations.AfterSuite;
+import org.testng.annotations.BeforeSuite;
+import org.testng.annotations.Test;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.Is.is;
+
+/**
+ * Simple verification that we can easily get a call graph out of
+ * some calls to logging via <tt>ONAPLogAdapter</tt>.
+ */
+public class CallGraphTest {
+
+ /** Temporary directory into which logfiles are written. */
+ private static File sDir;
+
+ @BeforeSuite
+ public static void setUp() throws Exception {
+ AbstractComponentTest.setInProcess();
+ sDir = Files.createTempDirectory(CallGraphTest.class.getName()).toFile();
+ System.getProperties().setProperty("SLF4J_OUTPUT_DIRECTORY", sDir.getAbsolutePath());
+ LoggerFactory.getLogger(CallGraphTest.class).info("Starting.");
+ }
+
+ @AfterSuite
+ public static void tearDown() throws Exception {
+ LoggerFactory.getLogger(CallGraphTest.class).info("Ending.");
+ Thread.sleep(1000L);
+ if (sDir != null) {
+ System.err.println("Should be deleting [" + sDir.getAbsolutePath() + "]...");
+ }
+ }
+
+ @Test(enabled = false)
+ public void testSimple() throws Exception {
+
+ final HttpServletRequest mock = new MockHttpServletRequest();
+ final ComponentAlpha a = new ComponentAlpha();
+ final Request request = new Request();
+ final Response response = a.execute(request, mock);
+ assertThat(response.getResponses().size(), is(0));
+ }
+
+ /**
+ * A more complex (interesting) example of generating a call graph.
+ * @throws Exception test failure.
+ */
+ @Test
+ public void testComplex() throws Exception {
+
+ Assert.assertNotNull(sDir);
+
+ // Fan out some requests between test components.
+
+ final Request a = new Request();
+ a.setService("alpha");
+
+ final Request b = new Request();
+ b.setService("beta");
+
+ final Request ac = new Request();
+ ac.setService("gamma");
+
+ final Request ad = new Request();
+ ad.setService("delta");
+
+ final Request bc1 = new Request();
+ bc1.setService("gamma");
+
+ final Request bc2 = new Request();
+ bc2.setService("gamma");
+
+ a.getRequests().add(b);
+ a.getRequests().add(ac);
+ a.getRequests().add(ad);
+ b.getRequests().add(bc1);
+ b.getRequests().add(bc2);
+
+ // Deeper.
+
+ final Request xb = new Request();
+ xb.setService("beta");
+
+ final Request xg = new Request();
+ xg.setService("gamma");
+
+ final Request xd = new Request();
+ xd.setService("delta");
+
+ a.getRequests().add(xb);
+ xb.getRequests().add(xg);
+ xg.getRequests().add(xd);
+
+ // Execute.
+
+ final HttpServletRequest mock = new MockHttpServletRequest();
+ final ComponentAlpha component = new ComponentAlpha();
+ final Response response = component.execute(a, mock);
+ System.err.println(response);
+
+ assertThat(response.getResponses().size(), is(4));
+
+ Thread.sleep(1000L);
+
+ // Find logfile.
+
+ File log = null;
+ for (final File candidate : sDir.listFiles()) {
+ if (candidate.getName().endsWith(".log")) {
+ log = candidate;
+ break;
+ }
+ }
+
+ Assert.assertNotNull(log);
+
+ System.err.println("READING LOGFILE: " + log.getAbsolutePath());
+
+ final CallGraphAnalyzer analyzer = new CallGraphAnalyzer();
+ try (final BufferedReader reader = new BufferedReader(new FileReader(log))) {
+ while (true) {
+
+ final String line = reader.readLine();
+ if (line == null) {
+ break;
+ }
+
+ final LogEntry entry = new LogEntry(line);
+ analyzer.add(entry);
+ }
+ }
+
+ //
+ // Debug during dev, but annoying the rest of the time.
+ //
+ // System.err.println("--------------------------------------------------");
+ // for (final LogEntry e : analyzer.getEntries()) {
+ // System.err.println(e.toShortString());
+ // }
+ // System.err.println("--------------------------------------------------");
+
+ final CallGraphReportWriter writer = new CallGraphReportWriter(analyzer);
+ final String shortReport = writer.getShortReport();
+ final String longReport = writer.getLongReport();
+
+ // Dump long report.
+
+ System.out.println("----\nGraph:\n\n" + longReport + "\n----");
+
+ // Validate short report.
+
+ assertThat("Alpha\n" +
+ " Beta\n" +
+ " Gamma\n" +
+ " Gamma\n" +
+ " Gamma\n" +
+ " Delta\n" +
+ " Beta\n" +
+ " Gamma\n" +
+ " Delta\n",
+ is(shortReport));
+
+ // Ensure output reaches System.xxx.
+
+ Thread.sleep(1000L);
+ }
+} \ No newline at end of file
diff --git a/reference/logging-slf4j-demo/src/test/java/org/onap/logging/ref/slf4j/analysis/CallGraphAnalyzer.java b/reference/logging-slf4j-demo/src/test/java/org/onap/logging/ref/slf4j/analysis/CallGraphAnalyzer.java
new file mode 100644
index 0000000..208b3e1
--- /dev/null
+++ b/reference/logging-slf4j-demo/src/test/java/org/onap/logging/ref/slf4j/analysis/CallGraphAnalyzer.java
@@ -0,0 +1,114 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.logging
+ * ================================================================================
+ * Copyright © 2018 Amdocs
+ * 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.logging.ref.slf4j.analysis;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.lang3.StringUtils;
+
+/**
+ * Crude analyzer for log messages, to build a simple
+ * representation of the call graph.
+ */
+public class CallGraphAnalyzer {
+
+ /** Messages of interest. */
+ private List<LogEntry> mEntries = new ArrayList<>();
+
+ /**
+ * Capture entry if it's interesting.
+ * @param entry candidate.
+ * @return this.
+ */
+ public CallGraphAnalyzer add(final LogEntry entry) {
+
+ if (entry.getLogger().contains("ONAPLogAdapterTest")) {
+ return this;
+ }
+
+ if (StringUtils.isNotBlank(entry.getMarkers())) {
+ this.mEntries.add(entry);
+ }
+
+ return this;
+ }
+
+ /**
+ * Get all captured entries, for diagnostics only.
+ * @return entries.
+ */
+ public List<LogEntry> getEntries() {
+ return this.mEntries;
+ }
+
+ /**
+ * Find the entry point into the call graph through the various components.
+ * @return entry point or (failure) null.
+ */
+ public LogEntry findEntryPoint() {
+ for (final LogEntry e : this.mEntries) {
+ if (e.getLogger().endsWith("ComponentAlpha")) {
+ if ("ENTRY".equals(e.getMarkers())) {
+ if (StringUtils.isBlank(e.getPartnerName())) {
+ return e;
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Find entries for where a component invokes others.
+ * @param parent parent ENTRY (not actually the entry where it's doing the invoking).
+ * @return components invoked by this one.
+ */
+ public List<LogEntry> findInvokes(final LogEntry parent) {
+ final List<LogEntry> invokes = new ArrayList<>();
+ for (final LogEntry e : this.mEntries) {
+ if (StringUtils.equals(parent.getInvocationID(), e.getInvocationID())) {
+ final String invokingID = e.getInvokingID();
+ if (StringUtils.isNotBlank(invokingID)) {
+ invokes.add(e);
+ }
+ }
+ }
+ return invokes;
+ }
+
+ /**
+ * Find a specific invocation.
+ * @param invoke invocation record.
+ * @return invocation ENTRY, or (failure) null if not found.
+ */
+ public LogEntry findInvocation(final LogEntry invoke) {
+ for (final LogEntry e : this.mEntries) {
+ if ("ENTRY".equals(e.getMarkers())) {
+ if (StringUtils.equals(invoke.getInvokingID(), e.getInvocationID())) {
+ return e;
+ }
+ }
+ }
+ return null;
+ }
+}
diff --git a/reference/logging-slf4j-demo/src/test/java/org/onap/logging/ref/slf4j/analysis/CallGraphReportWriter.java b/reference/logging-slf4j-demo/src/test/java/org/onap/logging/ref/slf4j/analysis/CallGraphReportWriter.java
new file mode 100644
index 0000000..ee67b35
--- /dev/null
+++ b/reference/logging-slf4j-demo/src/test/java/org/onap/logging/ref/slf4j/analysis/CallGraphReportWriter.java
@@ -0,0 +1,111 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.logging
+ * ================================================================================
+ * Copyright © 2018 Amdocs
+ * 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.logging.ref.slf4j.analysis;
+
+import java.util.List;
+
+import org.apache.commons.lang3.StringUtils;
+import org.testng.Assert;
+
+/**
+ * A simple, recursive text-only report writer for the call graph.
+ */
+public class CallGraphReportWriter {
+
+ /** The analyzer which does the work. */
+ final CallGraphAnalyzer mAnalyzer;
+
+ /** Short report, for validation. */
+ final StringBuilder mShortReport = new StringBuilder();
+
+ /** Longer report, for human eyes. */
+ final StringBuilder mLongReport = new StringBuilder();
+
+ /**
+ * Construct writer.
+ * @param analyzer initialized analyzer.
+ */
+ public CallGraphReportWriter(final CallGraphAnalyzer analyzer) {
+
+ this.mAnalyzer = analyzer;
+
+ Assert.assertTrue(analyzer.getEntries().size() > 0);
+ final LogEntry e0 = analyzer.findEntryPoint();
+ Assert.assertNotNull(e0);
+
+ this.mLongReport.append(e0.toShortString()).append("\n");
+ this.mShortReport.append(StringUtils.substringAfter(e0.getLogger(), ".Component")).append("\n");
+
+ this.report(e0, 1);
+
+ }
+
+ /**
+ * Recursively analyze.
+ * @param invoker entry point.
+ * @param depth recursive depth, for handbrake.
+ */
+ private void report(final LogEntry invoker, final int depth) {
+
+ if (depth > 100) {
+ throw new AssertionError("Recursion ad infinitum");
+ }
+
+ final List<LogEntry> invokes0 = this.mAnalyzer.findInvokes(invoker);
+ for (final LogEntry invoke0 : invokes0) {
+
+ final LogEntry invoked0 = this.mAnalyzer.findInvocation(invoke0);
+
+ Assert.assertNotNull(invoked0);
+
+ final String indent = StringUtils.repeat(' ', depth * 4);
+ this.mLongReport.append(indent).append(invoked0.toShortString()).append('\n');
+ this.mShortReport.append(indent).append(StringUtils.substringAfter(invoked0.getLogger(), ".Component")).append('\n');
+
+ report(invoked0, depth + 1);
+ }
+ }
+
+ /**
+ * Get report.
+ * @return short report, for validation.
+ */
+ public String getShortReport() {
+ return this.mShortReport.toString();
+ }
+
+ /**
+ * Get report.
+ * @return long report, for printing out.
+ */
+ public String getLongReport() {
+ return this.mLongReport.toString();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String toString() {
+ return this.getLongReport();
+ }
+}
diff --git a/reference/logging-slf4j-demo/src/test/java/org/onap/logging/ref/slf4j/analysis/LogEntry.java b/reference/logging-slf4j-demo/src/test/java/org/onap/logging/ref/slf4j/analysis/LogEntry.java
new file mode 100644
index 0000000..b9bd48f
--- /dev/null
+++ b/reference/logging-slf4j-demo/src/test/java/org/onap/logging/ref/slf4j/analysis/LogEntry.java
@@ -0,0 +1,238 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.logging
+ * ================================================================================
+ * Copyright © 2018 Amdocs
+ * 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.logging.ref.slf4j.analysis;
+
+import java.util.Calendar;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.xml.bind.DatatypeConverter;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.slf4j.event.Level;
+
+/**
+ * Test class for reading a logentry during analysis.
+ */
+public class LogEntry {
+
+ /** Property. */
+ private final Date mTimestamp;
+
+ /** Property. */
+ private final String mThread;
+
+ /** Property. */
+ private final Level mLevel;
+
+ /** Property. */
+ private final String mLogger;
+
+ /** Property. */
+ private final String mMessage;
+
+ /** Property. */
+ private final String mException;
+
+ /** Property. */
+ private final Map<String, String> mMDCs;
+
+ /** Property. */
+ private final String mMarkers;
+
+ /**
+ * Construct from log line.
+ * @param line to be parsed.
+ */
+ public LogEntry(final String line) {
+
+ final String [] tokens = line.split("\t", -1);
+ if (tokens.length < 8) {
+ throw new IllegalArgumentException("Unsupported line (expected 8+ tokens, got "
+ + tokens.length + "): " + line);
+ }
+
+ int index = 0;
+
+ this.mTimestamp = DatatypeConverter.parseDateTime(tokens[index++]).getTime();
+ this.mThread = tokens[index++];
+ this.mLevel = Level.valueOf(tokens[index++].trim());
+ this.mLogger = tokens[index++];
+
+ this.mMDCs = parseMDCs(tokens[index++]);
+ this.mMessage = tokens[index++];
+ this.mException = tokens[index++];
+ this.mMarkers = tokens[index++];
+ }
+
+ /**
+ * Parse serialized MDCs.
+ * @param mdc serialized DMC map.
+ * @return parsed.
+ */
+ static Map<String, String> parseMDCs(final String mdc) {
+
+ final Map<String, String> mdcs = new HashMap<>();
+ for (final String token : mdc.split(",")) {
+ final String[] mdcTokens = token.split("=");
+ if (mdcTokens.length == 2) {
+ mdcs.put(StringUtils.trim(mdcTokens[0]), StringUtils.trim(mdcTokens[1]));
+ }
+ }
+ return Collections.unmodifiableMap(mdcs);
+ }
+
+ /**
+ * Getter.
+ * @return property.
+ */
+ public Date getTimestamp() {
+ return this.mTimestamp;
+ }
+
+ /**
+ * Getter.
+ * @return property.
+ */
+ public String getThread() {
+ return this.mThread;
+ }
+
+ /**
+ * Getter.
+ * @return property.
+ */
+ public Level getLevel() {
+ return this.mLevel;
+ }
+
+ /**
+ * Getter.
+ * @return property.
+ */
+ public String getLogger() {
+ return this.mLogger;
+ }
+
+ /**
+ * Getter.
+ * @return property.
+ */
+ public String getMessage() {
+ return this.mMessage;
+ }
+
+ /**
+ * Getter.
+ * @return property.
+ */
+ public String getException() {
+ return this.mException;
+ }
+
+ /**
+ * Getter.
+ * @return property.
+ */
+ public Map<String, String> getMDCs() {
+ return this.mMDCs;
+ }
+
+ /**
+ * Getter.
+ * @return property.
+ */
+ public String getMarkers() {
+ return this.mMarkers;
+ }
+
+ /**
+ * Getter.
+ * @return property.
+ */
+ public String getRequestID() {
+ return this.getMDCs().get("RequestID");
+ }
+
+ /**
+ * Getter.
+ * @return property.
+ */
+ public String getInvocationID() {
+ return this.getMDCs().get("InvocationID");
+ }
+
+ /**
+ * Getter.
+ * @return property.
+ */
+ public String getPartnerName() {
+ return this.getMDCs().get("PartnerName");
+ }
+
+ /**
+ * Getter.
+ * @return property.
+ */
+ public String getInvokingID() {
+ if (StringUtils.defaultString(this.getMarkers()).startsWith("INVOKE")) {
+ return this.getMessage();
+ }
+ return null;
+ }
+
+ /**
+ * Getter.
+ * @return property.
+ */
+ public String toShortString() {
+ final StringBuilder buf = new StringBuilder();
+ buf.append("LogEntry(markers=").append(StringUtils.defaultString(this.getMarkers()));
+ buf.append(", logger=").append(this.getLogger().substring(1 + this.getLogger().lastIndexOf(".")));
+ if (StringUtils.isNotBlank(this.getRequestID())) {
+ buf.append(", requestID=[...]").append(StringUtils.right(this.getRequestID(), 8));
+ }
+ if (StringUtils.isNotBlank(this.getInvocationID())) {
+ buf.append(", invocationID=[...]").append(StringUtils.right(this.getInvocationID(), 8));
+ }
+ if (StringUtils.isNotBlank(this.getInvokingID())) {
+ buf.append(", invokingID=[...]").append(StringUtils.right(this.getInvokingID(), 8));
+ }
+
+ final Calendar c = Calendar.getInstance();
+ c.setTime(this.getTimestamp());
+
+ buf.append(", timestamp=").append(DatatypeConverter.printDateTime(c));
+ return buf.append(")").toString();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String toString() {
+ return ToStringBuilder.reflectionToString(this);
+ }
+}
diff --git a/reference/logging-slf4j-demo/src/test/java/org/onap/logging/ref/slf4j/analysis/LogEntryTest.java b/reference/logging-slf4j-demo/src/test/java/org/onap/logging/ref/slf4j/analysis/LogEntryTest.java
new file mode 100644
index 0000000..63ead27
--- /dev/null
+++ b/reference/logging-slf4j-demo/src/test/java/org/onap/logging/ref/slf4j/analysis/LogEntryTest.java
@@ -0,0 +1,71 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.logging
+ * ================================================================================
+ * Copyright © 2018 Amdocs
+ * 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.logging.ref.slf4j.analysis;
+
+import java.util.Map;
+
+import org.slf4j.event.Level;
+import org.testng.annotations.Test;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.Is.is;
+import static org.hamcrest.core.IsNull.notNullValue;
+
+public class LogEntryTest {
+
+ @Test
+ public void testLogEntry() {
+
+ final String eg = "2018-05-07T16:45:53.056Z\tpool-1-thread-1\tINFO"
+ + "\torg.onap.logging.ref.slf4j.component.gamma.ComponentGamma\tInstanceUUID=fa8dd337-6991-4535-a069-ca552466d972,"
+ + " RequestID=46161759-1b92-40a4-a408-800e0d62dd9e, ServiceName=service.alpha, EntryTimestamp=2018-05-08T02:45:53.056,"
+ + " InvocationID=aac8fec9-498c-42a2-936b-38f5c0f5ca82, PartnerName=service.beta, ClientIPAddress=127.0.0.1,"
+ + " ServerFQDN=localhost\t\t\tENTRY\t\n";
+
+ final LogEntry parsed = new LogEntry(eg);
+ assertThat(parsed.getTimestamp(), notNullValue());
+ assertThat(parsed.getThread(), is("pool-1-thread-1"));
+ assertThat(parsed.getLevel(), is(Level.INFO));
+ assertThat(parsed.getLogger(), is("org.onap.logging.ref.slf4j.component.gamma.ComponentGamma"));
+ assertThat(parsed.getMDCs().get("ServiceName"), is("service.alpha"));
+ assertThat(parsed.getMDCs().get("PartnerName"), is("service.beta"));
+ assertThat(parsed.getMessage(), is(""));
+ assertThat(parsed.getMarkers(), is("ENTRY"));
+ assertThat(parsed.getException(), is(""));
+
+ }
+
+ @Test
+ public void testParseMDCsEmpty() {
+ final Map<String, String> map = LogEntry.parseMDCs("");
+ assertThat(map.size(), is(0));
+ }
+
+ @Test
+ public void testParseMDCs() {
+ final Map<String, String> map = LogEntry.parseMDCs("A=B, C=D , D = F ");
+ assertThat(map.get("A"), is("B"));
+ assertThat(map.get("C"), is("D"));
+ assertThat(map.get("D"), is("F"));
+ assertThat(map.size(), is(3));
+ }
+}
diff --git a/reference/logging-slf4j-demo/src/test/java/org/onap/logging/ref/slf4j/demo/SLF4JRefApplicationTest.java b/reference/logging-slf4j-demo/src/test/java/org/onap/logging/ref/slf4j/demo/SLF4JRefApplicationTest.java
new file mode 100644
index 0000000..a01cbe8
--- /dev/null
+++ b/reference/logging-slf4j-demo/src/test/java/org/onap/logging/ref/slf4j/demo/SLF4JRefApplicationTest.java
@@ -0,0 +1,47 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.logging
+ * ================================================================================
+ * Copyright © 2018 Amdocs
+ * 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.logging.ref.slf4j.demo;
+
+import org.testng.annotations.Test;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.Is.is;
+import static org.hamcrest.core.IsNull.notNullValue;
+
+/**
+ * Tests for {@link SLF4JRefApplication}.
+ */
+public class SLF4JRefApplicationTest {
+
+ @Test
+ public void testProperty() {
+ assertThat(SLF4JRefApplication.SLF4J_OUTPUT_DIRECTORY,
+ is("SLF4J_OUTPUT_DIRECTORY"));
+ }
+
+ @Test
+ public void testInitOutputDirectory() throws Exception {
+ SLF4JRefApplication.initOutputDirectory();
+ assertThat(System.getProperty(SLF4JRefApplication.SLF4J_OUTPUT_DIRECTORY),
+ notNullValue());
+ }
+}
diff --git a/reference/logging-slf4j-demo/src/test/java/org/onap/logging/ref/slf4j/demo/bean/RequestTest.java b/reference/logging-slf4j-demo/src/test/java/org/onap/logging/ref/slf4j/demo/bean/RequestTest.java
new file mode 100644
index 0000000..6c622a7
--- /dev/null
+++ b/reference/logging-slf4j-demo/src/test/java/org/onap/logging/ref/slf4j/demo/bean/RequestTest.java
@@ -0,0 +1,64 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.logging
+ * ================================================================================
+ * Copyright © 2018 Amdocs
+ * 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.logging.ref.slf4j.demo.bean;
+
+import org.json.JSONObject;
+import org.testng.annotations.Test;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.Is.is;
+
+public class RequestTest {
+
+ @Test
+ public void testRoundtrip() {
+
+ final Request in = new Request();
+ in.setCode("code0");
+ in.setService("service0");
+ in.setSeverity("severity0");
+
+ final Request childA = new Request();
+ childA.setCode("codeA");
+ childA.setService("serviceA");
+ childA.setSeverity("severityA");
+
+ final Request childB = new Request();
+ childB.setCode("codeB");
+ childB.setService("serviceB");
+ childB.setSeverity("severityB");
+
+ in.getRequests().add(childA);
+ in.getRequests().add(childB);
+
+ System.out.println(in.toString());
+ System.out.println(new JSONObject(in.toString()).toString());
+
+ final Request out = Request.fromJSON(new JSONObject(in.toString()));
+ assertThat(out.getCode(), is(in.getCode()));
+ assertThat(out.getService(), is(in.getService()));
+ assertThat(out.getSeverity(), is(in.getSeverity()));
+ assertThat(out.getRequests().size(), is(2));
+ assertThat(out.getRequests().get(0).getCode(), is("codeA"));
+ assertThat(out.getRequests().get(1).getCode(), is("codeB"));
+ }
+}
diff --git a/reference/logging-slf4j-demo/src/test/java/org/onap/logging/ref/slf4j/demo/bean/ResponseTest.java b/reference/logging-slf4j-demo/src/test/java/org/onap/logging/ref/slf4j/demo/bean/ResponseTest.java
new file mode 100644
index 0000000..63cc68e
--- /dev/null
+++ b/reference/logging-slf4j-demo/src/test/java/org/onap/logging/ref/slf4j/demo/bean/ResponseTest.java
@@ -0,0 +1,61 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.logging
+ * ================================================================================
+ * Copyright © 2018 Amdocs
+ * 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.logging.ref.slf4j.demo.bean;
+
+import org.json.JSONObject;
+import org.testng.annotations.Test;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.Is.is;
+
+public class ResponseTest {
+
+ @Test
+ public void testRoundtrip() {
+
+ final Response in = new Response();
+ in.setCode("code0");
+ in.setSeverity("severity0");
+
+ final Response childA = new Response();
+ childA.setCode("codeA");
+ childA.setSeverity("severityA");
+
+ final Response childB = new Response();
+ childB.setCode("codeB");
+ childB.setSeverity("severityB");
+
+ in.getResponses().add(childA);
+ in.getResponses().add(childB);
+
+ System.out.println(in.toString());
+ System.out.println(new JSONObject(in.toString()).toString());
+
+ final Response out = Response.fromJSON(new JSONObject(in.toString()));
+ assertThat(out.getCode(), is(in.getCode()));
+ assertThat(out.getSeverity(), is(in.getSeverity()));
+ assertThat(out.getResponses().size(), is(2));
+ assertThat(out.getResponses().get(0).getCode(), is("codeA"));
+ assertThat(out.getResponses().get(1).getCode(), is("codeB"));
+
+ }
+}
diff --git a/reference/logging-slf4j-demo/src/test/java/org/onap/logging/ref/slf4j/demo/component/AbstractComponentTest.java b/reference/logging-slf4j-demo/src/test/java/org/onap/logging/ref/slf4j/demo/component/AbstractComponentTest.java
new file mode 100644
index 0000000..5275853
--- /dev/null
+++ b/reference/logging-slf4j-demo/src/test/java/org/onap/logging/ref/slf4j/demo/component/AbstractComponentTest.java
@@ -0,0 +1,29 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.logging
+ * ================================================================================
+ * Copyright © 2018 Amdocs
+ * 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.logging.ref.slf4j.demo.component;
+
+public class AbstractComponentTest {
+
+ public static void setInProcess() {
+ AbstractComponent.setInProcess();
+ }
+}
diff --git a/reference/logging-slf4j-demo/src/test/java/org/onap/logging/ref/slf4j/demo/component/alpha/ComponentAlphaTest.java b/reference/logging-slf4j-demo/src/test/java/org/onap/logging/ref/slf4j/demo/component/alpha/ComponentAlphaTest.java
new file mode 100644
index 0000000..50cd80a
--- /dev/null
+++ b/reference/logging-slf4j-demo/src/test/java/org/onap/logging/ref/slf4j/demo/component/alpha/ComponentAlphaTest.java
@@ -0,0 +1,45 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.logging
+ * ================================================================================
+ * Copyright © 2018 Amdocs
+ * 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.logging.ref.slf4j.demo.component.alpha;
+
+import java.util.UUID;
+
+import org.testng.annotations.Test;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.Is.is;
+
+/**
+ * Tests for {@link ComponentAlpha}.
+ */
+public class ComponentAlphaTest {
+
+ @Test
+ public void testGetId() {
+ assertThat(new ComponentAlpha().getId(), is("alpha"));
+ }
+
+ @Test
+ public void testGetInstanceUUID() {
+ UUID.fromString(new ComponentAlpha().getInstanceUUID());
+ }
+}
diff --git a/reference/logging-slf4j-demo/src/test/java/org/onap/logging/ref/slf4j/demo/component/beta/ComponentBetaTest.java b/reference/logging-slf4j-demo/src/test/java/org/onap/logging/ref/slf4j/demo/component/beta/ComponentBetaTest.java
new file mode 100644
index 0000000..20f4d72
--- /dev/null
+++ b/reference/logging-slf4j-demo/src/test/java/org/onap/logging/ref/slf4j/demo/component/beta/ComponentBetaTest.java
@@ -0,0 +1,45 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.logging
+ * ================================================================================
+ * Copyright © 2018 Amdocs
+ * 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.logging.ref.slf4j.demo.component.beta;
+
+import java.util.UUID;
+
+import org.testng.annotations.Test;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.Is.is;
+
+/**
+ * Tests for {@link ComponentBeta}.
+ */
+public class ComponentBetaTest {
+
+ @Test
+ public void testGetId() {
+ assertThat(new ComponentBeta().getId(), is("beta"));
+ }
+
+ @Test
+ public void testGetInstanceUUID() {
+ UUID.fromString(new ComponentBeta().getInstanceUUID());
+ }
+}
diff --git a/reference/logging-slf4j-demo/src/test/java/org/onap/logging/ref/slf4j/demo/component/delta/ComponentDeltaTest.java b/reference/logging-slf4j-demo/src/test/java/org/onap/logging/ref/slf4j/demo/component/delta/ComponentDeltaTest.java
new file mode 100644
index 0000000..53829a8
--- /dev/null
+++ b/reference/logging-slf4j-demo/src/test/java/org/onap/logging/ref/slf4j/demo/component/delta/ComponentDeltaTest.java
@@ -0,0 +1,45 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.logging
+ * ================================================================================
+ * Copyright © 2018 Amdocs
+ * 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.logging.ref.slf4j.demo.component.delta;
+
+import java.util.UUID;
+
+import org.testng.annotations.Test;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.Is.is;
+
+/**
+ * Tests for {@link ComponentDelta}.
+ */
+public class ComponentDeltaTest {
+
+ @Test
+ public void testGetId() {
+ assertThat(new ComponentDelta().getId(), is("delta"));
+ }
+
+ @Test
+ public void testGetInstanceUUID() {
+ UUID.fromString(new ComponentDelta().getInstanceUUID());
+ }
+}
diff --git a/reference/logging-slf4j-demo/src/test/java/org/onap/logging/ref/slf4j/demo/component/gamma/ComponentGammaTest.java b/reference/logging-slf4j-demo/src/test/java/org/onap/logging/ref/slf4j/demo/component/gamma/ComponentGammaTest.java
new file mode 100644
index 0000000..24222a6
--- /dev/null
+++ b/reference/logging-slf4j-demo/src/test/java/org/onap/logging/ref/slf4j/demo/component/gamma/ComponentGammaTest.java
@@ -0,0 +1,45 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.logging
+ * ================================================================================
+ * Copyright © 2018 Amdocs
+ * 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.logging.ref.slf4j.demo.component.gamma;
+
+import java.util.UUID;
+
+import org.testng.annotations.Test;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.Is.is;
+
+/**
+ * Tests for {@link ComponentGamma}.
+ */
+public class ComponentGammaTest {
+
+ @Test
+ public void testGetId() {
+ assertThat(new ComponentGamma().getId(), is("gamma"));
+ }
+
+ @Test
+ public void testGetInstanceUUID() {
+ UUID.fromString(new ComponentGamma().getInstanceUUID());
+ }
+}
diff --git a/reference/logging-slf4j-demo/src/test/java/testng.xml b/reference/logging-slf4j-demo/src/test/java/testng.xml
new file mode 100644
index 0000000..7b31c26
--- /dev/null
+++ b/reference/logging-slf4j-demo/src/test/java/testng.xml
@@ -0,0 +1,8 @@
+<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
+<suite name="org.onap.logging.ref.slf4j" verbose="9" thread-count="1" parallel="methods">
+ <test name="all" thread-count="1" enabled="true">
+ <packages>
+ <package name="org.onap.logging.ref.slf4j.*"/>
+ </packages>
+ </test>
+</suite> \ No newline at end of file