logging-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From rgo...@apache.org
Subject logging-log4j-audit git commit: Add RequestContext
Date Sun, 21 Jan 2018 23:45:39 GMT
Repository: logging-log4j-audit
Updated Branches:
  refs/heads/master 34383867c -> 13458ce7b


Add RequestContext


Project: http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/commit/13458ce7
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/tree/13458ce7
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/diff/13458ce7

Branch: refs/heads/master
Commit: 13458ce7b2934c25e02ce5e87e3d252587b27509
Parents: 3438386
Author: Ralph Goers <rgoers@apache.org>
Authored: Sun Jan 21 16:45:34 2018 -0700
Committer: Ralph Goers <rgoers@apache.org>
Committed: Sun Jan 21 16:45:34 2018 -0700

----------------------------------------------------------------------
 log4j-audit/log4j-audit-api/pom.xml             |   2 +-
 .../log4j/audit/AbstractEventLogger.java        |   2 +-
 .../logging/log4j/audit/LogEventFactory.java    |   1 -
 .../logging/log4j/audit/annotation/Chained.java |  33 +++++
 .../log4j/audit/annotation/ChainedSupplier.java |  29 ++++
 .../log4j/audit/annotation/ClientServer.java    |  29 ++++
 .../log4j/audit/annotation/HeaderPrefix.java    |  29 ++++
 .../logging/log4j/audit/annotation/Local.java   |  28 ++++
 .../annotation/RequestContextConstraints.java   |   2 +-
 .../audit/generator/InterfacesGenerator.java    |   2 -
 .../log4j/audit/request/ChainedMapping.java     |  17 ++-
 .../audit/request/ClientServerMapping.java      |   2 +-
 .../log4j/audit/request/LocalMapping.java       |   2 +-
 .../log4j/audit/request/RequestContextBase.java |  34 -----
 .../audit/request/RequestContextMappings.java   |  76 +++++++++-
 .../logging/log4j/audit/rest/ElapsedUtil.java   |  55 +++++++
 .../log4j/audit/rest/RequestContextFilter.java  | 119 +++++++++++++++
 .../rest/RequestContextHandlerInterceptor.java  |  83 +++++++++++
 .../rest/RequestContextHeaderInterceptor.java   |  24 +--
 .../logging/log4j/audit/RequestContext.java     | 148 +++++++++++++++++++
 .../logging/log4j/audit/RequestContextTest.java |  51 +++++++
 .../audit/service/config/WebMvcAppContext.java  |   1 -
 .../service/controller/AuditController.java     |   8 +-
 23 files changed, 713 insertions(+), 64 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/13458ce7/log4j-audit/log4j-audit-api/pom.xml
----------------------------------------------------------------------
diff --git a/log4j-audit/log4j-audit-api/pom.xml b/log4j-audit/log4j-audit-api/pom.xml
index 2af6dda..e5699ad 100644
--- a/log4j-audit/log4j-audit-api/pom.xml
+++ b/log4j-audit/log4j-audit-api/pom.xml
@@ -88,7 +88,7 @@
       <groupId>javax.servlet</groupId>
       <artifactId>javax.servlet-api</artifactId>
       <version>3.0.1</version>
-      <scope>test</scope>
+      <scope>provided</scope>
     </dependency>
   </dependencies>
 </project>

http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/13458ce7/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/AbstractEventLogger.java
----------------------------------------------------------------------
diff --git a/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/AbstractEventLogger.java b/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/AbstractEventLogger.java
index 1437104..e37c8f2 100644
--- a/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/AbstractEventLogger.java
+++ b/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/AbstractEventLogger.java
@@ -176,7 +176,7 @@ public abstract class AbstractEventLogger {
             }
             if (sb.length() > 0) {
                 throw new IllegalStateException("Event " + msg.getId().getName() +
-                        " is missing required RequestContextBase values for " + sb.toString());
+                        " is missing required RequestContextMapping values for " + sb.toString());
             }
         }
         Map<String, Attribute> reqCtxAttributes = catalogManager.getRequestContextAttributes();

http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/13458ce7/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/LogEventFactory.java
----------------------------------------------------------------------
diff --git a/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/LogEventFactory.java b/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/LogEventFactory.java
index 72ce06a..85f2692 100644
--- a/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/LogEventFactory.java
+++ b/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/LogEventFactory.java
@@ -21,7 +21,6 @@ import java.lang.reflect.InvocationHandler;
 import java.lang.reflect.Method;
 import java.lang.reflect.Proxy;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;

