http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/f0884aeb/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/Event.java
----------------------------------------------------------------------
diff --git 
a/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/Event.java
 
b/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/Event.java
new file mode 100644
index 0000000..4c1c582
--- /dev/null
+++ 
b/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/Event.java
@@ -0,0 +1,185 @@
+/*
+ * 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.catalog.api;
+
+import java.io.Serializable;
+import java.util.List;
+import java.util.Set;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+
+/**
+ * Basic attributes common to all events.
+ */
+public class Event implements Serializable {
+
+    private static final long serialVersionUID = 1512172827909901054L;
+    private Long id;
+    private String name;
+    private String displayName;
+    private String description;
+    private Set<String> aliases;
+    @JsonIgnore
+    private String catalogId;
+    private List<EventAttribute> attributes;
+
+    /**
+     * Set default values.
+     */
+    public Event() {
+        catalogId = "DEFAULT";
+    }
+    
+    /**
+     * Return the id or the event.
+     * @return the Event's id.
+     */
+    public Long getId() {
+        return id;
+    }
+
+    /**
+     * Set the event's id.
+     * @param id the Event's id.
+     */
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    /**
+     * Return the name of the event.
+     * @return the name of the event.
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * Sets the name of the event.
+     * @param name The name of the event.
+     * @return this Event.
+     */
+    public Event setName(String name) {
+        this.name = name;
+        return this;
+    }
+
+    /**
+     * Returns the name to display for this event.
+     * @return the display name for this event.
+     */
+    public String getDisplayName() {
+        return displayName;
+    }
+
+    /**
+     * Set the display name for this event.
+     * @param name the name to display for this event.
+     * @return this Event.
+     */
+    public Event setDisplayName(String name) {
+        this.displayName = name;
+        return this;
+    }
+
+    /**
+     * Return the description of the event.
+     * @return the event description.
+     */
+    public String getDescription() {
+        return description;
+    }
+
+    /**
+     * Set the event description.
+     * @param description The description of the event.
+     * @return this Event.
+     */
+    public Event setDescription(String description) {
+        this.description = description;
+        return this;
+    }
+
+    /**
+     * Get the Catalog Id this Event is associated with.
+     * @return the catalog id or null.
+     */
+    public String getCatalogId() {
+        return catalogId;
+    }
+
+    /**
+     * Set the catalog id this Event is associated with.
+     * @param catalogId The catalog id or null.
+     */
+    public void setCatalogId(String catalogId) {
+        this.catalogId = catalogId;
+    }
+
+    /**
+     * Returns the Set of alias Strings.
+     * @return the Set of alias Strings.
+     */
+    public Set<String> getAliases() {
+        return aliases;
+    }
+
+    /**
+     * Sets the Set of alias Strings.
+     * @param aliases the Set of alias Strings.
+     * @return this Event.
+     */
+    public Event setAliases(Set<String> aliases) {
+        this.aliases = aliases;
+        return this;
+    }
+
+    /**
+     * Returns the List of Attribute names.
+     * @return the List of Attribute names.
+     */
+    public List<EventAttribute> getAttributes() {
+        return attributes;
+    }
+
+    /**
+     * Sets the List of Atribute names.
+     * @param attributes The List of Attribute names.
+     * @return this Event.
+     */
+    public Event setAttributes(List<EventAttribute> attributes) {
+        this.attributes = attributes;
+        return this;
+    }
+
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append("{\"name\" : \"").append(name).append("\", \"displayName\" : 
\"").append(displayName).append("\"");
+        sb.append(", \"description\" : \"").append(description).append("\", 
\"attributes\" : [");
+        boolean first = true;
+        for (EventAttribute attribute : attributes) {
+            if (!first) {
+                sb.append(", ");
+            } else {
+                first = false;
+            }
+            sb.append("{\"name\" : 
\"").append(attribute.getName()).append("\", \"required\" : 
").append(attribute.isRequired()).append("}");
+        }
+        sb.append("]}");
+        return sb.toString();
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/f0884aeb/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/EventAttribute.java
----------------------------------------------------------------------
diff --git 
a/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/EventAttribute.java
 
b/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/EventAttribute.java
new file mode 100644
index 0000000..325e416
--- /dev/null
+++ 
b/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/EventAttribute.java
@@ -0,0 +1,67 @@
+/*
+ * 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.catalog.api;
+
+/**
+ * Attribute used in an event
+ */
+public class EventAttribute {
+
+    private String name;
+
+    private boolean isRequired;
+
+    public EventAttribute() {
+    }
+
+    public EventAttribute(String name, boolean isRequired) {
+        this.name = name;
+        this.isRequired = isRequired;
+    }
+
+    /**
+     * The name of the attribute.
+     * @return the name of the Attribute.
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * Set the name of the Attribute.
+     * @param attributeName the Attribute's name.
+     */
+    public void setName(String attributeName) {
+        this.name = attributeName;
+    }
+
+    /**
+     * Indicates whether the attribute is required.
+     * @return true if the Attribute is required, false otherwise.
+     */
+    public boolean isRequired() {
+        return isRequired;
+    }
+
+    /**
+     * Sets whether the attribute is required.
+     * @param required true if the attribute is required, false otherwise.
+     */
+    public void setRequired(boolean required) {
+        isRequired = required;
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/f0884aeb/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/ListResponse.java
----------------------------------------------------------------------
diff --git 
a/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/ListResponse.java
 
b/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/ListResponse.java
new file mode 100644
index 0000000..3ddf8be
--- /dev/null
+++ 
b/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/ListResponse.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2001-2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.logging.log4j.catalog.api;
+
+import java.util.List;
+
+/**
+ *
+ */
+public class ListResponse<T> {
+
+    private String result;
+    private List<T> data;
+
+    public String getResult() {
+        return result;
+    }
+
+    public void setResult(String result) {
+        this.result = result;
+    }
+
+    public List<T> getData() {
+        return data;
+    }
+
+    public void setData(List<T> data) {
+        this.data = data;
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/f0884aeb/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/Product.java
----------------------------------------------------------------------
diff --git 
a/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/Product.java
 
b/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/Product.java
new file mode 100644
index 0000000..f9f3737
--- /dev/null
+++ 
b/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/Product.java
@@ -0,0 +1,151 @@
+/*
+ * 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.catalog.api;
+
+import java.io.Serializable;
+import java.util.List;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import org.apache.logging.log4j.catalog.api.Event;
+
+
+/**
+ * Definition of a Product.
+ */
+public class Product implements Serializable {
+
+    private static final long serialVersionUID = -736368842796386523L;
+    private Long id;
+    private String name;
+    private String displayName;
+    private String description;
+    @JsonIgnore
+    private String catalogId;
+    private List<String> events;
+
+    /**
+     * Set default values.
+     */
+    public Product() {
+        catalogId = "DEFAULT";
+    }
+    
+    /**
+     * Return the id of the Product.
+     * @return the Product's id.
+     */
+    public Long getId() {
+        return id;
+    }
+
+    /**
+     * Set the id of the Product.
+     * @param id the Product's id.
+     */
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    /**
+     * Returns the name of the product.
+     * @return the name of the product.
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * Set the name of the product.
+     * @param name the name of the product.
+     * @return this Product.
+     */
+    public Product setName(String name) {
+        this.name = name;
+        return this;
+    }
+
+    /**
+     * Returns the name used when displaying the product.
+     * @return the display name of the product.
+     */
+    public String getDisplayName() {
+        return displayName;
+    }
+
+    /**
+     * Set the name to be displayed for this product.
+     * @param name the display name for the product.
+     * @return this Product.
+     */
+    public Product setDisplayName(String name) {
+        this.displayName = name;
+        return this;
+    }
+
+    /**
+     * Return the product description.
+     * @return the description of the product.
+     */
+    public String getDescription() {
+        return description;
+    }
+
+    /**
+     * Set the description of the product.
+     * @param description the description of the product.
+     * @return this Product.
+     */
+    public Product setDescription(String description) {
+        this.description = description;
+        return this;
+    }
+
+    /**
+     * Get the Catalog Id this Product is associated with.
+     * @return the catalog id or null.
+     */
+    public String getCatalogId() {
+        return catalogId;
+    }
+
+    /**
+     * Set the catalog id this Product is associated with.
+     * @param catalogId The catalog id or null.
+     */
+    public void setCatalogId(String catalogId) {
+        this.catalogId = catalogId;
+    }
+
+    /**
+     * Returns the List of Event names associated with this product.
+     * @return the List of Events.
+     */
+    public List<String> getEvents() {
+        return events;
+    }
+
+    /**
+     * Sets the List of Event names for this product.
+     * @param events the List of Events.
+     * @return this Product.
+     */
+    public Product setEvents(List<String> events) {
+        this.events = events;
+        return this;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/f0884aeb/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/Type.java
----------------------------------------------------------------------
diff --git 
a/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/Type.java
 
b/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/Type.java
new file mode 100644
index 0000000..ef2ac55
--- /dev/null
+++ 
b/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/Type.java
@@ -0,0 +1,27 @@
+/*
+ * 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.catalog.api;
+
+/**
+ * Definition of an EventDto type.
+ */
+public class Type {
+
+    private String typeName;
+
+
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/f0884aeb/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/Versions.java
----------------------------------------------------------------------
diff --git 
a/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/Versions.java
 
b/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/Versions.java
new file mode 100644
index 0000000..6d824f1
--- /dev/null
+++ 
b/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/Versions.java
@@ -0,0 +1,26 @@
+/*
+ * 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.catalog.api;
+
+import org.springframework.http.MediaType;
+
+public final class Versions {
+    public static final MediaType V1_0 = new MediaType("application", 
"vnd.nextiva.license-v1.0+json");
+    public static final String V1_0_VALUE = 
"application/vnd.nextiva.license-v1.0+json";
+
+    private Versions() { }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/f0884aeb/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/annotation/ConditionOnPropertyExists.java
----------------------------------------------------------------------
diff --git 
a/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/annotation/ConditionOnPropertyExists.java
 
b/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/annotation/ConditionOnPropertyExists.java
new file mode 100644
index 0000000..ae88ebf
--- /dev/null
+++ 
b/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/annotation/ConditionOnPropertyExists.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2001-2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.logging.log4j.catalog.api.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import org.springframework.context.annotation.Conditional;
+
+/**
+ * Prevents a bean from being created unless a property exists.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.TYPE, ElementType.METHOD})
+@Conditional(value = PropertyExistsCondition.class)
+public @interface ConditionOnPropertyExists {
+    /**
+     * The name of the property to test for existence.
+     * @return The property name.
+     */
+    public String value();
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/f0884aeb/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/annotation/PropertyExistsCondition.java
----------------------------------------------------------------------
diff --git 
a/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/annotation/PropertyExistsCondition.java
 
b/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/annotation/PropertyExistsCondition.java
new file mode 100644
index 0000000..f11a94d
--- /dev/null
+++ 
b/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/annotation/PropertyExistsCondition.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2001-2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.logging.log4j.catalog.api.annotation;
+
+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;
+
+/**
+ *
+ */
+public class PropertyExistsCondition implements Condition {
+    @Override
+    public boolean matches(ConditionContext context, AnnotatedTypeMetadata 
metadata) {
+        Environment env = context.getEnvironment();
+        MultiValueMap<String, Object> attrs = 
metadata.getAllAnnotationAttributes(ConditionOnPropertyExists.class.getName());
+        if (attrs != null) {
+            Object value = attrs.get("value");
+            return value != null && null != env && 
env.getProperty(value.toString()) != null;
+        }
+        return false;
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/f0884aeb/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/dao/AbstractCatalogReader.java
----------------------------------------------------------------------
diff --git 
a/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/dao/AbstractCatalogReader.java
 
b/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/dao/AbstractCatalogReader.java
new file mode 100644
index 0000000..747c7df
--- /dev/null
+++ 
b/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/dao/AbstractCatalogReader.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2001-2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.logging.log4j.catalog.api.dao;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.logging.log4j.catalog.api.Attribute;
+import org.apache.logging.log4j.catalog.api.CatalogData;
+import org.apache.logging.log4j.catalog.api.CatalogReader;
+import org.apache.logging.log4j.catalog.api.Category;
+import org.apache.logging.log4j.catalog.api.Event;
+import org.apache.logging.log4j.catalog.api.Product;
+
+public abstract class AbstractCatalogReader implements CatalogReader {
+    protected CatalogData catalogData = null;
+
+    protected final Map<String, Attribute> attributes = new HashMap<>();
+
+    @Override
+    public Map<String, Attribute> getAttributes() {
+        return attributes;
+    }
+
+    @Override
+    public Attribute getAttribute(String name) {
+        return attributes.get(name);
+    }
+
+    @Override
+    public Category getCategory(String name) {
+        if (catalogData.getCategories() != null) {
+            return catalogData.getCategories().stream().filter(c -> 
c.getName().equals(name)).findFirst().orElse(null);
+        }
+        return null;
+    }
+
+
+    @Override
+    public Event getEvent(String name) {
+        if (catalogData.getEvents() != null) {
+            return catalogData.getEvents().stream().filter(e -> 
e.getName().equals(name)).findFirst().orElse(null);
+        }
+        return null;
+    }
+
+
+    @Override
+    public Product getProduct(String name) {
+        if (catalogData.getProducts() != null) {
+            return catalogData.getProducts().stream().filter(p -> 
p.getName().equals(name)).findFirst().orElse(null);
+        }
+        return null;
+    }
+
+    public String readCatalog() {
+        return null;
+    }
+
+    @Override
+    public CatalogData read() {
+        return catalogData;
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/f0884aeb/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/dao/CatalogDao.java
----------------------------------------------------------------------
diff --git 
a/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/dao/CatalogDao.java
 
b/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/dao/CatalogDao.java
new file mode 100644
index 0000000..09d1337
--- /dev/null
+++ 
b/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/dao/CatalogDao.java
@@ -0,0 +1,64 @@
+/*
+ * 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.catalog.api.dao;
+
+import java.util.Map;
+
+import org.apache.logging.log4j.catalog.api.Attribute;
+import org.apache.logging.log4j.catalog.api.CatalogData;
+import org.apache.logging.log4j.catalog.api.CatalogReader;
+import org.apache.logging.log4j.catalog.api.CatalogWriter;
+import org.apache.logging.log4j.catalog.api.Category;
+import org.apache.logging.log4j.catalog.api.Constraint;
+import org.apache.logging.log4j.catalog.api.Event;
+import org.apache.logging.log4j.catalog.api.Product;
+import org.apache.logging.log4j.catalog.api.exception.DuplicateNameException;
+import org.apache.logging.log4j.catalog.api.exception.NameNotFoundException;
+
+/**
+ * Provides access to the Catalog.
+ */
+public interface CatalogDao extends CatalogReader, CatalogWriter {
+
+    /**
+     * Return all the Attributes as a Map.
+     * @return A map of the attributes where the key is the Attribute's name.
+     */
+    Map<String, Attribute> getAttributes();
+
+    /**
+     * Retrieves an Attribute.
+     * @param name The attribute name.
+     * @return The Attribute or null if no attribute with the specified name 
exists.
+     */
+    Attribute getAttribute(String name);
+
+    /**
+     * Retrieves a Category. Modifications made to the Category may not be 
reflected if updateCategory() is
+     * not called.
+     * @param name The category name.
+     * @return The Category.
+     */
+    Category getCategory(String name);
+
+
+    Event getEvent(String name);
+
+
+    Product getProduct(String name);
+
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/f0884aeb/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/dao/ClassPathCatalogReader.java
----------------------------------------------------------------------
diff --git 
a/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/dao/ClassPathCatalogReader.java
 
b/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/dao/ClassPathCatalogReader.java
new file mode 100644
index 0000000..0548545
--- /dev/null
+++ 
b/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/dao/ClassPathCatalogReader.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2001-2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.logging.log4j.catalog.api.dao;
+
+import java.io.ByteArrayOutputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.Collection;
+import java.util.Map;
+
+import com.fasterxml.jackson.core.JsonFactory;
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.catalog.api.CatalogData;
+import org.apache.logging.log4j.util.LoaderUtil;
+
+/**
+ * Reads the catalog from the local file system.
+ */
+public class ClassPathCatalogReader extends AbstractCatalogReader {
+
+    private static final Logger LOGGER = 
LogManager.getLogger(ClassPathCatalogReader.class);
+    private static final String BASEDIR = "baseDir";
+
+    private static final String CATALOG_ATTRIBUTE_NAME = "catalogFile";
+    private static final String DEFAULT_CATALOG_FILE = "catalog.json";
+
+    private final String catalog;
+
+    public ClassPathCatalogReader(Map<String, String> attributes) throws 
IOException {
+        String catalogFile = attributes != null ?
+            attributes.getOrDefault(CATALOG_ATTRIBUTE_NAME, 
DEFAULT_CATALOG_FILE) : DEFAULT_CATALOG_FILE;
+        Collection<URL> catalogs = LoaderUtil.findResources(catalogFile);
+        URL catalogURL;
+        if (catalogs.size() == 0) {
+            LOGGER.error("No catalog named {} could be found on the class 
path", catalogFile);
+            throw new FileNotFoundException("No catalog named " + catalogFile 
+ " could be found");
+        } else if (catalogs.size() > 1) {
+            catalogURL = catalogs.stream().findFirst().get();
+            LOGGER.warn("Multiple catalogs named {} were found. Using {}", 
catalogFile, catalogURL.toString());
+        } else {
+            catalogURL = catalogs.stream().findFirst().get();
+        }
+
+        catalog = readCatalog(catalogURL);
+        JsonFactory factory = new JsonFactory();
+        factory.enable(JsonParser.Feature.ALLOW_COMMENTS);
+        ObjectMapper objectMapper = new ObjectMapper(factory);
+        catalogData = objectMapper.readValue(catalog, CatalogData.class);
+    }
+
+    private String readCatalog(URL catalogUrl) throws IOException {
+        try (InputStream is = catalogUrl.openStream()) {
+            ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            byte[] buffer = new byte[1024];
+            int length;
+            while ((length = is.read(buffer)) != -1) {
+                baos.write(buffer, 0, length);
+            }
+            return baos.toString("UTF-8");
+        }
+    }
+
+    public ClassPathCatalogReader() throws IOException {
+        this(null);
+    }
+
+    @Override
+    public String readCatalog() {
+        return catalog;
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/f0884aeb/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/dao/FileCatalogReader.java
----------------------------------------------------------------------
diff --git 
a/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/dao/FileCatalogReader.java
 
b/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/dao/FileCatalogReader.java
new file mode 100644
index 0000000..4f32d05
--- /dev/null
+++ 
b/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/dao/FileCatalogReader.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2001-2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.logging.log4j.catalog.api.dao;
+
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.Map;
+
+import com.fasterxml.jackson.core.JsonFactory;
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.catalog.api.CatalogData;
+
+/**
+ * Reads the catalog from the local file system.
+ */
+public class FileCatalogReader extends AbstractCatalogReader {
+
+    private static final Logger LOGGER = 
LogManager.getLogger(FileCatalogReader.class);
+    private static final String BASEDIR = "baseDir";
+
+    private static final String CATALOG_ATTRIBUTE_NAME = "catalogFile";
+    private static final String DEFAULT_CATALOG_FILE = 
"src/main/resources/catalog.json";
+
+    private final String catalog;
+
+    public FileCatalogReader(Map<String, String> attributes) throws 
IOException {
+        StringBuilder catalogPath = new StringBuilder();
+        String basePath = attributes.get(BASEDIR);
+        String catalogFile = attributes.getOrDefault(CATALOG_ATTRIBUTE_NAME, 
DEFAULT_CATALOG_FILE);
+        if (basePath != null) {
+            catalogPath.append(attributes.get(BASEDIR));
+            if (basePath.endsWith("/")) {
+                if (catalogFile.startsWith("/")) {
+                    catalogPath.append(catalogFile.substring(1));
+                } else {
+                    catalogPath.append(catalogFile);
+                }
+            } else {
+                if (catalogFile.startsWith("/")) {
+                    catalogPath.append(catalogFile);
+                } else {
+                    catalogPath.append("/").append(catalogFile);
+                }
+            }
+        } else if (catalogFile != null){
+            catalogPath.append(catalogFile);
+        } else {
+            LOGGER.warn("No catalogFile attribute was provided. Using {}", 
DEFAULT_CATALOG_FILE);
+            catalogPath.append(DEFAULT_CATALOG_FILE);
+        }
+        byte[] encoded = Files.readAllBytes(Paths.get(catalogPath.toString()));
+        catalog = new String(encoded, StandardCharsets.UTF_8);
+        JsonFactory factory = new JsonFactory();
+        factory.enable(JsonParser.Feature.ALLOW_COMMENTS);
+        ObjectMapper objectMapper = new ObjectMapper(factory);
+        catalogData = objectMapper.readValue(catalog, CatalogData.class);
+    }
+
+    public FileCatalogReader() throws IOException {
+        byte[] encoded = Files.readAllBytes(Paths.get(DEFAULT_CATALOG_FILE));
+        catalog = new String(encoded, StandardCharsets.UTF_8);
+        JsonFactory factory = new JsonFactory();
+        factory.enable(JsonParser.Feature.ALLOW_COMMENTS);
+        ObjectMapper objectMapper = new ObjectMapper(factory);
+        catalogData = objectMapper.readValue(catalog, CatalogData.class);
+    }
+
+    @Override
+    public String readCatalog() {
+        return catalog;
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/f0884aeb/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/dao/JsonCatalogReader.java
----------------------------------------------------------------------
diff --git 
a/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/dao/JsonCatalogReader.java
 
b/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/dao/JsonCatalogReader.java
new file mode 100644
index 0000000..d7ef00d
--- /dev/null
+++ 
b/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/dao/JsonCatalogReader.java
@@ -0,0 +1,67 @@
+/*
+ * 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.catalog.api.dao;
+
+import com.fasterxml.jackson.core.JsonFactory;
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.catalog.api.Attribute;
+import org.apache.logging.log4j.catalog.api.CatalogReader;
+
+/**
+ * Provides access to the JSON version of the catalog. This version is not 
modifiable.
+ */
+//@Component
+public class JsonCatalogReader extends AbstractCatalogReader {
+
+    private static final Logger LOGGER = 
LogManager.getLogger(JsonCatalogReader.class);
+
+    //@Autowired
+    CatalogReader catalogReader;
+
+    public CatalogReader getCatalogReader() {
+        return catalogReader;
+    }
+
+    public void setCatalogReader(CatalogReader catalogReader) {
+        this.catalogReader = catalogReader;
+    }
+
+    //@PostConstruct
+    public void init() {
+        catalogData = catalogReader.read();
+        for (Attribute attribute : catalogData.getAttributes()) {
+            attributes.put(attribute.getName(), attribute);
+        }
+    }
+
+    @Override
+    public String readCatalog() {
+        JsonFactory factory = new JsonFactory();
+        factory.enable(JsonParser.Feature.ALLOW_COMMENTS);
+        ObjectMapper mapper = new ObjectMapper(factory);
+        try {
+            return mapper.writeValueAsString(catalogData);
+        } catch (JsonProcessingException ex) {
+            LOGGER.error("Unable to serialze Catalog", ex);
+            return null;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/f0884aeb/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/exception/CatalogException.java
----------------------------------------------------------------------
diff --git 
a/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/exception/CatalogException.java
 
b/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/exception/CatalogException.java
new file mode 100644
index 0000000..b15c568
--- /dev/null
+++ 
b/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/exception/CatalogException.java
@@ -0,0 +1,41 @@
+/*
+ * 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.catalog.api.exception;
+
+/**
+ *
+ */
+public class CatalogException extends RuntimeException {
+
+    private static final long serialVersionUID = 413784416933702749L;
+
+    public CatalogException() {
+        super();
+    }
+
+    public CatalogException(String msg) {
+        super(msg);
+    }
+
+    public CatalogException(Throwable t) {
+        super(t);
+    }
+
+    public CatalogException(String msg, Throwable t) {
+        super(msg, t);
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/f0884aeb/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/exception/CatalogModificationException.java
----------------------------------------------------------------------
diff --git 
a/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/exception/CatalogModificationException.java
 
b/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/exception/CatalogModificationException.java
new file mode 100644
index 0000000..1114e2b
--- /dev/null
+++ 
b/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/exception/CatalogModificationException.java
@@ -0,0 +1,41 @@
+/*
+ * 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.catalog.api.exception;
+
+/**
+ *
+ */
+public class CatalogModificationException extends CatalogException {
+
+    private static final long serialVersionUID = 1999555060428715446L;
+
+    public CatalogModificationException() {
+        super();
+    }
+
+    public CatalogModificationException(String msg) {
+        super(msg);
+    }
+
+    public CatalogModificationException(Throwable t) {
+        super(t);
+    }
+
+    public CatalogModificationException(String msg, Throwable t) {
+        super(msg, t);
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/f0884aeb/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/exception/CatalogNotFoundException.java
----------------------------------------------------------------------
diff --git 
a/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/exception/CatalogNotFoundException.java
 
b/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/exception/CatalogNotFoundException.java
new file mode 100644
index 0000000..d0400bf
--- /dev/null
+++ 
b/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/exception/CatalogNotFoundException.java
@@ -0,0 +1,41 @@
+/*
+ * 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.catalog.api.exception;
+
+/**
+ *
+ */
+public class CatalogNotFoundException extends CatalogException {
+
+    private static final long serialVersionUID = 413784416933702749L;
+
+    public CatalogNotFoundException() {
+        super();
+    }
+
+    public CatalogNotFoundException(String msg) {
+        super(msg);
+    }
+
+    public CatalogNotFoundException(Throwable t) {
+        super(t);
+    }
+
+    public CatalogNotFoundException(String msg, Throwable t) {
+        super(msg, t);
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/f0884aeb/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/exception/CatalogReadException.java
----------------------------------------------------------------------
diff --git 
a/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/exception/CatalogReadException.java
 
b/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/exception/CatalogReadException.java
new file mode 100644
index 0000000..1b162cb
--- /dev/null
+++ 
b/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/exception/CatalogReadException.java
@@ -0,0 +1,41 @@
+/*
+ * 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.catalog.api.exception;
+
+/**
+ *
+ */
+public class CatalogReadException extends CatalogException {
+
+    private static final long serialVersionUID = -373722489224872918L;
+
+    public CatalogReadException() {
+        super();
+    }
+
+    public CatalogReadException(String msg) {
+        super(msg);
+    }
+
+    public CatalogReadException(Throwable t) {
+        super(t);
+    }
+
+    public CatalogReadException(String msg, Throwable t) {
+        super(msg, t);
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/f0884aeb/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/exception/CatalogWriteException.java
----------------------------------------------------------------------
diff --git 
a/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/exception/CatalogWriteException.java
 
b/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/exception/CatalogWriteException.java
new file mode 100644
index 0000000..4f44501
--- /dev/null
+++ 
b/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/exception/CatalogWriteException.java
@@ -0,0 +1,41 @@
+/*
+ * 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.catalog.api.exception;
+
+/**
+ *
+ */
+public class CatalogWriteException extends CatalogException {
+
+    private static final long serialVersionUID = -373722489224872918L;
+
+    public CatalogWriteException() {
+        super();
+    }
+
+    public CatalogWriteException(String msg) {
+        super(msg);
+    }
+
+    public CatalogWriteException(Throwable t) {
+        super(t);
+    }
+
+    public CatalogWriteException(String msg, Throwable t) {
+        super(msg, t);
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/f0884aeb/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/exception/ConstraintCreationException.java
----------------------------------------------------------------------
diff --git 
a/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/exception/ConstraintCreationException.java
 
b/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/exception/ConstraintCreationException.java
new file mode 100644
index 0000000..70e1607
--- /dev/null
+++ 
b/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/exception/ConstraintCreationException.java
@@ -0,0 +1,41 @@
+/*
+ * 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.catalog.api.exception;
+
+/**
+ *
+ */
+public class ConstraintCreationException extends RuntimeException {
+
+    private static final long serialVersionUID = 2142398619256674767L;
+
+    public ConstraintCreationException() {
+        super();
+    }
+
+    public ConstraintCreationException(String msg) {
+        super(msg);
+    }
+
+    public ConstraintCreationException(Throwable t) {
+        super(t);
+    }
+
+    public ConstraintCreationException(String msg, Throwable t) {
+        super(msg, t);
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/f0884aeb/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/exception/ConstraintValidationException.java
----------------------------------------------------------------------
diff --git 
a/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/exception/ConstraintValidationException.java
 
b/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/exception/ConstraintValidationException.java
new file mode 100644
index 0000000..b65b5bd
--- /dev/null
+++ 
b/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/exception/ConstraintValidationException.java
@@ -0,0 +1,41 @@
+/*
+ * 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.catalog.api.exception;
+
+/**
+ *
+ */
+public class ConstraintValidationException extends RuntimeException {
+
+    private static final long serialVersionUID = 2142398619256674767L;
+
+    public ConstraintValidationException() {
+        super();
+    }
+
+    public ConstraintValidationException(String msg) {
+        super(msg);
+    }
+
+    public ConstraintValidationException(Throwable t) {
+        super(t);
+    }
+
+    public ConstraintValidationException(String msg, Throwable t) {
+        super(msg, t);
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/f0884aeb/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/exception/DuplicateNameException.java
----------------------------------------------------------------------
diff --git 
a/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/exception/DuplicateNameException.java
 
b/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/exception/DuplicateNameException.java
new file mode 100644
index 0000000..e8a8e92
--- /dev/null
+++ 
b/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/exception/DuplicateNameException.java
@@ -0,0 +1,41 @@
+/*
+ * 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.catalog.api.exception;
+
+/**
+ *
+ */
+public class DuplicateNameException extends RuntimeException {
+
+    private static final long serialVersionUID = 1031387508145563656L;
+
+    public DuplicateNameException() {
+        super();
+    }
+
+    public DuplicateNameException(String msg) {
+        super(msg);
+    }
+
+    public DuplicateNameException(Throwable t) {
+        super(t);
+    }
+
+    public DuplicateNameException(String msg, Throwable t) {
+        super(msg, t);
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/f0884aeb/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/exception/InvalidEnvironmentException.java
----------------------------------------------------------------------
diff --git 
a/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/exception/InvalidEnvironmentException.java
 
b/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/exception/InvalidEnvironmentException.java
new file mode 100644
index 0000000..0135015
--- /dev/null
+++ 
b/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/exception/InvalidEnvironmentException.java
@@ -0,0 +1,41 @@
+/*
+ * 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.catalog.api.exception;
+
+/**
+ *
+ */
+public class InvalidEnvironmentException extends RuntimeException {
+
+    private static final long serialVersionUID = 5430017753467095045L;
+
+    public InvalidEnvironmentException() {
+        super();
+    }
+
+    public InvalidEnvironmentException(String msg) {
+        super(msg);
+    }
+
+    public InvalidEnvironmentException(Throwable t) {
+        super(t);
+    }
+
+    public InvalidEnvironmentException(String msg, Throwable t) {
+        super(msg, t);
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/f0884aeb/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/exception/InvalidSiteException.java
----------------------------------------------------------------------
diff --git 
a/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/exception/InvalidSiteException.java
 
b/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/exception/InvalidSiteException.java
new file mode 100644
index 0000000..17296d1
--- /dev/null
+++ 
b/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/exception/InvalidSiteException.java
@@ -0,0 +1,41 @@
+/*
+ * 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.catalog.api.exception;
+
+/**
+ *
+ */
+public class InvalidSiteException extends RuntimeException {
+
+    private static final long serialVersionUID = -705205114100982089L;
+
+    public InvalidSiteException() {
+        super();
+    }
+
+    public InvalidSiteException(String msg) {
+        super(msg);
+    }
+
+    public InvalidSiteException(Throwable t) {
+        super(t);
+    }
+
+    public InvalidSiteException(String msg, Throwable t) {
+        super(msg, t);
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/f0884aeb/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/exception/NameNotFoundException.java
----------------------------------------------------------------------
diff --git 
a/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/exception/NameNotFoundException.java
 
b/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/exception/NameNotFoundException.java
new file mode 100644
index 0000000..85a390a
--- /dev/null
+++ 
b/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/exception/NameNotFoundException.java
@@ -0,0 +1,41 @@
+/*
+ * 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.catalog.api.exception;
+
+/**
+ *
+ */
+public class NameNotFoundException extends RuntimeException {
+
+    private static final long serialVersionUID = -792734057485544367L;
+
+    public NameNotFoundException() {
+        super();
+    }
+
+    public NameNotFoundException(String msg) {
+        super(msg);
+    }
+
+    public NameNotFoundException(Throwable t) {
+        super(t);
+    }
+
+    public NameNotFoundException(String msg, Throwable t) {
+        super(msg, t);
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/f0884aeb/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/package-info.java
----------------------------------------------------------------------
diff --git 
a/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/package-info.java
 
b/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/package-info.java
new file mode 100644
index 0000000..6927b9b
--- /dev/null
+++ 
b/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/package-info.java
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2001-2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * Catalog API.
+ */
+package org.apache.logging.log4j.catalog.api;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/f0884aeb/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/plugins/CaseInsensitiveEnumConstraint.java
----------------------------------------------------------------------
diff --git 
a/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/plugins/CaseInsensitiveEnumConstraint.java
 
b/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/plugins/CaseInsensitiveEnumConstraint.java
new file mode 100644
index 0000000..67e50bf
--- /dev/null
+++ 
b/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/plugins/CaseInsensitiveEnumConstraint.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2001-2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.logging.log4j.catalog.api.plugins;
+
+import java.util.Arrays;
+
+import org.apache.logging.log4j.catalog.api.ConstraintType;
+import org.apache.logging.log4j.core.config.plugins.Plugin;
+import static 
org.apache.logging.log4j.catalog.api.util.StringUtils.appendNewline;
+import static org.apache.logging.log4j.catalog.api.util.StringUtils.isBlank;
+
+/**
+ * Performs a case insensitive comparison to verify the value is in the list 
of acceptable values.
+ */
+@Plugin(name = "anyCaseEnum", category = ConstraintType.CATEGORY)
+public class CaseInsensitiveEnumConstraint implements ConstraintType {
+
+    @Override
+    public void validate(boolean isRequestContext, String name, String value, 
String enums, StringBuilder error) {
+        if (!isBlank(enums) && !isBlank(value)) {
+            boolean result = 
Arrays.stream(enums.trim().split("\\s*,\\s*")).anyMatch(value::equalsIgnoreCase);
+            if (!result) {
+                appendNewline(error);
+                if (isRequestContext) {
+                    error.append("ThreadContext key ");
+                }
+                error.append(name).append(" does not match one of the values: 
").append(enums);
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/f0884aeb/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/plugins/ConstraintPlugins.java
----------------------------------------------------------------------
diff --git 
a/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/plugins/ConstraintPlugins.java
 
b/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/plugins/ConstraintPlugins.java
new file mode 100644
index 0000000..b2e587f
--- /dev/null
+++ 
b/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/plugins/ConstraintPlugins.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright 2001-2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.logging.log4j.catalog.api.plugins;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.catalog.api.ConstraintType;
+import 
org.apache.logging.log4j.catalog.api.exception.ConstraintCreationException;
+import org.apache.logging.log4j.core.config.plugins.util.PluginManager;
+import org.apache.logging.log4j.core.config.plugins.util.PluginType;
+import org.apache.logging.log4j.core.util.ReflectionUtil;
+
+/**
+ *
+ */
+
+public class ConstraintPlugins {
+
+    private static Logger LOGGER = 
LogManager.getLogger(ConstraintPlugins.class);
+
+    private static Map<String, ConstraintType> constraintMap = new HashMap<>();
+
+    private static volatile ConstraintPlugins instance = null;
+
+    private static final Object LOCK = new Object();
+
+    public static ConstraintPlugins getInstance() {
+        if (instance == null) {
+            synchronized(LOCK) {
+                if (instance == null) {
+                    instance = new ConstraintPlugins();
+                }
+            }
+        }
+        return instance;
+    }
+
+    private ConstraintPlugins() {
+
+        final PluginManager manager = new 
PluginManager(ConstraintType.CATEGORY);
+        if (LOGGER instanceof org.apache.logging.log4j.core.Logger) {
+            List<String> pluginPackages =
+                    ((org.apache.logging.log4j.core.Logger) 
LOGGER).getContext().getConfiguration().getPluginPackages();
+            manager.collectPlugins(pluginPackages);
+        } else {
+            manager.collectPlugins();
+        }
+        final Map<String, PluginType<?>> plugins = manager.getPlugins();
+        for (Map.Entry<String, PluginType<?>> entry : plugins.entrySet()) {
+            try {
+                final Class<? extends ConstraintType> clazz = 
entry.getValue().getPluginClass().asSubclass(ConstraintType.class);
+                ConstraintType constraintType = 
ReflectionUtil.instantiate(clazz);
+                constraintMap.put(entry.getKey(), constraintType);
+            } catch (final Throwable t) {
+                throw new ConstraintCreationException("Unable to create 
constraint for " + entry.getKey(), t);
+            }
+        }
+    }
+
+    public void validateConstraint(boolean isRequestContext, String 
constraint, String name,
+                                          String value, String 
constraintValue, StringBuilder errors) {
+        ConstraintType constraintType = 
constraintMap.get(constraint.toLowerCase(Locale.US));
+        if (constraintType == null) {
+            if (errors.length() > 0) {
+                errors.append("\n");
+            }
+            errors.append("Unable to locate constraint type 
").append(constraint);
+            if (isRequestContext) {
+                errors.append(" for ThreadContext key ");
+            } else {
+                errors.append(" for key ");
+            }
+            errors.append(name);
+            return;
+        }
+        constraintType.validate(isRequestContext, name, value, 
constraintValue, errors);
+    }
+
+    public ConstraintType findByName(String name) {
+        return constraintMap.get(name.toLowerCase(Locale.US));
+    }
+
+    public Map<String, ConstraintType> getConstraintMap() {
+        return Collections.unmodifiableMap(constraintMap);
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/f0884aeb/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/plugins/ConstraintTypeDeserializer.java
----------------------------------------------------------------------
diff --git 
a/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/plugins/ConstraintTypeDeserializer.java
 
b/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/plugins/ConstraintTypeDeserializer.java
new file mode 100644
index 0000000..56e70a7
--- /dev/null
+++ 
b/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/plugins/ConstraintTypeDeserializer.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2001-2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.logging.log4j.catalog.api.plugins;
+
+import java.io.IOException;
+
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.DeserializationContext;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
+import org.apache.logging.log4j.catalog.api.ConstraintType;
+import org.apache.logging.log4j.catalog.api.exception.NameNotFoundException;
+
+/**
+ *
+ */
+public class ConstraintTypeDeserializer extends 
StdDeserializer<ConstraintType> {
+
+    ConstraintPlugins plugins = ConstraintPlugins.getInstance();
+
+    public ConstraintTypeDeserializer() {
+        this(null);
+    }
+
+    public ConstraintTypeDeserializer(Class<?> vc) {
+        super(vc);
+    }
+
+    @Override
+    public ConstraintType deserialize(JsonParser jp, DeserializationContext 
ctxt)
+            throws IOException, JsonProcessingException {
+        JsonNode node = jp.getCodec().readTree(jp);
+        String name = node.get("name").textValue();
+        ConstraintType type = plugins.findByName(name);
+        if (type == null) {
+            throw new NameNotFoundException("Unable to locate plugin for 
constraint type " + name);
+        }
+        return type;
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/f0884aeb/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/plugins/ConstraintTypeSerializer.java
----------------------------------------------------------------------
diff --git 
a/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/plugins/ConstraintTypeSerializer.java
 
b/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/plugins/ConstraintTypeSerializer.java
new file mode 100644
index 0000000..95ef645
--- /dev/null
+++ 
b/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/plugins/ConstraintTypeSerializer.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2001-2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.logging.log4j.catalog.api.plugins;
+
+import java.io.IOException;
+
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.DeserializationContext;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.SerializerProvider;
+import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
+import com.fasterxml.jackson.databind.ser.std.StdSerializer;
+import org.apache.logging.log4j.catalog.api.ConstraintType;
+import org.apache.logging.log4j.catalog.api.exception.NameNotFoundException;
+
+/**
+ *
+ */
+public class ConstraintTypeSerializer extends StdSerializer<ConstraintType> {
+
+    public ConstraintTypeSerializer() {
+        this(null);
+    }
+
+    public ConstraintTypeSerializer(Class<ConstraintType> vc) {
+        super(vc);
+    }
+
+    @Override
+    public void serialize(ConstraintType constraintType, JsonGenerator 
jsonGenerator,
+                          SerializerProvider serializerProvider) throws 
IOException {
+        jsonGenerator.writeStartObject();
+        jsonGenerator.writeStringField("name", constraintType.getName());
+        jsonGenerator.writeEndObject();
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/f0884aeb/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/plugins/EnumConstraint.java
----------------------------------------------------------------------
diff --git 
a/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/plugins/EnumConstraint.java
 
b/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/plugins/EnumConstraint.java
new file mode 100644
index 0000000..929c0a8
--- /dev/null
+++ 
b/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/plugins/EnumConstraint.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2001-2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.logging.log4j.catalog.api.plugins;
+
+import java.util.Arrays;
+
+import org.apache.logging.log4j.catalog.api.ConstraintType;
+import org.apache.logging.log4j.core.config.plugins.Plugin;
+import static 
org.apache.logging.log4j.catalog.api.util.StringUtils.appendNewline;
+import static org.apache.logging.log4j.catalog.api.util.StringUtils.isBlank;
+
+/**
+ * Performs a comparison to verify the value is in the list of acceptable 
values.
+ */
+@Plugin(name = "enum", category = ConstraintType.CATEGORY)
+public class EnumConstraint implements ConstraintType {
+
+    @Override
+    public void validate(boolean isRequestContext, String name, String value, 
String enums, StringBuilder error) {
+        if (!isBlank(enums) && !isBlank(value)) {
+            boolean result = 
Arrays.stream(enums.trim().split("\\s*,\\s*")).anyMatch(value::equals);
+            if (!result) {
+                appendNewline(error);
+                if (isRequestContext) {
+                    error.append("ThreadContext key ");
+                }
+                error.append(name).append(" does not match one of the values: 
").append(enums);
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/f0884aeb/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/plugins/MaxLengthConstraint.java
----------------------------------------------------------------------
diff --git 
a/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/plugins/MaxLengthConstraint.java
 
b/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/plugins/MaxLengthConstraint.java
new file mode 100644
index 0000000..430fc7a
--- /dev/null
+++ 
b/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/plugins/MaxLengthConstraint.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2001-2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.logging.log4j.catalog.api.plugins;
+
+import org.apache.logging.log4j.catalog.api.ConstraintType;
+import org.apache.logging.log4j.core.config.plugins.Plugin;
+import static org.apache.logging.log4j.catalog.api.util.StringUtils.isBlank;
+import static 
org.apache.logging.log4j.catalog.api.util.StringUtils.appendNewline;
+
+/**
+ *
+ */
+@Plugin(name = "maxLength", category = ConstraintType.CATEGORY)
+public class MaxLengthConstraint implements ConstraintType {
+
+    @Override
+    public void validate(boolean isRequestContext, String name, String value, 
String maxLength, StringBuilder error) {
+        if (isBlank(maxLength)) {
+            appendNewline(error);
+            if (isRequestContext) {
+                error.append("ThreadContext key ");
+            }
+            error.append(name).append(" has no maximum length value defined");
+            return;
+        }
+        if (!isBlank(value)) {
+            try {
+                int maxlen = Integer.parseInt(maxLength);
+                if (value.length() > maxlen) {
+                    appendNewline(error);
+                    if (isRequestContext) {
+                        error.append("ThreadContext key ");
+                    }
+                    error.append(name).append(" exceeds 
").append(maxLength).append(" characters.");
+                }
+            } catch (Exception ex) {
+                appendNewline(error);
+                if (isRequestContext) {
+                    error.append("ThreadContext key ");
+                }
+                error.append(name).append(" encountered an error trying to 
determine the maximum length value: ").append(ex.getMessage());
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/f0884aeb/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/plugins/MaxValueConstraint.java
----------------------------------------------------------------------
diff --git 
a/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/plugins/MaxValueConstraint.java
 
b/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/plugins/MaxValueConstraint.java
new file mode 100644
index 0000000..dc7b807
--- /dev/null
+++ 
b/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/plugins/MaxValueConstraint.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2001-2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.logging.log4j.catalog.api.plugins;
+
+import java.math.BigDecimal;
+
+import org.apache.logging.log4j.catalog.api.ConstraintType;
+import org.apache.logging.log4j.core.config.plugins.Plugin;
+import static org.apache.logging.log4j.catalog.api.util.StringUtils.isBlank;
+import static 
org.apache.logging.log4j.catalog.api.util.StringUtils.appendNewline;
+
+/**
+ *
+ */
+@Plugin(name = "maxValue", category = ConstraintType.CATEGORY)
+public class MaxValueConstraint implements ConstraintType {
+
+    @Override
+    public void validate(boolean isRequestContext, String name, String value, 
String maxValue, StringBuilder error) {
+        if (isBlank(maxValue)) {
+            appendNewline(error);
+            if (isRequestContext) {
+                error.append("ThreadContext key ");
+            }
+            error.append(name).append(" has no value for the minimum value 
defined");
+            return;
+        }
+        if (!isBlank(value)) {
+            try {
+                BigDecimal minVal = new BigDecimal(maxValue);
+                BigDecimal val = new BigDecimal(value);
+                if (val.compareTo(minVal) > 0) {
+                    appendNewline(error);
+                    if (isRequestContext) {
+                        error.append("ThreadContext key ");
+                    }
+                    error.append(name).append(" is less than 
").append(maxValue);
+                }
+            } catch (Exception ex) {
+                appendNewline(error);
+                if (isRequestContext) {
+                    error.append("ThreadContext key ");
+                }
+                error.append(name).append(" encountered an error trying to 
determine the minimum value: ").append(ex.getMessage());
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/f0884aeb/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/plugins/MinLengthConstraint.java
----------------------------------------------------------------------
diff --git 
a/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/plugins/MinLengthConstraint.java
 
b/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/plugins/MinLengthConstraint.java
new file mode 100644
index 0000000..271663a
--- /dev/null
+++ 
b/log4j-catalog/log4j-catalog-api/src/main/java/org/apache/logging/log4j/catalog/api/plugins/MinLengthConstraint.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2001-2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.logging.log4j.catalog.api.plugins;
+
+import org.apache.logging.log4j.catalog.api.ConstraintType;
+import org.apache.logging.log4j.core.config.plugins.Plugin;
+import static org.apache.logging.log4j.catalog.api.util.StringUtils.isBlank;
+import static 
org.apache.logging.log4j.catalog.api.util.StringUtils.appendNewline;
+
+/**
+ *
+ */
+@Plugin(name = "minLength", category = ConstraintType.CATEGORY)
+public class MinLengthConstraint implements ConstraintType {
+
+    @Override
+    public void validate(boolean isRequestContext, String name, String value, 
String minLength, StringBuilder error) {
+        if (isBlank(minLength)) {
+            appendNewline(error);
+            if (isRequestContext) {
+                error.append("ThreadContext key ");
+            }
+            error.append(name).append(" has no minimum length value defined");
+            return;
+        }
+        if (!isBlank(value)) {
+            try {
+                int minlen = Integer.parseInt(minLength);
+                if (value.length() < minlen) {
+                    appendNewline(error);
+                    if (isRequestContext) {
+                        error.append("ThreadContext key ");
+                    }
+                    error.append(name).append(" does not contain 
").append(minLength).append(" characters.");
+                }
+            } catch (Exception ex) {
+                appendNewline(error);
+                if (isRequestContext) {
+                    error.append("ThreadContext key ");
+                }
+                error.append(name).append(" encountered an error trying to 
determine the minimum length value: ").append(ex.getMessage());
+            }
+        }
+    }
+}

Reply via email to