Repository: logging-log4j-audit
Updated Branches:
  refs/heads/master cdcd1ad4b -> 9f16663ff


Remove dependencies, mark others as optional. Improve documentation


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/9f16663f
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/tree/9f16663f
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/diff/9f16663f

Branch: refs/heads/master
Commit: 9f16663ff50660d838dcc5c3e4500de5b31c26ce
Parents: cdcd1ad
Author: Ralph Goers <rgo...@apache.org>
Authored: Sun Feb 4 22:43:39 2018 -0700
Committer: Ralph Goers <rgo...@apache.org>
Committed: Sun Feb 4 22:43:39 2018 -0700

----------------------------------------------------------------------
 log4j-audit/log4j-audit-api/pom.xml             |  16 +-
 .../audit/generator/InterfacesGenerator.java    |  32 --
 .../rest/RequestContextHeaderInterceptor.java   |   2 +-
 log4j-catalog/log4j-catalog-api/pom.xml         |  26 +-
 .../api/annotation/JdbcUrlCondition.java        |   1 -
 pom.xml                                         |   5 +-
 src/site/markdown/catalog.md.vm                 |  86 +++++-
 src/site/markdown/changelog.md                  |  10 -
 src/site/markdown/requestContext.md             |  27 --
 src/site/markdown/requestContext.md.vm          | 291 +++++++++++++++++++
 src/site/markdown/sample.md.vm                  |  48 +++
 src/site/site.xml                               |   3 +-
 12 files changed, 442 insertions(+), 105 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/9f16663f/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 e5699ad..d2f218c 100644
--- a/log4j-audit/log4j-audit-api/pom.xml
+++ b/log4j-audit/log4j-audit-api/pom.xml
@@ -60,8 +60,19 @@
       <artifactId>jackson-datatype-jsr310</artifactId>
     </dependency>
     <dependency>
-      <groupId>net.sf.jopt-simple</groupId>
-      <artifactId>jopt-simple</artifactId>
+      <groupId>org.springframework</groupId>
+      <artifactId>spring-core</artifactId>
+      <optional>true</optional>
+    </dependency>
+    <dependency>
+      <groupId>org.springframework</groupId>
+      <artifactId>spring-web</artifactId>
+      <optional>true</optional>
+    </dependency>
+    <dependency>
+      <groupId>org.springframework</groupId>
+      <artifactId>spring-webmvc</artifactId>
+      <optional>true</optional>
     </dependency>
     <!-- Test Dependencies -->
     <dependency>
@@ -72,6 +83,7 @@
     <dependency>
       <groupId>org.apache.logging.log4j</groupId>
       <artifactId>log4j-jcl</artifactId>
+      <scope>test</scope>
     </dependency>
     <dependency>
       <groupId>org.apache.logging.log4j</groupId>

http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/9f16663f/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 8f22c41..1efd1e4 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
@@ -22,8 +22,6 @@ import java.util.Map;
 import java.util.Optional;
 import java.util.Set;
 
-import joptsimple.OptionParser;
-import joptsimple.OptionSet;
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
 import org.apache.logging.log4j.audit.util.NamingUtils;
@@ -36,11 +34,6 @@ import org.apache.logging.log4j.catalog.api.Event;
 import org.apache.logging.log4j.catalog.api.EventAttribute;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
-import org.springframework.context.ApplicationContext;
-import org.springframework.context.support.ClassPathXmlApplicationContext;
-import org.springframework.context.support.FileSystemXmlApplicationContext;
-import org.springframework.core.env.CommandLinePropertySource;
-import org.springframework.core.env.JOptCommandLinePropertySource;
 import org.springframework.stereotype.Component;
 
 @Component
@@ -120,31 +113,6 @@ public class InterfacesGenerator {
         this.enterpriseId = enterpriseId;
     }
 