http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/13458ce7/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/annotation/Chained.java
----------------------------------------------------------------------
diff --git a/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/annotation/Chained.java b/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/annotation/Chained.java
new file mode 100644
index 0000000..0678a0b
--- /dev/null
+++ b/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/annotation/Chained.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+package org.apache.logging.log4j.audit.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.util.function.Consumer;
+import java.util.function.Supplier;
+
+@Target(ElementType.FIELD)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface Chained {
+
+    String fieldName();
+
+    String chainedFieldName();
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/13458ce7/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/annotation/ChainedSupplier.java
----------------------------------------------------------------------
diff --git a/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/annotation/ChainedSupplier.java b/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/annotation/ChainedSupplier.java
new file mode 100644
index 0000000..9135565
--- /dev/null
+++ b/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/annotation/ChainedSupplier.java
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+package org.apache.logging.log4j.audit.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Target(ElementType.FIELD)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface ChainedSupplier {
+
+    String value();
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/13458ce7/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/annotation/ClientServer.java
----------------------------------------------------------------------
diff --git a/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/annotation/ClientServer.java b/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/annotation/ClientServer.java
new file mode 100644
index 0000000..c988b67
--- /dev/null
+++ b/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/annotation/ClientServer.java
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+package org.apache.logging.log4j.audit.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Repeatable;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Target(ElementType.FIELD)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface ClientServer {
+
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/13458ce7/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/annotation/HeaderPrefix.java
----------------------------------------------------------------------
diff --git a/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/annotation/HeaderPrefix.java b/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/annotation/HeaderPrefix.java
new file mode 100644
index 0000000..595f05c
--- /dev/null
+++ b/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/annotation/HeaderPrefix.java
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+package org.apache.logging.log4j.audit.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface HeaderPrefix {
+
+    String value() default "request-context-";
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/13458ce7/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/annotation/Local.java
----------------------------------------------------------------------
diff --git a/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/annotation/Local.java b/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/annotation/Local.java
new file mode 100644
index 0000000..14a986a
--- /dev/null
+++ b/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/annotation/Local.java
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+package org.apache.logging.log4j.audit.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Target(ElementType.FIELD)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface Local {
+
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/13458ce7/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/annotation/RequestContextConstraints.java
----------------------------------------------------------------------
diff --git a/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/annotation/RequestContextConstraints.java b/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/annotation/RequestContextConstraints.java
index 27930fe..260d744 100644
--- a/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/annotation/RequestContextConstraints.java
+++ b/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/annotation/RequestContextConstraints.java
@@ -22,7 +22,7 @@ import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
 
 /**
- * Container for RequestContextBase constraints.
+ * Container for RequestContextMapping constraints.
  */
 @Target(ElementType.TYPE)
 @Retention(RetentionPolicy.RUNTIME)

http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/13458ce7/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/generator/InterfacesGenerator.java
----------------------------------------------------------------------
diff --git a/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/generator/InterfacesGenerator.java b/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/generator/InterfacesGenerator.java
index 57d6c2b..8f22c41 100644
--- a/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/generator/InterfacesGenerator.java
+++ b/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/generator/InterfacesGenerator.java
@@ -34,9 +34,7 @@ import org.apache.logging.log4j.catalog.api.Constraint;
 import org.apache.logging.log4j.catalog.api.ConstraintType;
 import org.apache.logging.log4j.catalog.api.Event;
 import org.apache.logging.log4j.catalog.api.EventAttribute;
-import org.apache.logging.log4j.catalog.api.dao.CatalogDao;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.context.ApplicationContext;
 import org.springframework.context.support.ClassPathXmlApplicationContext;

http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/13458ce7/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/request/ChainedMapping.java
----------------------------------------------------------------------
diff --git a/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/request/ChainedMapping.java b/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/request/ChainedMapping.java
index 973551c..32ec5f9 100644
--- a/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/request/ChainedMapping.java
+++ b/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/request/ChainedMapping.java
@@ -16,12 +16,25 @@
  */
 package org.apache.logging.log4j.audit.request;
 
+import java.util.function.Supplier;
+
 /**
- * Represents the mapping of a RequestContextBase variable that is propagated from the client to the server with
+ * Represents the mapping of a RequestContextMapping variable that is propagated from the client to the server with
  * as a new variable name.
  */
 public class ChainedMapping extends RequestContextMapping {
-    public ChainedMapping(String fieldName, String chainedFieldName) {
+    Supplier<String> supplier;
+
+    public ChainedMapping(String fieldName, String chainedFieldName, Supplier<String> localValueSupplier) {
         super(fieldName, Scope.CHAIN, chainedFieldName);
+        this.supplier = localValueSupplier;
+    }
+
+    public Supplier<String> getSupplier() {
+        return supplier;
+    }
+
+    public void setSupplier(Supplier<String> supplier) {
+        this.supplier = supplier;
     }
 }

http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/13458ce7/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/request/ClientServerMapping.java
----------------------------------------------------------------------
diff --git a/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/request/ClientServerMapping.java b/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/request/ClientServerMapping.java
index 3e695d0..ef5eeec 100644
--- a/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/request/ClientServerMapping.java
+++ b/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/request/ClientServerMapping.java
@@ -17,7 +17,7 @@
 package org.apache.logging.log4j.audit.request;
 
 /**
- * Represents the mapping of a RequestContextBase variable that should be propogated from client to server.
+ * Represents the mapping of a RequestContextMapping variable that should be propogated from client to server.
  */
 public class ClientServerMapping extends RequestContextMapping {
     public ClientServerMapping(String fieldName) {

http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/13458ce7/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/request/LocalMapping.java
----------------------------------------------------------------------
diff --git a/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/request/LocalMapping.java b/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/request/LocalMapping.java
index 9df88e5..c1c29c1 100644
--- a/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/request/LocalMapping.java
+++ b/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/request/LocalMapping.java
@@ -17,7 +17,7 @@
 package org.apache.logging.log4j.audit.request;
 
 /**
- * Represents the Mapping for a RequestContextBase variable that only exists in the local application.
+ * Represents the Mapping for a RequestContextMapping variable that only exists in the local application.
  */
 public class LocalMapping extends RequestContextMapping {
     public LocalMapping(String fieldName) {

http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/13458ce7/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/request/RequestContextBase.java
----------------------------------------------------------------------
diff --git a/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/request/RequestContextBase.java b/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/request/RequestContextBase.java
deleted file mode 100644
index 4262221..0000000
--- a/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/request/RequestContextBase.java
+++ /dev/null
@@ -1,34 +0,0 @@
-
-package org.apache.logging.log4j.audit.request;
-
-import java.util.Map;
-
-import org.apache.logging.log4j.ThreadContext;
-
-public abstract class RequestContextBase {
-
-    private static RequestContextMappings mappings = null;
-
-    protected static void setMappings(RequestContextMappings requestContextMappings) {
-        if (mappings != null) {
-            throw new IllegalStateException("RequestContextMappings were previously set");
-        }
-        mappings = requestContextMappings;
-    }
-
-    public static RequestContextMappings getMappings() {
-        return mappings;
-    }
-
-    public static void clear() {
-        ThreadContext.clearMap();
-    }
-
-    public static String get(String key) {
-        return ThreadContext.get(key);
-    }
-
-    public static Map<String, String> get() {
-        return ThreadContext.getImmutableContext();
-    }
-}

http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/13458ce7/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/request/RequestContextMappings.java
----------------------------------------------------------------------
diff --git a/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/request/RequestContextMappings.java b/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/request/RequestContextMappings.java
index 7e6c4c2..c55ea0d 100644
--- a/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/request/RequestContextMappings.java
+++ b/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/request/RequestContextMappings.java
@@ -16,21 +16,85 @@
  */
 package org.apache.logging.log4j.audit.request;
 
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Field;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.function.Supplier;
+
+import org.apache.logging.log4j.audit.annotation.Chained;
+import org.apache.logging.log4j.audit.annotation.ChainedSupplier;
+import org.apache.logging.log4j.audit.annotation.ClientServer;
+import org.apache.logging.log4j.audit.annotation.HeaderPrefix;
+import org.apache.logging.log4j.audit.annotation.Local;
 
 public class RequestContextMappings {
 
+    private static final String DEFAULT_HEADER_PREFIX = "request-context-";
     private final Map<String, RequestContextMapping> mappings = new HashMap<>();
     private final String headerPrefix;
 
-    public RequestContextMappings(RequestContextMapping[] mappingArray, String headerPrefix) {
-        this.headerPrefix = headerPrefix;
-        for (RequestContextMapping mapping : mappingArray) {
-            mappings.put(mapping.getFieldName().toLowerCase(), mapping);
+    public RequestContextMappings(String fqcn) {
+        this(getClass(fqcn));
+    }
+
+    private static Class<?> getClass(String fqcn) {
+        if (fqcn == null) {
+            throw new IllegalArgumentException("RequestContext class name cannot be null");
+        }
+        try {
+            return Class.forName(fqcn);
+        } catch (ClassNotFoundException ex) {
+            throw new IllegalArgumentException("Invalid RequestContext class name", ex);
         }
     }
 
+    public RequestContextMappings(Class<?> clazz) {
+        if (clazz == null) {
+            throw new IllegalArgumentException("A RequestContext class must be provided");
+        }
+        Annotation annotation = clazz.getAnnotation(HeaderPrefix.class);
+        this.headerPrefix = annotation != null ? ((HeaderPrefix) annotation).value().toLowerCase() : DEFAULT_HEADER_PREFIX;
+        Field[] fields = clazz.getDeclaredFields();
+        for (Field field : fields) {
+            if (field.getType().equals(String.class)) {
+                String fieldName;
+                try {
+                    fieldName = (String) field.get(null);
+                } catch (IllegalAccessException ex) {
+                    continue;
+                }
+                if (fieldName == null) {
+                    continue;
+                }
+                annotation = field.getAnnotation(ClientServer.class);
+                if (annotation != null) {
+                    mappings.put(fieldName.toLowerCase(), new ClientServerMapping(fieldName));
+                    continue;
+                }
+
+                annotation = field.getAnnotation(Local.class);
+                if (annotation != null) {
+                    mappings.put(fieldName.toLowerCase(), new LocalMapping(fieldName));
+                }
+            } else if (field.getType().equals(Supplier.class)) {
+                annotation = field.getAnnotation(Chained.class);
+                if (annotation != null) {
+                    Chained chained = (Chained) annotation;
+                    try {
+                        @SuppressWarnings("unchecked")
+                        Supplier<String> supplier = (Supplier<String>) field.get(null);
+                        mappings.put(chained.fieldName().toLowerCase(),
+                                new ChainedMapping(chained.fieldName(), chained.chainedFieldName(), supplier));
+                    } catch (IllegalAccessException ex) {
+                        throw new IllegalArgumentException("Unable to retrieve Supplier for chained field " + chained.fieldName());
+                    }
+                }
+            }
+        }
+        mappings.entrySet().removeIf(a -> validateChained(a.getValue()));
+    }
+
     public RequestContextMapping getMapping(String name) {
         return mappings.get(name.toLowerCase());
     }
@@ -46,4 +110,8 @@ public class RequestContextMappings {
     public String getHeaderPrefix() {
         return headerPrefix;
     }
+
+    private boolean validateChained(RequestContextMapping mapping) {
+        return mapping.getScope() == Scope.CHAIN && !mappings.containsKey(mapping.getChainKey().toLowerCase());
+    }
 }

http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/13458ce7/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/rest/ElapsedUtil.java
----------------------------------------------------------------------
diff --git a/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/rest/ElapsedUtil.java b/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/rest/ElapsedUtil.java
new file mode 100644
index 0000000..46f7c89
--- /dev/null
+++ b/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/rest/ElapsedUtil.java
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+package org.apache.logging.log4j.audit.rest;
+
+import java.text.DecimalFormat;
+
+public class ElapsedUtil {
+
+    private static long NANO_PER_SECOND = 1000000000L;
+    private static long NANO_PER_MINUTE = NANO_PER_SECOND * 60;
+    private static long NANO_PER_HOUR = NANO_PER_MINUTE * 60;
+
+    static void addElapsed(long elapsed, StringBuilder msg) {
+        long nanoseconds = elapsed;
+        // Get elapsed hours
+        long hours = nanoseconds / NANO_PER_HOUR;
+        // Get remaining nanoseconds
+        nanoseconds = nanoseconds % NANO_PER_HOUR;
+        // Get minutes
+        long minutes = nanoseconds / NANO_PER_MINUTE;
+        // Get remaining nanoseconds
+        nanoseconds = nanoseconds % NANO_PER_MINUTE;
+        // Get seconds
+        long seconds = nanoseconds / NANO_PER_SECOND;
+        // Get remaining nanoseconds
+        nanoseconds = nanoseconds % NANO_PER_SECOND;
+
+        if (hours > 0) {
+            msg.append(hours).append(" hours ");
+        }
+        if (minutes > 0 || hours > 0) {
+            msg.append(minutes).append(" minutes ");
+        }
+
+        DecimalFormat numFormat = null;
+        numFormat = new DecimalFormat("#0");
+        msg.append(numFormat.format(seconds)).append('.');
+        numFormat = new DecimalFormat("000000000");
+        msg.append(numFormat.format(nanoseconds)).append(" seconds");
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/13458ce7/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/rest/RequestContextFilter.java
----------------------------------------------------------------------
diff --git a/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/rest/RequestContextFilter.java b/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/rest/RequestContextFilter.java
new file mode 100644
index 0000000..28f922a
--- /dev/null
+++ b/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/rest/RequestContextFilter.java
@@ -0,0 +1,119 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+package org.apache.logging.log4j.audit.rest;
+
+import java.io.IOException;
+import java.text.DecimalFormat;
+import java.util.Enumeration;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.ThreadContext;
+import org.apache.logging.log4j.audit.request.ChainedMapping;
+import org.apache.logging.log4j.audit.request.RequestContextMapping;
+import org.apache.logging.log4j.audit.request.RequestContextMappings;
+
+/**
+ * Filter to initialize and clear the RequestContext.
+ */
+public class RequestContextFilter implements Filter {
+
+    private static final Logger logger = LogManager.getLogger(RequestContextFilter.class);
+    private final Class<?> requestContextClass;
+    private RequestContextMappings mappings;
+
+    public RequestContextFilter() {
+        requestContextClass = null;
+    }
+
+    public RequestContextFilter(Class<?> clazz) {
+        requestContextClass = clazz;
+    }
+
+    /**
+     * @param filterConfig
+     * @throws ServletException
+     */
+    @Override
+    public void init(FilterConfig filterConfig) throws ServletException {
+        if (requestContextClass != null) {
+            mappings = new RequestContextMappings(requestContextClass);
+        } else {
+            String requestContextClassName = filterConfig.getInitParameter("requestContextClass");
+            if (requestContextClassName == null) {
+                logger.error("No RequestContext class name was provided");
+                throw new IllegalArgumentException("No RequestContext class name provided");
+            }
+            mappings = new RequestContextMappings(requestContextClassName);
+        }
+    }
+
+    /**
+     * Manages the initialization and clearing of the RequestContext.
+     */
+    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
+            throws IOException, ServletException {
+        if (servletRequest instanceof HttpServletRequest) {
+            HttpServletRequest request = (HttpServletRequest) servletRequest;
+            HttpServletResponse response = (HttpServletResponse) servletResponse;
+            logger.info("Starting request {}" + request.getRequestURI());
+            try {
+                Enumeration headers = request.getHeaderNames();
+                while (headers.hasMoreElements()) {
+                    String name = (String) headers.nextElement();
+                    RequestContextMapping mapping = mappings.getMappingByHeader(name);
+                    logger.debug("Got Mapping:{} for Header:{}", mapping, name);
+                    if (mapping != null) {
+                        if (mapping.isChained()) {
+                            ThreadContext.put(mapping.getChainKey(), request.getHeader(name));
+                            logger.debug("Setting Context Key:{} with value:{}", mapping.getChainKey(), request.getHeader(name));
+                            String value = ((ChainedMapping)mapping).getSupplier().get();
+                            ThreadContext.put(mapping.getFieldName(), value);
+                            logger.debug("Setting Context Key:{} with value:{}", mapping.getFieldName(), value);
+                        } else {
+                            ThreadContext.put(mapping.getFieldName(), request.getHeader(name));
+                            logger.debug("Setting Context Key:{} with value:{}", mapping.getFieldName(), request.getHeader(name));
+                        }
+                    }
+                }
+                long start = System.nanoTime();
+                filterChain.doFilter(servletRequest, servletResponse);
+                long elapsed = System.nanoTime() - start;
+                StringBuilder sb = new StringBuilder("Request ").append(request.getRequestURI()).append(" completed in ");
+                ElapsedUtil.addElapsed(elapsed, sb);
+                logger.info(sb.toString());
+            } catch (Throwable e) {
+                logger.error("Application cascaded error", e);
+                response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+            } finally {
+                ThreadContext.clearMap();
+            }
+        }
+    }
+
+    public void destroy() {
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/13458ce7/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/rest/RequestContextHandlerInterceptor.java
----------------------------------------------------------------------
diff --git a/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/rest/RequestContextHandlerInterceptor.java b/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/rest/RequestContextHandlerInterceptor.java
new file mode 100644
index 0000000..173461a
--- /dev/null
+++ b/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/rest/RequestContextHandlerInterceptor.java
@@ -0,0 +1,83 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+package org.apache.logging.log4j.audit.rest;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.util.Enumeration;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.ThreadContext;
+import org.apache.logging.log4j.audit.request.ChainedMapping;
+import org.apache.logging.log4j.audit.request.RequestContextMapping;
+import org.apache.logging.log4j.audit.request.RequestContextMappings;
+import org.springframework.web.servlet.HandlerInterceptor;
+import org.springframework.web.servlet.ModelAndView;
+
+/**
+ * May be used instead of the RequestContextFilter to convert RequestContext headers to ThreadContext variables.
+ */
+public class RequestContextHandlerInterceptor implements HandlerInterceptor {
+
+    private static final Logger logger = LogManager.getLogger(RequestContextHandlerInterceptor.class);
+    private RequestContextMappings mappings;
+    private ThreadLocal<Long> startTime = new ThreadLocal<>();
+
+    public RequestContextHandlerInterceptor(Class<?> clazz) {
+        mappings = new RequestContextMappings(clazz);
+    }
+
+    @Override
+    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object o) throws Exception {
+        logger.info("Starting request {}" + request.getRequestURI());
+        Enumeration headers = request.getHeaderNames();
+        while (headers.hasMoreElements()) {
+            String name = (String) headers.nextElement();
+            RequestContextMapping mapping = mappings.getMappingByHeader(name);
+            logger.debug("Got Mapping:{} for Header:{}", mapping, name);
+            if (mapping != null) {
+                if (mapping.isChained()) {
+                    ThreadContext.put(mapping.getChainKey(), request.getHeader(name));
+                    logger.debug("Setting Context Key:{} with value:{}", mapping.getChainKey(), request.getHeader(name));
+                    String value = ((ChainedMapping) mapping).getSupplier().get();
+                    ThreadContext.put(mapping.getFieldName(), value);
+                    logger.debug("Setting Context Key:{} with value:{}", mapping.getFieldName(), value);
+                } else {
+                    ThreadContext.put(mapping.getFieldName(), request.getHeader(name));
+                    logger.debug("Setting Context Key:{} with value:{}", mapping.getFieldName(), request.getHeader(name));
+                }
+            }
+        }
+        startTime.set(System.nanoTime());
+        return true;
+    }
+
+    @Override
+    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object o, ModelAndView modelAndView) throws Exception {
+        long elapsed = System.nanoTime() - startTime.get();
+        StringBuilder sb = new StringBuilder("Request ").append(request.getRequestURI()).append(" completed in ");
+        ElapsedUtil.addElapsed(elapsed, sb);
+        logger.info(sb.toString());
+        startTime.remove();
+    }
+
+    @Override
+    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
+        ThreadContext.clearMap();
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/13458ce7/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/rest/RequestContextHeaderInterceptor.java
----------------------------------------------------------------------
diff --git a/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/rest/RequestContextHeaderInterceptor.java b/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/rest/RequestContextHeaderInterceptor.java
index 49368f1..409cfa4 100644
--- a/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/rest/RequestContextHeaderInterceptor.java
+++ b/log4j-audit/log4j-audit-api/src/main/java/org/apache/logging/log4j/audit/rest/RequestContextHeaderInterceptor.java
@@ -19,7 +19,7 @@ package org.apache.logging.log4j.audit.rest;
 import java.io.IOException;
 import java.util.Map;
 
-import org.apache.logging.log4j.audit.request.RequestContextBase;
+import org.apache.logging.log4j.ThreadContext;
 import org.apache.logging.log4j.audit.request.RequestContextMapping;
 import org.apache.logging.log4j.audit.request.RequestContextMappings;
 import org.springframework.http.HttpHeaders;
@@ -29,29 +29,29 @@ import org.springframework.http.client.ClientHttpRequestInterceptor;
 import org.springframework.http.client.ClientHttpResponse;
 
 /**
- * Creates a List of Headers containing the keys and values in the RequestContextBase that have a mapping indicating
+ * Creates a List of Headers containing the keys and values in the RequestContext that have a mapping indicating
  * they should be propogated to the service being called.
  *
- * This class is designed to be used by Spring as part of the REST Template configuration.
+ * This class is designed to be used by Spring as part of the REST Template configuration when calling a REST service.
  *
  */
 public class RequestContextHeaderInterceptor implements ClientHttpRequestInterceptor {
 
+    private RequestContextMappings mappings = null;
+
+    public void setRequestContextMappings(RequestContextMappings mappings) {
+        this.mappings = mappings;
+    }
+
     @Override
     public ClientHttpResponse intercept(HttpRequest httpRequest, byte[] body,
                                         ClientHttpRequestExecution clientHttpRequestExecution) throws IOException {
-        Map<String, String> map = RequestContextBase.get();
+        Map<String, String> map = ThreadContext.getImmutableContext();
         HttpHeaders headers = httpRequest.getHeaders();
-        RequestContextMappings mappings = RequestContextBase.getMappings();
         for (Map.Entry<String, String> entry : map.entrySet()) {
             RequestContextMapping mapping = mappings.getMapping(entry.getKey());
-            if (mapping != null) {
-                if (mapping.isChained()) {
-
-                    headers.add(mappings.getHeaderPrefix() + mapping.getChainKey(), entry.getValue());
-                } else if (!mapping.isLocal()) {
-                    headers.add(mappings.getHeaderPrefix() + mapping.getFieldName(), entry.getValue());
-                }
+            if (mapping != null && !mapping.isLocal()) {
+                headers.add(mappings.getHeaderPrefix() + mapping.getFieldName(), entry.getValue());
             }
         }
         return clientHttpRequestExecution.execute(httpRequest, body);

http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/13458ce7/log4j-audit/log4j-audit-api/src/test/java/org/apache/logging/log4j/audit/RequestContext.java
----------------------------------------------------------------------
diff --git a/log4j-audit/log4j-audit-api/src/test/java/org/apache/logging/log4j/audit/RequestContext.java b/log4j-audit/log4j-audit-api/src/test/java/org/apache/logging/log4j/audit/RequestContext.java
new file mode 100644
index 0000000..372e294
--- /dev/null
+++ b/log4j-audit/log4j-audit-api/src/test/java/org/apache/logging/log4j/audit/RequestContext.java
@@ -0,0 +1,148 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+package org.apache.logging.log4j.audit;
+
+import java.util.UUID;
+import java.util.function.Supplier;
+
+import org.apache.logging.log4j.ThreadContext;
+import org.apache.logging.log4j.audit.annotation.Chained;
+import org.apache.logging.log4j.audit.annotation.ChainedSupplier;
+import org.apache.logging.log4j.audit.annotation.ClientServer;
+import org.apache.logging.log4j.audit.annotation.HeaderPrefix;
+import org.apache.logging.log4j.audit.annotation.Local;
+import org.apache.logging.log4j.core.util.NetUtils;
+import org.apache.logging.log4j.core.util.UuidUtil;
+
+/**
+ * Defines all the variables that an application needs to be available in the ThreadContext for audit logging and
+ * general application usage.
+ */
+@HeaderPrefix("mycorp-context-")
+public final class RequestContext {
+
+    @ClientServer
+    public static final String REQUEST_ID = "requestId";
+    @ClientServer
+    public static final String SESSION_ID = "sessionId";
+    @ClientServer
+    public static final String ACCOUNT_NUMBER = "accountNumber";
+    @ClientServer
+    public static final String IP_ADDRESS = "ipAddress";
+    @ClientServer
+    public static final String USER_ID = "userId";
+    @ClientServer
+    public static final String LOGIN_ID = "loginId";
+    @Local
+    public static final String CALLING_HOST = "callingHost";
+
+    public static final String HOST_NAME = "hostName";
+
+    private static final String LOCAL_HOST_NAME = NetUtils.getLocalHostname();
+    /**
+     * The Supplier is used to populate the hostName key after the hostName value from the caller has been
+     * placed into the callingHost map entry.
+     */
+    @Chained(fieldName = HOST_NAME, chainedFieldName = CALLING_HOST)
+    public static final Supplier<String> LOCAL_HOST_SUPPLIER = () -> LOCAL_HOST_NAME;
+
+    public static void clear() {
+        ThreadContext.clearMap();
+    }
+
+    public static String getRequestId() {
+        String uuidStr = ThreadContext.get(REQUEST_ID);
+        UUID uuid;
+        if (uuidStr == null) {
+            uuid = UuidUtil.getTimeBasedUuid();
+            ThreadContext.put(REQUEST_ID, uuid.toString());
+        }
+        return uuidStr;
+    }
+
+    public static String getSessionId() {
+        return ThreadContext.get(SESSION_ID);
+    }
+
+    public static void setSessionId(UUID sessionId) {
+        if (sessionId != null) {
+            ThreadContext.put(SESSION_ID, sessionId.toString());
+        }
+    }
+
+    public static void setSessionId(String sessionId) {
+        if (sessionId != null) {
+            ThreadContext.put(SESSION_ID, sessionId);
+        }
+    }
+
+    public static void setAccountNumber(Long accountNumber) {
+        ThreadContext.put(ACCOUNT_NUMBER, accountNumber.toString());
+    }
+
+    public static Long getAccountNumber() {
+        String value = ThreadContext.get(ACCOUNT_NUMBER);
+        if (value == null || value.length() == 0) {
+            return 0L;
+        }
+        try {
+            return Long.parseLong(value);
+        } catch (Exception e) {
+            return 0L;
+        }
+    }
+
+    public static void setIpAddress(String address) {
+        ThreadContext.put(IP_ADDRESS, address);
+    }
+
+    public static String getIpAddress() {
+        return ThreadContext.get(IP_ADDRESS);
+    }
+
+    public static void setUserId(String userId) {
+        ThreadContext.put(USER_ID, userId);
+    }
+
+    public static String getUserId() {
+        return ThreadContext.get(USER_ID);
+    }
+
+    public static void setLoginId(String loginId) {
+        ThreadContext.put(LOGIN_ID, loginId);
+    }
+
+    public static String getLoginId() {
+        return ThreadContext.get(LOGIN_ID);
+    }
+
+    public static String getHostName() {
+        return ThreadContext.get(HOST_NAME);
+    }
+
+    public static void setHostName(String hostName) {
+        ThreadContext.put(HOST_NAME, hostName);
+    }
+
+    public static String getCallingHost() {
+        return ThreadContext.get(CALLING_HOST);
+    }
+
+    public static void setCallingHost(String hostName) {
+        ThreadContext.put(CALLING_HOST, hostName);
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/13458ce7/log4j-audit/log4j-audit-api/src/test/java/org/apache/logging/log4j/audit/RequestContextTest.java
----------------------------------------------------------------------
diff --git a/log4j-audit/log4j-audit-api/src/test/java/org/apache/logging/log4j/audit/RequestContextTest.java b/log4j-audit/log4j-audit-api/src/test/java/org/apache/logging/log4j/audit/RequestContextTest.java
new file mode 100644
index 0000000..754ffa2
--- /dev/null
+++ b/log4j-audit/log4j-audit-api/src/test/java/org/apache/logging/log4j/audit/RequestContextTest.java
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+package org.apache.logging.log4j.audit;
+
+import org.apache.logging.log4j.audit.request.RequestContextMapping;
+import org.apache.logging.log4j.audit.request.RequestContextMappings;
+import org.apache.logging.log4j.audit.request.Scope;
+import org.apache.logging.log4j.core.util.UuidUtil;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+public class RequestContextTest {
+
+    @Test
+    public void testRequestContext() throws Exception {
+        RequestContext.getRequestId();
+        RequestContext.setSessionId(UuidUtil.getTimeBasedUuid().toString());
+        RequestContext.setLoginId("testuser");
+        assertEquals("Incorrect loginId", "testuser", RequestContext.getLoginId());
+        RequestContext.setHostName("myhost");
+        assertEquals("Incorrect host name", "myhost", RequestContext.getHostName());
+        RequestContext.setIpAddress("127.0.0.1");
+        assertEquals("Incorrect LoginId", "127.0.0.1", RequestContext.getIpAddress());
+    }
+
+    @Test
+    public void testMappings() throws Exception {
+        RequestContextMappings mappings = new RequestContextMappings(RequestContext.class);
+        assertEquals("Incorrect header prefix", "mycorp-context-", mappings.getHeaderPrefix());
+        RequestContextMapping mapping = mappings.getMapping("hostName");
+        assertNotNull("No mappings for hostName", mapping);
+        assertEquals("Incorrect chain key", "callingHost", mapping.getChainKey());
+        mapping = mappings.getMapping("loginId");
+        assertEquals("Incorrect scope for loginId", Scope.CLIENT_SERVER, mapping.getScope());
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/13458ce7/log4j-audit/log4j-audit-war/src/main/java/org/apache/logging/log4j/audit/service/config/WebMvcAppContext.java
----------------------------------------------------------------------
diff --git a/log4j-audit/log4j-audit-war/src/main/java/org/apache/logging/log4j/audit/service/config/WebMvcAppContext.java b/log4j-audit/log4j-audit-war/src/main/java/org/apache/logging/log4j/audit/service/config/WebMvcAppContext.java
index 088f12a..db602d1 100644
--- a/log4j-audit/log4j-audit-war/src/main/java/org/apache/logging/log4j/audit/service/config/WebMvcAppContext.java
+++ b/log4j-audit/log4j-audit-war/src/main/java/org/apache/logging/log4j/audit/service/config/WebMvcAppContext.java
@@ -77,7 +77,6 @@ import static org.apache.commons.lang3.StringUtils.isNotBlank;
 @EnableWebMvc
 @EnableScheduling
 @ComponentScan(basePackages = {"org.apache.logging.log4j.catalog.jpa", "org.apache.logging.log4j.audit.service"})
-//@ImportResource("classpath*:propertySources.xml")
 public class WebMvcAppContext extends WebMvcConfigurerAdapter {
 
     private static final Logger LOGGER = LogManager.getLogger(WebMvcAppContext.class);

http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/13458ce7/log4j-audit/log4j-audit-war/src/main/java/org/apache/logging/log4j/audit/service/controller/AuditController.java
----------------------------------------------------------------------
diff --git a/log4j-audit/log4j-audit-war/src/main/java/org/apache/logging/log4j/audit/service/controller/AuditController.java b/log4j-audit/log4j-audit-war/src/main/java/org/apache/logging/log4j/audit/service/controller/AuditController.java
index b934a53..446f283 100644
--- a/log4j-audit/log4j-audit-war/src/main/java/org/apache/logging/log4j/audit/service/controller/AuditController.java
+++ b/log4j-audit/log4j-audit-war/src/main/java/org/apache/logging/log4j/audit/service/controller/AuditController.java
@@ -48,10 +48,12 @@ public class AuditController {
     @PostMapping(value = "/event/log", produces = Versions.V1_0_VALUE)
     @ResponseStatus(value = HttpStatus.OK)
     public void logEvent(@RequestBody AuditDto auditDto) {
-        ThreadContext.clearMap();
         try {
-            for (Map.Entry<String, String> entry : auditDto.getRequestContextMap().entrySet()) {
-                ThreadContext.put(entry.getKey(), entry.getValue());
+            Map<String, String> requestContextMap = auditDto.getRequestContextMap();
+            if (requestContextMap != null) {
+                for (Map.Entry<String, String> entry : requestContextMap.entrySet()) {
+                    ThreadContext.put(entry.getKey(), entry.getValue());
+                }
             }
             auditLogger.logEvent(auditDto.getEventName(), auditDto.getCatalogId(), auditDto.getProperties());
         } finally {


Mime
View raw message