-    /**
-     * @param args
-     * @throws Exception
-     */
-    public static void main(String[] args) throws Exception {
-        OptionParser parser = new OptionParser();
-        parser.accepts(CONTEXT);
-        OptionSet options = parser.parse(args);
-        CommandLinePropertySource<joptsimple.OptionSet> clps = new 
JOptCommandLinePropertySource(options);
-        ApplicationContext applicationContext = null;
-        if (clps.containsProperty(CONTEXT)) {
-            applicationContext = new 
FileSystemXmlApplicationContext(clps.getProperty(CONTEXT));
-        } else {
-            applicationContext = new ClassPathXmlApplicationContext();
-        }
-        InterfacesGenerator generator =
-                (InterfacesGenerator) 
applicationContext.getBean("org.apache.logging.log4j.audit.generator.InterfacesGenerator");
-        if (generator != null) {
-            generator.generateSource();
-            return;
-        }
-        LOGGER.error("Unable to generate source files, no generator is 
configured");
-        System.exit(-1);
-    }
-
     public void generateSource() throws Exception {
         boolean errors = false;
         CatalogData catalogData = catalogReader.read();

http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/9f16663f/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 b2d309a..850a34b 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
@@ -39,7 +39,7 @@ public class RequestContextHeaderInterceptor implements 
ClientHttpRequestInterce
 
     private RequestContextMappings mappings = null;
 
-    public void setRequestContextMappings(RequestContextMappings mappings) {
+    public RequestContextHeaderInterceptor(RequestContextMappings mappings) {
         this.mappings = mappings;
     }
 

http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/9f16663f/log4j-catalog/log4j-catalog-api/pom.xml
----------------------------------------------------------------------
diff --git a/log4j-catalog/log4j-catalog-api/pom.xml 
b/log4j-catalog/log4j-catalog-api/pom.xml
index 79109a5..35616c0 100644
--- a/log4j-catalog/log4j-catalog-api/pom.xml
+++ b/log4j-catalog/log4j-catalog-api/pom.xml
@@ -37,16 +37,6 @@
   </distributionManagement>
   <dependencies>
     <dependency>
-      <groupId>io.springfox</groupId>
-      <artifactId>springfox-swagger2</artifactId>
-      <exclusions>
-        <exclusion>
-          <groupId>org.aspectj</groupId>
-          <artifactId>aspectjrt</artifactId>
-        </exclusion>
-      </exclusions>
-    </dependency>
-    <dependency>
       <groupId>junit</groupId>
       <artifactId>junit</artifactId>
       <scope>test</scope>
@@ -86,23 +76,13 @@
     </dependency>
     <dependency>
       <groupId>org.springframework</groupId>
-      <artifactId>spring-context</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.springframework</groupId>
-      <artifactId>spring-context-support</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.springframework</groupId>
-      <artifactId>spring-beans</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.springframework</groupId>
       <artifactId>spring-core</artifactId>
+      <optional>true</optional>
     </dependency>
     <dependency>
       <groupId>org.springframework</groupId>
-      <artifactId>spring-aop</artifactId>
+      <artifactId>spring-web</artifactId>
+      <optional>true</optional>
     </dependency>
     <dependency>
       <groupId>javax.servlet</groupId>

http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/9f16663f/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/annotation/JdbcUrlCondition.java
----------------------------------------------------------------------
diff --git 
a/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/annotation/JdbcUrlCondition.java
 
b/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/annotation/JdbcUrlCondition.java
index ceeca50..435558b 100644
--- 
a/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/annotation/JdbcUrlCondition.java
+++ 
b/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/annotation/JdbcUrlCondition.java
@@ -21,7 +21,6 @@ import org.springframework.context.annotation.Condition;
 import org.springframework.context.annotation.ConditionContext;
 import org.springframework.core.env.Environment;
 import org.springframework.core.type.AnnotatedTypeMetadata;
-import org.springframework.util.MultiValueMap;
 
 /**
  *

http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/9f16663f/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 79a47e9..4f69dc5 100644
--- a/pom.xml
+++ b/pom.xml
@@ -143,11 +143,8 @@
     <json.version>20090211</json.version>
     <junit.version>4.12</junit.version>
     <jxr.plugin.version>2.5</jxr.plugin.version>
-    <log4j.version>2.9.2-SNAPSHOT</log4j.version>
+    <log4j.version>2.10.0</log4j.version>
     <mockito.version>2.0.31-beta</mockito.version>
-    <nextiva.properties.version>6.0.26</nextiva.properties.version>
-    <nextiva.utilities.version>6.0.34-SNAPSHOT</nextiva.utilities.version>
-    <oracle.ojdbc.version>12.1.0.2</oracle.ojdbc.version>
     <pdf.plugin.version>1.2</pdf.plugin.version>
     <pmd.plugin.version>3.6</pmd.plugin.version>
     <postgresql.version>42.2.0</postgresql.version>

http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/9f16663f/src/site/markdown/catalog.md.vm
----------------------------------------------------------------------
diff --git a/src/site/markdown/catalog.md.vm b/src/site/markdown/catalog.md.vm
index 9ac78ab..62d270f 100644
--- a/src/site/markdown/catalog.md.vm
+++ b/src/site/markdown/catalog.md.vm
@@ -18,6 +18,7 @@
 #set($h1='#')
 #set($h2='##')
 #set($h3='###')
+#set($h4='####')
 
 $h1 The Apache Log4j Audit Catalog
 
@@ -33,14 +34,91 @@ Attributes are the discrete data elements to be captured in 
audit events. One of
 is to avoid having what are essentially the same attributes with different 
names in various events. When creating
 new events users are highly encouraged to scan the existing attributes for one 
that is already present.
 
-An Attribute definition contains the following items:
-*
+Attributes can have aliases and examples, however the Catalog UI provides no 
way to edit these and Log4j Audit
+currently doesn't do anything with these fields.
 
 $h3 Events
 
-$h3 Products
+Events represent the aggregation of attributes to be collected when a specific 
action is performed. Event
+names should identify what action took place and the associated attributes 
should identify the key characteristics
+of who performed the action and what they did.
 
-$h3 Categories
+Events can have aliases, however the Catalog UI provides no way to edit them 
and Log4j Audit
+currently doesn't do anything with alias fields.
 
+$h3 Products and Categories.
 
+Products and Categories can be defined as a way of grouping events. Log4j 
Audit doesn't do anything with
+this data but a user interface might use this data as a way to limit searches 
or provide a drop down list
+of events.
+
+$h2 The Catalog Editor
+
+Log4j Audit provides an AuditCatalog WAR that can be deployed to a servlet 
container for use in creating and
+maintaining the catalog. Because the Catalog Editor requires the credentials 
to be configured on the machine
+where the web application is running and it performs no other authentication 
of the user, it is recommended
+that the Catalog Editor be run locally on the user's machine.
+
+The catalog provides screens to maintain the attributes, events, products, and 
categories defined in the catalog.
+Changes made to these entities are stored in an in-memory database until the 
user elects to persist them, at which
+time the catalog is exported as JSON and stored into the configured git 
repository.
+
+Because the editor can only edit the default catalog and the persistant 
storage is the JSON file in the Git
+repository, the Catalog Editor is configured to only use the in memory 
database.
+
+$h3 Attributes
+
+The attribute edit screen allows attributes to be defined, modified or 
deleted. The fields that may be modified are:
+<table>
+<tr><th>Field</th><th>Description</th></tr>
+<tr><td>Name</td><td>The name of the attribute as it will be known to Java. It 
is expected to be defined in camelCase.</td></tr>
+<tr><td>Display Name</td><td>The text that should be used to display the field 
in an application</td></tr>
+<tr><td>Description</td><td>The description of the attribute as it would 
appear in help text in a UI.</td></tr>
+<tr><td>Data Type</td><td>The type of data contained in the field. Must be one 
of BIG_DECIMAL, BOOLEAN, DOUBLE, FLOAT, INT, LIST, LONG, MAP, STRING</td></tr>
+<tr><td>Indexed</td><td>True if this field should be indexed when stored in a 
database.</td></tr>
+<tr><td>Sortable</td><td>True if this field should be sortable when displayed 
in a UI.</td></tr>
+<tr><td>Required</td><td>True if this field is required by default</td></tr>
+<tr><td>Request Context</td><td>True if this attribute is provided in the 
RequestContext</td></tr>
+<tr><td>Constraints</td><td>Rules to use to validate the value. Must be null 
or one of ANYCASEENUM, ENUM, MAXLENGTH, MAXVALUE, MINLENGTH, MINVALUE, 
PATTERN</td></tr>
+</table>
+
+$h4 Data Types
+
+An attribute must be defined as being one of the supported data types. Log4j 
Audit will use this information when generating the
+event Interfaces. By doing so, the data being logged will be guaranteed to be 
of the correct type at compile time. When
+logging using the Audit Service the data will be validated for the correct 
type when the event is received.
+
+$h4 Constraints
+
+If a constraint is present on an attribute definition Log4j Audit will 
validate the value when the event is logged. The enum types must provide
+a list of valid values. The min and max constraints must be configured with an 
appropriate value. The pattern constraints must be configured
+with a regular expression to apply against the value. If the data fails to 
validate against a constraint the attempt to audit the event will fail.
+Using constraints can prevent garbage data from being included in the audit 
database but at the cost of potentially having auditing fail.
+
+![Attribute Editor](images/attributes.png "Attribute Editor")
+
+$h3 Events
+
+The event edit screen allows events to be defined, modified, or deleted. The 
fields that may be modified are:
+<table>
+<tr><th>Field</th><th>Description</th></tr>
+<tr><td>Name</td><td>The name of the event as it will be known in the catalog. 
It is expected to be defined in camelCase.</td></tr>
+<tr><td>Display Name</td><td>The text that should be used to display the name 
of the event in an application</td></tr>
+<tr><td>Description</td><td>The description of the event as it would appear in 
help text in a UI.</td></tr>
+<tr><td>Assigned Attributes</td><td>The attributes to be associated with this 
event and whether they are required.</td></tr>
+</table>
+
+RequestContext attributes are always part of audit events whether they are 
declared or not. Specifying a non-RequestContext
+attribute is required for it to be associated with an event. Specifying a 
value of True or False for whether the
+attribute is required to be present will override whatever definition was 
present when the attribute was defined. If
+neither box is checked the attribute definition's required attribute will be 
honored.
+
+
+![Event Editor](images/events.png "Event Editor")
+
+$h3 Products and Categories
+
+Events may be grouped into products and categories, however it is not required 
that an event be included in a product or category.
+Log4j Audit doesn't use the products or categories itself, however UI tools 
that display audit events may choose to filter based on
+products or categories.
 

http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/9f16663f/src/site/markdown/changelog.md
----------------------------------------------------------------------
diff --git a/src/site/markdown/changelog.md b/src/site/markdown/changelog.md
index d021ed1..120a4a9 100644
--- a/src/site/markdown/changelog.md
+++ b/src/site/markdown/changelog.md
@@ -22,13 +22,3 @@
 
 [Manual change log](changes-report.html)
 
-Apache Log4j 2 is not compatible with the previous versions. Please have the 
following in mind when upgrading to
-Log4j 2 in your project:
-
-* Log4j 2.4 and greater requires Java 7, versions 2.0-alpha1 to 2.3 required 
Java 6.
-* The XML configuration has been simplified and is not compatible with Log4j 
1.x.
-* Configuration via property files is supported from version 2.4, but is not 
compatible with Log4j 1.x.
-* Configuration via JSON or YAML is supported, but these formats require
-[additional runtime dependencies](runtime-dependencies.html).
-* Although Log4j 2 is not directly compatible with Log4j 1.x a compatibility 
bridge has been provided to reduce the
-need to make coding changes.

http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/9f16663f/src/site/markdown/requestContext.md
----------------------------------------------------------------------
diff --git a/src/site/markdown/requestContext.md 
b/src/site/markdown/requestContext.md
deleted file mode 100644
index ac16cd0..0000000
--- a/src/site/markdown/requestContext.md
+++ /dev/null
@@ -1,27 +0,0 @@
-<!-- vim: set syn=markdown : -->
-<!--
-    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.
--->
-#set($h1='#')
-#set($h2='##')
-#set($h3='###')
-
-$h1 RequestContext
-
-Log4j-Audit incorporates Log4j ThreadContext variables 
-
-$h2 Catalog Components
-

http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/9f16663f/src/site/markdown/requestContext.md.vm
----------------------------------------------------------------------
diff --git a/src/site/markdown/requestContext.md.vm 
b/src/site/markdown/requestContext.md.vm
new file mode 100644
index 0000000..2fcb2ac
--- /dev/null
+++ b/src/site/markdown/requestContext.md.vm
@@ -0,0 +1,291 @@
+<!-- vim: set syn=markdown : -->
+<!--
+    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.
+-->
+#set($h1='#')
+#set($h2='##')
+#set($h3='###')
+
+$h1 RequestContext
+
+Log4j-Audit incorporates Log4j ThreadContext variables as a way of including 
information into audit events that is
+common throughout the application. This would include things like a client 
account number (especially useful in
+multi-tenant applications), the user's login id, and the ip address of the 
user. In a services-based application
+these values need to be populated at the point of entry to the application and 
then passed to all the service
+endpoints. It is especially useful to create artificial request and session 
ids so that all the activities across
+all the servers can be correlated to the user's request and/or session.
+
+Log4j provides a convenient way to identify the RequestContext variables such 
that they can be reliably accessed by the
+application and passed to the target services. To do this the application 
should create a RequestContext class that
+resembles:
+
+```
+import org.apache.logging.log4j.ThreadContext;
+import org.apache.logging.log4j.audit.annotation.Chained;
+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;
+    /**
+     * The methods in this class are not required by framework components that 
use the RequestContext properties.
+     * They are provided as a convenience for applications. If they are not 
provided the properties can be accessed
+     * directly through the Log4j ThreadContext Map using the keys above.
+     */
+    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);
+    }
+}
+```
+The HeaderPrefix annotation is used to define the string to be prepended to 
the names of the ThreadContext variables
+when they are passed to a REST service. The default value is 
"request-context-".
+
+The ClientServer, Local, and Chained annotations represent the 3 types of 
RequestContext variables.
+* ClientServer represents a variable whose value should be passed to the 
target service using the same name.
+* Local represents a variable that is used in the local application and should 
not be passed to a client service.
+* Chained represents a variable that should be passed to the target service 
using a new name. A variable with the
+same named may be created in the target service using a different value. This 
is primarily used to pass the name
+of the current server to the target service.
+
+The public static set and get methods are optional but provide a convenient 
way to access the variables stored in
+Log4j's ThreadContext Map.
+
+$h2 Initializing the RequestContext
+
+The RequestContext should be initialized at the beginning of every request and 
cleared at the end of the request. In
+a Spring web application this can be handled in a Servlet Filter similar to 
this example.
+
+```
+public class RequestContextInterceptor implements HandlerInterceptor {
+
+       private static Logger logger = 
LogManager.getLogger(RequestContextInterceptor.class);
+       private ThreadLocal<Long> startTime = new ThreadLocal<>();
+
+       @Override
+       public boolean preHandle(HttpServletRequest request,
+                        HttpServletResponse response, Object handler) throws 
Exception {
+
+        boolean success = true;
+        String uri = request.getRequestURI();
+        String queryString = request.getQueryString();
+        HttpSession session = request.getSession(true);
+
+
+        if (!uri.contains("login") {
+            // SessionData will be populated during login.
+            SessionData sessionData = SessionData.getSessionData(session);
+            if (sessionData == null) {
+                logger.info("no account logged in - send to login page");
+                response.sendRedirect("/login);
+                success = false;
+            } else {
+                startTime.set(System.nanoTime());
+                               long corpAcctNbr = 
sessionData.getCorporateAccountNumber();
+                RequestContext.getRequestId();
+                RequestContext.setCorpAcctNumber(corpAcctNbr);
+                
RequestContext.setUserId(Long.toString(sessionData.getUserId()));
+                RequestContext.setIpAddress(request.getRemoteAddr());
+                RequestContext.setOnBehalfOf(sessionData.getOnBehalfOf());
+                       
RequestContext.setOnBehalfOfAccount(sessionData.getOnBehalfOfAccount());
+                               
RequestContext.setSessionId(sessionData.getSessionId());
+                       RequestContext.setLoginId(sessionData.getLoginId());
+                String localHost = NetUtils.getLocalHostname();
+                if (localHost != null && !localHost.equals("UNKNOWN_HOST")) {
+                    RequestContext.setHostName(localHost);
+                }
+                RequestContext.setProductName("Application");
+                RequestContext.setProductVersion("3");
+                       }
+               } else {
+            RequestContext.setIpAddress(request.getRemoteAddr());
+            startTime.set(System.nanoTime());
+        }
+
+
+               return success;
+       }
+
+       @Override
+       public void postHandle(HttpServletRequest request,
+                       HttpServletResponse response, Object handler,
+                       ModelAndView modelAndView) throws Exception {
+       }
+
+       @Override
+       public void afterCompletion(HttpServletRequest request,
+                       HttpServletResponse response, Object handler, Exception 
ex)
+                       throws Exception {
+           Long start = startTime.get();
+        if (start != null) {
+            long elapsed = System.nanoTime() - start;
+            startTime.remove();
+            StringBuilder sb = new StringBuilder("Request 
").append(request.getRequestURI()).append(" completed in ");
+            ElapseUtil.addElapsed(elapsed, sb);
+            logger.info(sb.toString());
+        }
+               RequestContext.clear();
+       }
+```
+
+$h2 Passing the RequestContext to a Service
+
+Log4j Audit provides an Interceptor that can be used with Spring applications 
that will convert RequestContext
+variables to HTTP headers. The RequestContextHeaderInterceptor can be created 
by a java configuration method such as:
+
+```
+    @Bean
+    public List<ClientHttpRequestInterceptor> createInterceptor() {
+        List<ClientHttpRequestInterceptor> list = new ArrayList<>();
+        RequestContextMappings mappings = new 
RequestContextMappings(RequestContext.class));
+        list.add(new RequestContextHeaderInterceptor(mappings);
+        return list;
+    }
+```
+
+The returned list should then be added to the RestTemplate.
+
+The target application then needs to convert the headers back into 
RequestContext variables by creating a class that
+extends WebApplicationInitializer that does:
+
+```
+    @Override
+    public void onStartup(ServletContext servletContext) throws 
ServletException {
+        RequestContextFilter filter = new 
RequestContextFilter(RequestContext.class);
+        servletContext.addFilter("requestContextFilter", 
filter).addMappingForUrlPatterns(null, true, "/*");
+    }
+```
+
+As an added benefit, the RequestContextFilter will log the beginning and end 
of each request and log the elapsed
+time at the end of the request.
+
+When logging RequestContext variables simply configure log4j2.xml to include 
specific ThreadContext variables or
+all of them using the %X pattern converter or by setting the includeMdc, 
includeThreadContext, or properties attribute
+to true on the desired Layout.
+
+

http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/9f16663f/src/site/markdown/sample.md.vm
----------------------------------------------------------------------
diff --git a/src/site/markdown/sample.md.vm b/src/site/markdown/sample.md.vm
new file mode 100644
index 0000000..d4ca2bd
--- /dev/null
+++ b/src/site/markdown/sample.md.vm
@@ -0,0 +1,48 @@
+<!-- vim: set syn=markdown : -->
+<!--
+    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.
+-->
+#set($h1='#')
+#set($h2='##')
+#set($h3='###')
+
+$h1 The Apache Log4j Audit Sample Project
+
+Log4j-Audit has a companion sample project at 
https://github.com/apache/logging-log4j-audit-sample. This project
+contains 3 modules that are described in the following sections. Developers 
may clone this project and use it
+as the basis for their own auditing projects
+
+$h2 Audit Service API
+
+The Audit Service API module contains the JSON catalog file that is used to 
generate the audit event Interfaces.
+After running the build the generated Java source files will reside in the 
target/generated-source/log4j-audit
+directory. All the classes will be in the org.apache.logging.log4j.audit.event 
package.
+
+$h2 Audit Service WAR
+
+The Audit Service WAR module builds a REST application that can be deployed to 
a servlet container. The REST
+application provides endpoints to perform audit logging for remote and 
non-Java applications as well as
+endpoints to create, read, update and delete dynamic catalog entries.
+
+$h2 Sample Application
+
+As its name implies, the sample application module provides a minimal sample 
application that demonstrates how
+audit logging may be performed. Because this is a standalone application 
instead of a web application, initialization
+of the RequestContext does not match how it would typically be done when 
integrated into a web application.
+
+
+
+

http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/9f16663f/src/site/site.xml
----------------------------------------------------------------------
diff --git a/src/site/site.xml b/src/site/site.xml
index fc3a2e5..b6d1d0b 100644
--- a/src/site/site.xml
+++ b/src/site/site.xml
@@ -21,7 +21,7 @@
          xsi:schemaLocation="http://maven.apache.org/DECORATION/1.4.0 
http://maven.apache.org/xsd/decoration-1.4.0.xsd";>
   <body>
     <links>
-      <item name="Logging Wiki" href="https://wiki.apache.org/logging"/>
+      <item name="Logging Wiki" 
href="https://cwiki.apache.org/confluence/display/LOGGING/Home"/>
       <item name="Apache" href="https://www.apache.org/"/>
       <item name="Logging Services" href="https://logging.apache.org/"/>
       <item name="GitHub" 
href="https://github.com/apache/logging-log4j-audit"/>
@@ -42,6 +42,7 @@
       <item name="Getting Started" href="/gettingStarted.html"/>
       <item name="RequestContext" href="/requestContext.html"/>
       <item name="Audit Catalog" href="catalog.html"/>
+      <item name="Sample Project" href="sample.html"/>
       <item name="Changelog" href="/changelog.html"/>
     </menu>
 

Reply via email to