From 470c3ddb9159d6e0b0a9d31af28e8ed46d570db6 Mon Sep 17 00:00:00 2001
From: Fabio Pistolesi <fabio.pistolesi@forgerock.com>
Date: Tue, 27 Sep 2016 17:03:29 +0000
Subject: [PATCH] OPENDJ-3313 Add Json handler log publisher in dsconfig

---
 opendj-server-legacy/src/messages/org/opends/messages/logger.properties                                                              |   11 
 opendj-server-legacy/src/main/java/org/opends/server/loggers/CommonAudit.java                                                        |  374 ++++++++++++++++++++----------
 opendj-maven-plugin/src/main/resources/config/xml/org/forgerock/opendj/server/config/JsonFileHTTPAccessLogPublisherConfiguration.xml |  124 ++++++++++
 opendj-server-legacy/src/main/java/org/opends/server/loggers/JsonFileAccessLogPublisher.java                                         |   52 ++++
 opendj-server-legacy/resource/schema/02-config.ldif                                                                                  |   17 +
 opendj-maven-plugin/src/main/resources/config/xml/org/forgerock/opendj/server/config/JsonFileAccessLogPublisherConfiguration.xml     |  142 +++++++++++
 6 files changed, 585 insertions(+), 135 deletions(-)

diff --git a/opendj-maven-plugin/src/main/resources/config/xml/org/forgerock/opendj/server/config/JsonFileAccessLogPublisherConfiguration.xml b/opendj-maven-plugin/src/main/resources/config/xml/org/forgerock/opendj/server/config/JsonFileAccessLogPublisherConfiguration.xml
new file mode 100644
index 0000000..e146abb
--- /dev/null
+++ b/opendj-maven-plugin/src/main/resources/config/xml/org/forgerock/opendj/server/config/JsonFileAccessLogPublisherConfiguration.xml
@@ -0,0 +1,142 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  The contents of this file are subject to the terms of the Common Development and
+  Distribution License (the License). You may not use this file except in compliance with the
+  License.
+
+  You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
+  specific language governing permission and limitations under the License.
+
+  When distributing Covered Software, include this CDDL Header Notice in each file and include
+  the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
+  Header, with the fields enclosed by brackets [] replaced by your own identifying
+  information: "Portions Copyright [year] [name of copyright owner]".
+
+  Copyright 2016 ForgeRock AS.
+  -->
+<adm:managed-object name="json-file-access-log-publisher"
+  plural-name="json-file-access-log-publishers"
+  package="org.forgerock.opendj.server.config" extends="access-log-publisher"
+  xmlns:adm="http://opendj.forgerock.org/admin"
+  xmlns:ldap="http://opendj.forgerock.org/admin-ldap">
+  <adm:synopsis>
+    <adm:user-friendly-plural-name />
+    Publish access messages to Json files.
+  </adm:synopsis>
+  <adm:profile name="ldap">
+    <ldap:object-class>
+      <ldap:name>ds-cfg-json-file-access-log-publisher</ldap:name>
+      <ldap:superior>ds-cfg-access-log-publisher</ldap:superior>
+    </ldap:object-class>
+  </adm:profile>
+  <adm:property-override name="java-class" advanced="true">
+    <adm:default-behavior>
+      <adm:defined>
+        <adm:value>
+          org.opends.server.loggers.JsonFileAccessLogPublisher
+        </adm:value>
+      </adm:defined>
+    </adm:default-behavior>
+  </adm:property-override>
+  <adm:property name="log-directory" mandatory="true">
+    <adm:synopsis>
+      The directory to use for the log files generated by the
+      <adm:user-friendly-name />.
+      The path to the directory is relative to the server root.
+    </adm:synopsis>
+    <adm:requires-admin-action>
+      <adm:component-restart />
+    </adm:requires-admin-action>
+    <adm:default-behavior>
+      <adm:defined>
+        <adm:value>logs</adm:value>
+      </adm:defined>
+    </adm:default-behavior>
+    <adm:syntax>
+     <adm:string>
+       <adm:pattern>
+        <adm:regex>.*</adm:regex>
+        <adm:usage>DIRECTORY</adm:usage>
+          <adm:synopsis>
+            A path to an existing directory that is readable and writable by the server.
+          </adm:synopsis>
+        </adm:pattern>
+      </adm:string>
+    </adm:syntax>
+    <adm:profile name="ldap">
+      <ldap:attribute>
+        <ldap:name>ds-cfg-log-directory</ldap:name>
+      </ldap:attribute>
+    </adm:profile>
+  </adm:property>
+  <adm:property name="rotation-policy" multi-valued="true">
+    <adm:synopsis>
+      The rotation policy to use for the
+      <adm:user-friendly-name />.
+    </adm:synopsis>
+    <adm:description>
+      When multiple policies are used, rotation will occur if any
+      policy's conditions are met.
+    </adm:description>
+    <adm:default-behavior>
+      <adm:alias>
+        <adm:synopsis>
+          No rotation policy is used and log rotation will not occur.
+        </adm:synopsis>
+      </adm:alias>
+    </adm:default-behavior>
+    <adm:syntax>
+      <adm:aggregation parent-path="/"
+        relation-name="log-rotation-policy" />
+    </adm:syntax>
+    <adm:profile name="ldap">
+      <ldap:attribute>
+        <ldap:name>ds-cfg-rotation-policy</ldap:name>
+      </ldap:attribute>
+    </adm:profile>
+  </adm:property>
+  <adm:property name="retention-policy" multi-valued="true">
+    <adm:synopsis>
+      The retention policy to use for the
+      <adm:user-friendly-name />.
+    </adm:synopsis>
+    <adm:description>
+      When multiple policies are used, log files are cleaned when
+      any of the policy's conditions are met.
+    </adm:description>
+    <adm:default-behavior>
+      <adm:alias>
+        <adm:synopsis>
+          No retention policy is used and log files are never cleaned.
+        </adm:synopsis>
+      </adm:alias>
+    </adm:default-behavior>
+    <adm:syntax>
+      <adm:aggregation parent-path="/"
+        relation-name="log-retention-policy" />
+    </adm:syntax>
+    <adm:profile name="ldap">
+      <ldap:attribute>
+        <ldap:name>ds-cfg-retention-policy</ldap:name>
+      </ldap:attribute>
+    </adm:profile>
+  </adm:property>
+  <adm:property name="log-control-oids">
+    <adm:synopsis>
+      Specifies whether control OIDs will be included in operation log records.
+    </adm:synopsis>
+    <adm:default-behavior>
+      <adm:defined>
+        <adm:value>false</adm:value>
+      </adm:defined>
+    </adm:default-behavior>
+    <adm:syntax>
+      <adm:boolean />
+    </adm:syntax>
+    <adm:profile name="ldap">
+      <ldap:attribute>
+        <ldap:name>ds-cfg-log-control-oids</ldap:name>
+      </ldap:attribute>
+    </adm:profile>
+  </adm:property>
+</adm:managed-object>
diff --git a/opendj-maven-plugin/src/main/resources/config/xml/org/forgerock/opendj/server/config/JsonFileHTTPAccessLogPublisherConfiguration.xml b/opendj-maven-plugin/src/main/resources/config/xml/org/forgerock/opendj/server/config/JsonFileHTTPAccessLogPublisherConfiguration.xml
new file mode 100644
index 0000000..223cac2
--- /dev/null
+++ b/opendj-maven-plugin/src/main/resources/config/xml/org/forgerock/opendj/server/config/JsonFileHTTPAccessLogPublisherConfiguration.xml
@@ -0,0 +1,124 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  The contents of this file are subject to the terms of the Common Development and
+  Distribution License (the License). You may not use this file except in compliance with the
+  License.
+
+  You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
+  specific language governing permission and limitations under the License.
+
+  When distributing Covered Software, include this CDDL Header Notice in each file and include
+  the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
+  Header, with the fields enclosed by brackets [] replaced by your own identifying
+  information: "Portions Copyright [year] [name of copyright owner]".
+
+  Copyright 2016 ForgeRock AS.
+  -->
+<adm:managed-object name="json-file-http-access-log-publisher"
+  plural-name="json-file-http-access-log-publishers"
+  package="org.forgerock.opendj.server.config" extends="http-access-log-publisher"
+  xmlns:adm="http://opendj.forgerock.org/admin"
+  xmlns:ldap="http://opendj.forgerock.org/admin-ldap">
+  <adm:synopsis>
+    <adm:user-friendly-plural-name />
+    Publish access messages to Json files.
+  </adm:synopsis>
+  <adm:profile name="ldap">
+    <ldap:object-class>
+      <ldap:name>ds-cfg-json-file-http-access-log-publisher</ldap:name>
+      <ldap:superior>ds-cfg-http-access-log-publisher</ldap:superior>
+    </ldap:object-class>
+  </adm:profile>
+  <adm:property-override name="java-class" advanced="true">
+    <adm:default-behavior>
+      <adm:defined>
+        <adm:value>
+          org.opends.server.loggers.CommonAuditHTTPAccessLogPublisher
+        </adm:value>
+      </adm:defined>
+    </adm:default-behavior>
+  </adm:property-override>
+  <adm:property name="log-directory" mandatory="true">
+    <adm:synopsis>
+      The directory to use for the log files generated by the
+      <adm:user-friendly-name />.
+      The path to the directory is relative to the server root.
+    </adm:synopsis>
+    <adm:requires-admin-action>
+      <adm:component-restart />
+    </adm:requires-admin-action>
+    <adm:default-behavior>
+      <adm:defined>
+        <adm:value>logs</adm:value>
+      </adm:defined>
+    </adm:default-behavior>
+    <adm:syntax>
+     <adm:string>
+       <adm:pattern>
+        <adm:regex>.*</adm:regex>
+        <adm:usage>DIRECTORY</adm:usage>
+          <adm:synopsis>
+            A path to an existing directory that is readable and writable by the server.
+          </adm:synopsis>
+        </adm:pattern>
+      </adm:string>
+    </adm:syntax>
+    <adm:profile name="ldap">
+      <ldap:attribute>
+        <ldap:name>ds-cfg-log-directory</ldap:name>
+      </ldap:attribute>
+    </adm:profile>
+  </adm:property>
+  <adm:property name="rotation-policy" multi-valued="true">
+    <adm:synopsis>
+      The rotation policy to use for the
+      <adm:user-friendly-name />.
+    </adm:synopsis>
+    <adm:description>
+      When multiple policies are used, rotation will occur if any
+      policy's conditions are met.
+    </adm:description>
+    <adm:default-behavior>
+      <adm:alias>
+        <adm:synopsis>
+          No rotation policy is used and log rotation will not occur.
+        </adm:synopsis>
+      </adm:alias>
+    </adm:default-behavior>
+    <adm:syntax>
+      <adm:aggregation parent-path="/"
+        relation-name="log-rotation-policy" />
+    </adm:syntax>
+    <adm:profile name="ldap">
+      <ldap:attribute>
+        <ldap:name>ds-cfg-rotation-policy</ldap:name>
+      </ldap:attribute>
+    </adm:profile>
+  </adm:property>
+  <adm:property name="retention-policy" multi-valued="true">
+    <adm:synopsis>
+      The retention policy to use for the
+      <adm:user-friendly-name />.
+    </adm:synopsis>
+    <adm:description>
+      When multiple policies are used, log files are cleaned when
+      any of the policy's conditions are met.
+    </adm:description>
+    <adm:default-behavior>
+      <adm:alias>
+        <adm:synopsis>
+          No retention policy is used and log files are never cleaned.
+        </adm:synopsis>
+      </adm:alias>
+    </adm:default-behavior>
+    <adm:syntax>
+      <adm:aggregation parent-path="/"
+        relation-name="log-retention-policy" />
+    </adm:syntax>
+    <adm:profile name="ldap">
+      <ldap:attribute>
+        <ldap:name>ds-cfg-retention-policy</ldap:name>
+      </ldap:attribute>
+    </adm:profile>
+  </adm:property>
+</adm:managed-object>
diff --git a/opendj-server-legacy/resource/schema/02-config.ldif b/opendj-server-legacy/resource/schema/02-config.ldif
index e31b684..2d47767 100644
--- a/opendj-server-legacy/resource/schema/02-config.ldif
+++ b/opendj-server-legacy/resource/schema/02-config.ldif
@@ -6014,3 +6014,20 @@
   SUP ds-cfg-http-endpoint
   STRUCTURAL
   X-ORIGIN 'OpenDJ Directory Server' )
+objectClasses: ( 1.3.6.1.4.1.36733.2.1.2.45
+  NAME 'ds-cfg-json-file-access-log-publisher'
+  SUP ds-cfg-access-log-publisher
+  STRUCTURAL
+  MUST ( ds-cfg-log-directory )
+  MAY ( ds-cfg-log-control-oids $
+        ds-cfg-rotation-policy $
+        ds-cfg-retention-policy )
+  X-ORIGIN 'OpenDJ Directory Server' )
+objectClasses: ( 1.3.6.1.4.1.36733.2.1.2.46
+  NAME 'ds-cfg-json-file-http-access-log-publisher'
+  SUP ds-cfg-http-access-log-publisher
+  STRUCTURAL
+  MUST ( ds-cfg-log-directory )
+  MAY ( ds-cfg-rotation-policy $
+        ds-cfg-retention-policy )
+  X-ORIGIN 'OpenDJ Directory Server' )
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/loggers/CommonAudit.java b/opendj-server-legacy/src/main/java/org/opends/server/loggers/CommonAudit.java
index 23659b4..fe326f4 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/loggers/CommonAudit.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/loggers/CommonAudit.java
@@ -48,6 +48,7 @@
 import org.forgerock.audit.AuditServiceProxy;
 import org.forgerock.audit.DependencyProvider;
 import org.forgerock.audit.events.EventTopicsMetaData;
+import org.forgerock.audit.events.handlers.FileBasedEventHandlerConfiguration;
 import org.forgerock.audit.events.handlers.FileBasedEventHandlerConfiguration.FileRetention;
 import org.forgerock.audit.events.handlers.FileBasedEventHandlerConfiguration.FileRotation;
 import org.forgerock.audit.filter.FilterPolicy;
@@ -56,6 +57,8 @@
 import org.forgerock.audit.handlers.csv.CsvAuditEventHandlerConfiguration.CsvFormatting;
 import org.forgerock.audit.handlers.csv.CsvAuditEventHandlerConfiguration.CsvSecurity;
 import org.forgerock.audit.handlers.csv.CsvAuditEventHandlerConfiguration.EventBufferingConfiguration;
+import org.forgerock.audit.handlers.json.JsonAuditEventHandler;
+import org.forgerock.audit.handlers.json.JsonAuditEventHandlerConfiguration;
 import org.forgerock.audit.json.AuditJsonConfig;
 import org.forgerock.i18n.slf4j.LocalizedLogger;
 import org.forgerock.json.JsonValue;
@@ -63,7 +66,6 @@
 import org.forgerock.opendj.config.ConfigurationFramework;
 import org.forgerock.opendj.config.server.ConfigException;
 import org.forgerock.opendj.ldap.DN;
-import org.forgerock.opendj.ldap.schema.ObjectClass;
 import org.forgerock.opendj.server.config.server.CsvFileAccessLogPublisherCfg;
 import org.forgerock.opendj.server.config.server.CsvFileHTTPAccessLogPublisherCfg;
 import org.forgerock.opendj.server.config.server.ExternalAccessLogPublisherCfg;
@@ -71,15 +73,15 @@
 import org.forgerock.opendj.server.config.server.FileCountLogRetentionPolicyCfg;
 import org.forgerock.opendj.server.config.server.FixedTimeLogRotationPolicyCfg;
 import org.forgerock.opendj.server.config.server.FreeDiskSpaceLogRetentionPolicyCfg;
+import org.forgerock.opendj.server.config.server.JsonFileAccessLogPublisherCfg;
+import org.forgerock.opendj.server.config.server.JsonFileHTTPAccessLogPublisherCfg;
 import org.forgerock.opendj.server.config.server.LogPublisherCfg;
 import org.forgerock.opendj.server.config.server.LogRetentionPolicyCfg;
 import org.forgerock.opendj.server.config.server.LogRotationPolicyCfg;
 import org.forgerock.opendj.server.config.server.SizeLimitLogRetentionPolicyCfg;
 import org.forgerock.opendj.server.config.server.SizeLimitLogRotationPolicyCfg;
 import org.forgerock.opendj.server.config.server.TimeLimitLogRotationPolicyCfg;
-import org.opends.server.core.DirectoryServer;
 import org.opends.server.core.ServerContext;
-import org.opends.server.types.Entry;
 import org.opends.server.util.StaticUtils;
 
 /**
@@ -191,7 +193,7 @@
    */
   public RequestHandler getRequestHandler(LogPublisherCfg config) throws ConfigException
   {
-    if (new PublisherConfig(serverContext, config).isHttpAccessLog())
+    if (new PublisherConfig(serverContext, config).logType.isHttp())
     {
       return httpAccessAuditService;
     }
@@ -215,7 +217,7 @@
       {
         final PublisherConfig newPublisher = new PublisherConfig(serverContext, newConfig);
         String normalizedName = getConfigNormalizedName(newConfig);
-        if (newPublisher.isHttpAccessLog())
+        if (newPublisher.logType.isHttp())
         {
           // if an old version exists, it is replaced by the new one
           httpAccessPublishers.put(normalizedName, newPublisher);
@@ -397,7 +399,7 @@
   /**
    * Build filter policies at the AuditService level to prevent logging of the headers for HTTP requests.
    * <p>
-   * HTTP Headers may contains authentication information.
+   * HTTP Headers may contain authentication information.
    */
   private Map<String, FilterPolicy> getFilterPoliciesToPreventHttpHeadersLogging()
   {
@@ -410,16 +412,18 @@
 
   private void addHandlerToBuilder(PublisherConfig publisher, AuditServiceBuilder builder) throws ConfigException
   {
-    if (publisher.isCsv())
+    switch (publisher.auditType)
     {
+    case CSV:
       addCsvHandler(publisher, builder);
-    }
-    else if (publisher.isExternal())
-    {
+      break;
+    case JSON:
+      addJsonHandler(publisher, builder);
+      break;
+    case EXTERNAL:
       addExternalHandler(publisher, builder);
-    }
-    else
-    {
+      break;
+    default:
       throw new ConfigException(ERR_COMMON_AUDIT_UNSUPPORTED_HANDLER_TYPE.get(publisher.getDn()));
     }
   }
@@ -446,27 +450,26 @@
 
   private void addCsvHandler(PublisherConfig publisher, AuditServiceBuilder builder) throws ConfigException
   {
-    String name = publisher.getName();
     try
     {
       CsvConfigData config = publisher.getCsvConfig();
       CsvAuditEventHandlerConfiguration csvConfig = new CsvAuditEventHandlerConfiguration();
       File logDirectory = getFileForPath(config.getLogDirectory());
       csvConfig.setLogDirectory(logDirectory.getAbsolutePath());
-      csvConfig.setName(name);
+      csvConfig.setName(publisher.getName());
       csvConfig.setTopics(Collections.singleton(publisher.getCommonAuditTopic()));
 
       addCsvHandlerFormattingConfig(config, csvConfig);
       addCsvHandlerBufferingConfig(config, csvConfig);
       addCsvHandlerSecureConfig(publisher, config, csvConfig);
-      addCsvHandlerRotationConfig(publisher, config, csvConfig);
-      addCsvHandlerRetentionConfig(publisher, config, csvConfig);
+      addHandlerRotationConfig(publisher, config, csvConfig);
+      addHandlerRetentionConfig(publisher, config, csvConfig);
 
       builder.withAuditEventHandler(CsvAuditEventHandler.class, csvConfig);
     }
     catch (Exception e)
     {
-      throw new ConfigException(ERR_COMMON_AUDIT_CSV_HANDLER_CREATION.get(publisher.getDn(), e), e);
+      throw new ConfigException(ERR_COMMON_AUDIT_FILE_BASED_HANDLER_CREATION.get(publisher.getDn(), e), e);
     }
   }
 
@@ -507,8 +510,36 @@
     }
   }
 
-  private void addCsvHandlerRotationConfig(PublisherConfig publisher, CsvConfigData config,
-      CsvAuditEventHandlerConfiguration auditConfig) throws ConfigException
+  private void addJsonHandler(PublisherConfig publisher, AuditServiceBuilder builder) throws ConfigException
+  {
+    try
+    {
+      JsonConfigData config = publisher.getJsonConfig();
+      JsonAuditEventHandlerConfiguration jsonConfig = new JsonAuditEventHandlerConfiguration();
+      File logDirectory = getFileForPath(config.getLogDirectory());
+      jsonConfig.setLogDirectory(logDirectory.getAbsolutePath());
+      jsonConfig.setName(publisher.getName());
+      jsonConfig.setTopics(Collections.singleton(publisher.getCommonAuditTopic()));
+      addJsonHandlerBufferingConfig(config, jsonConfig);
+      addHandlerRetentionConfig(publisher, config, jsonConfig);
+      addHandlerRotationConfig(publisher, config, jsonConfig);
+
+      builder.withAuditEventHandler(JsonAuditEventHandler.class, jsonConfig);
+    }
+    catch (Exception e)
+    {
+      throw new ConfigException(ERR_COMMON_AUDIT_FILE_BASED_HANDLER_CREATION.get(publisher.getDn(), e), e);
+    }
+  }
+
+  private void addJsonHandlerBufferingConfig(JsonConfigData config, JsonAuditEventHandlerConfiguration auditConfig)
+  {
+    JsonAuditEventHandlerConfiguration.EventBufferingConfiguration jsonBufferingConfig =
+        new JsonAuditEventHandlerConfiguration.EventBufferingConfiguration();
+  }
+
+  private void addHandlerRotationConfig(PublisherConfig publisher, HandlerConfigData config,
+      FileBasedEventHandlerConfiguration auditConfig) throws ConfigException
   {
     SortedSet<String> rotationPolicies = config.getRotationPolicies();
     if (rotationPolicies.isEmpty())
@@ -544,8 +575,8 @@
     auditConfig.setFileRotation(fileRotation);
   }
 
-  private void addCsvHandlerRetentionConfig(PublisherConfig publisher, CsvConfigData config,
-      CsvAuditEventHandlerConfiguration auditConfig) throws ConfigException
+  private void addHandlerRetentionConfig(PublisherConfig publisher, HandlerConfigData config,
+      FileBasedEventHandlerConfiguration auditConfig) throws ConfigException
   {
     SortedSet<String> retentionPolicies = config.getRetentionPolicies();
     if (retentionPolicies.isEmpty())
@@ -650,7 +681,7 @@
    */
   public boolean isCommonAuditConfig(LogPublisherCfg config) throws ConfigException
   {
-    return new PublisherConfig(serverContext, config).isCommonAudit();
+    return new PublisherConfig(serverContext, config).isCommonAudit;
   }
 
   /**
@@ -705,42 +736,45 @@
   {
     private final LogPublisherCfg config;
     private final boolean isCommonAudit;
-    private LogType logType;
+    private LogType logType = LogType.UNCONFIGURED;
     private AuditType auditType;
 
     PublisherConfig(ServerContext serverContext, LogPublisherCfg config) throws ConfigException
     {
       this.config = config;
-      Entry configEntry = DirectoryServer.getConfigEntry(config.dn());
-      if (hasObjectClass(serverContext,configEntry, "ds-cfg-csv-file-access-log-publisher"))
+      if (config instanceof JsonFileAccessLogPublisherCfg)
+      {
+        auditType = AuditType.JSON;
+        logType = LogType.ACCESSLOG;
+      }
+      else if (config instanceof JsonFileHTTPAccessLogPublisherCfg)
+      {
+        auditType = AuditType.JSON;
+        logType = LogType.HTTPLOG;
+      }
+      if (config instanceof CsvFileAccessLogPublisherCfg)
       {
         auditType = AuditType.CSV;
-        logType = LogType.ACCESS;
+        logType = LogType.ACCESSLOG;
       }
-      else if (hasObjectClass(serverContext,configEntry, "ds-cfg-csv-file-http-access-log-publisher"))
+      else if (config instanceof CsvFileHTTPAccessLogPublisherCfg)
       {
         auditType = AuditType.CSV;
-        logType = LogType.HTTP_ACCESS;
+        logType = LogType.HTTPLOG;
       }
-      else if (hasObjectClass(serverContext,configEntry, "ds-cfg-external-access-log-publisher"))
+      if (config instanceof ExternalAccessLogPublisherCfg)
       {
         auditType = AuditType.EXTERNAL;
-        logType = LogType.ACCESS;
+        logType = LogType.ACCESSLOG;
       }
-      else if (hasObjectClass(serverContext,configEntry, "ds-cfg-external-http-access-log-publisher"))
+      else if (config instanceof ExternalHTTPAccessLogPublisherCfg)
       {
         auditType = AuditType.EXTERNAL;
-        logType = LogType.HTTP_ACCESS;
+        logType = LogType.HTTPLOG;
       }
       isCommonAudit = auditType != null;
     }
 
-    private boolean hasObjectClass(ServerContext serverContext, Entry entry, String objectClassName)
-    {
-      ObjectClass objectClass = serverContext.getSchema().getObjectClass(objectClassName);
-      return !objectClass.isPlaceHolder() && entry.hasObjectClass(objectClass);
-    }
-
     DN getDn()
     {
       return config.dn();
@@ -753,76 +787,22 @@
 
     String getCommonAuditTopic() throws ConfigException
     {
-      if (isAccessLog())
-      {
-        return "ldap-access";
-      }
-      else if (isHttpAccessLog())
-      {
-        return "http-access";
-      }
-      throw new ConfigException(ERR_COMMON_AUDIT_UNSUPPORTED_LOG_PUBLISHER.get(config.dn()));
-    }
-
-    boolean isExternal()
-    {
-      return AuditType.EXTERNAL == auditType;
-    }
-
-    boolean isCsv()
-    {
-      return AuditType.CSV == auditType;
-    }
-
-    boolean isAccessLog()
-    {
-      return LogType.ACCESS == logType;
-    }
-
-    boolean isHttpAccessLog()
-    {
-      return LogType.HTTP_ACCESS == logType;
-    }
-
-    boolean isCommonAudit()
-    {
-      return isCommonAudit;
+      return logType.getCommonAuditTopic(config);
     }
 
     CsvConfigData getCsvConfig() throws ConfigException
     {
-      if (isAccessLog())
-      {
-        CsvFileAccessLogPublisherCfg conf = (CsvFileAccessLogPublisherCfg) config;
-        return new CsvConfigData(conf.getLogDirectory(), conf.getCsvQuoteChar(), conf.getCsvDelimiterChar(), conf
-            .getCsvEolSymbols(), conf.isAsynchronous(), conf.isAutoFlush(), conf.isTamperEvident(), conf
-            .getSignatureTimeInterval(), conf.getKeyStoreFile(), conf.getKeyStorePinFile(), conf.getRotationPolicy(),
-            conf.getRetentionPolicy());
-      }
-      if (isHttpAccessLog())
-      {
-        CsvFileHTTPAccessLogPublisherCfg conf = (CsvFileHTTPAccessLogPublisherCfg) config;
-        return new CsvConfigData(conf.getLogDirectory(), conf.getCsvQuoteChar(), conf.getCsvDelimiterChar(), conf
-            .getCsvEolSymbols(), conf.isAsynchronous(), conf.isAutoFlush(), conf.isTamperEvident(), conf
-            .getSignatureTimeInterval(), conf.getKeyStoreFile(), conf.getKeyStorePinFile(), conf.getRotationPolicy(),
-            conf.getRetentionPolicy());
-      }
-      throw new ConfigException(ERR_COMMON_AUDIT_UNSUPPORTED_LOG_PUBLISHER.get(config.dn()));
+      return logType.getCsvConfig(config);
+    }
+
+    JsonConfigData getJsonConfig() throws ConfigException
+    {
+      return logType.getJsonConfig(config);
     }
 
     ExternalConfigData getExternalConfig() throws ConfigException
     {
-      if (isAccessLog())
-      {
-        ExternalAccessLogPublisherCfg conf = (ExternalAccessLogPublisherCfg) config;
-        return new ExternalConfigData(conf.getConfigFile());
-      }
-      if (isHttpAccessLog())
-      {
-        ExternalHTTPAccessLogPublisherCfg conf = (ExternalHTTPAccessLogPublisherCfg) config;
-        return new ExternalConfigData(conf.getConfigFile());
-      }
-      throw new ConfigException(ERR_COMMON_AUDIT_UNSUPPORTED_LOG_PUBLISHER.get(config.dn()));
+      return logType.getExternalConfig(config);
     }
 
     @Override
@@ -851,25 +831,182 @@
   /** Types of audit handlers managed. */
   private enum AuditType
   {
-    CSV, EXTERNAL
+    CSV, JSON, EXTERNAL
   }
 
-  /** Types of log managed. */
+  /** Log types for LDAP or HTTP, to get specific configuration depending on the handler. **/
   private enum LogType
   {
-    ACCESS, HTTP_ACCESS
+    UNCONFIGURED
+    {
+      @Override
+      String getCommonAuditTopic(LogPublisherCfg config) throws ConfigException
+      {
+        throw new ConfigException(ERR_COMMON_AUDIT_UNSUPPORTED_LOG_PUBLISHER.get(config.dn()));
+      }
+
+      @Override
+      ExternalConfigData getExternalConfig(LogPublisherCfg config) throws ConfigException
+      {
+        throw new ConfigException(ERR_COMMON_AUDIT_UNSUPPORTED_LOG_PUBLISHER.get(config.dn()));
+      }
+
+      @Override
+      CsvConfigData getCsvConfig(LogPublisherCfg config) throws ConfigException
+      {
+        throw new ConfigException(ERR_COMMON_AUDIT_UNSUPPORTED_LOG_PUBLISHER.get(config.dn()));
+      }
+
+      @Override
+      JsonConfigData getJsonConfig(LogPublisherCfg config) throws ConfigException
+      {
+        throw new ConfigException(ERR_COMMON_AUDIT_UNSUPPORTED_LOG_PUBLISHER.get(config.dn()));
+      }
+
+      @Override
+      boolean isHttp()
+      {
+        return false;
+      }
+    },
+    HTTPLOG
+    {
+      @Override
+      public String getCommonAuditTopic(LogPublisherCfg config)
+      {
+        return "http-access";
+      }
+
+      @Override
+      public ExternalConfigData getExternalConfig(LogPublisherCfg config) throws ConfigException
+      {
+        ExternalHTTPAccessLogPublisherCfg conf = (ExternalHTTPAccessLogPublisherCfg) config;
+        return new ExternalConfigData(conf.getConfigFile());
+      }
+
+      @Override
+      public CsvConfigData getCsvConfig(LogPublisherCfg config) throws ConfigException
+      {
+        CsvFileHTTPAccessLogPublisherCfg conf = (CsvFileHTTPAccessLogPublisherCfg) config;
+        return new CsvConfigData(conf.getLogDirectory(), conf.getCsvQuoteChar(), conf.getCsvDelimiterChar(), conf
+            .getCsvEolSymbols(), conf.isAsynchronous(), conf.isAutoFlush(), conf.isTamperEvident(), conf
+            .getSignatureTimeInterval(), conf.getKeyStoreFile(), conf.getKeyStorePinFile(), conf.getRotationPolicy(),
+            conf.getRetentionPolicy());
+      }
+
+      @Override
+      public JsonConfigData getJsonConfig(LogPublisherCfg config) throws ConfigException
+      {
+        JsonFileHTTPAccessLogPublisherCfg conf = (JsonFileHTTPAccessLogPublisherCfg) config;
+        return new JsonConfigData(conf.getLogDirectory(), conf.getRotationPolicy(), conf.getRetentionPolicy());
+      }
+
+      @Override
+      public boolean isHttp()
+      {
+        return true;
+      }
+    },
+    ACCESSLOG
+    {
+      @Override
+      public String getCommonAuditTopic(LogPublisherCfg config)
+      {
+        return "ldap-access";
+      }
+
+      @Override
+      public ExternalConfigData getExternalConfig(LogPublisherCfg config) throws ConfigException
+      {
+        ExternalAccessLogPublisherCfg conf = (ExternalAccessLogPublisherCfg) config;
+        return new ExternalConfigData(conf.getConfigFile());
+      }
+
+      @Override
+      public CsvConfigData getCsvConfig(LogPublisherCfg config) throws ConfigException
+      {
+        CsvFileAccessLogPublisherCfg conf = (CsvFileAccessLogPublisherCfg) config;
+        return new CsvConfigData(conf.getLogDirectory(), conf.getCsvQuoteChar(), conf.getCsvDelimiterChar(), conf
+            .getCsvEolSymbols(), conf.isAsynchronous(), conf.isAutoFlush(), conf.isTamperEvident(), conf
+            .getSignatureTimeInterval(), conf.getKeyStoreFile(), conf.getKeyStorePinFile(), conf.getRotationPolicy(),
+            conf.getRetentionPolicy());
+      }
+
+      @Override
+      public JsonConfigData getJsonConfig(LogPublisherCfg config) throws ConfigException
+      {
+        JsonFileAccessLogPublisherCfg conf = (JsonFileAccessLogPublisherCfg) config;
+        return new JsonConfigData(conf.getLogDirectory(), conf.getRotationPolicy(), conf.getRetentionPolicy());
+      }
+
+      @Override
+      public boolean isHttp()
+      {
+        return false;
+      }
+    };
+
+    abstract String getCommonAuditTopic(LogPublisherCfg config) throws ConfigException;
+    abstract ExternalConfigData getExternalConfig(LogPublisherCfg config) throws ConfigException;
+    abstract CsvConfigData getCsvConfig(LogPublisherCfg config) throws ConfigException;
+    abstract JsonConfigData getJsonConfig(LogPublisherCfg config) throws ConfigException;
+    abstract boolean isHttp();
   }
 
   /**
-   * Contains the parameters for a CSV handler.
+   * Contains common parameters for non External CAUD handlers.
    * <p>
-   * OpenDJ log publishers that logs to a CSV handler have the same parameters but do not share
+   * OpenDJ log publishers that log to a CAUD handler have the same parameters but do not share
    * a common ancestor with all the parameters (e.g Access Log, HTTP Access Log, ...), hence this class
-   * is necessary to avoid duplicating code that setup the configuration of the CSV handler.
+   * is necessary to avoid duplicating code that setup configuration of the handler.
    */
-  private static class CsvConfigData
+  private abstract static class HandlerConfigData
   {
     private final String logDirectory;
+    private final SortedSet<String> rotationPolicies;
+    private final SortedSet<String> retentionPolicies;
+
+    HandlerConfigData(String logDirectory, SortedSet<String> rotationPolicies, SortedSet<String> retentionPolicies)
+    {
+      this.logDirectory = logDirectory;
+      this.rotationPolicies = rotationPolicies;
+      this.retentionPolicies = retentionPolicies;
+    }
+
+    String getLogDirectory()
+    {
+      return logDirectory;
+    }
+
+    SortedSet<String> getRotationPolicies()
+    {
+      return rotationPolicies;
+    }
+
+    SortedSet<String> getRetentionPolicies()
+    {
+      return retentionPolicies;
+    }
+  }
+
+  /**
+   * Contains common parameters for the Json handler.
+   */
+  private static class JsonConfigData extends HandlerConfigData
+  {
+    JsonConfigData(String logDirectory, SortedSet<String> rotationPolicies, SortedSet<String> retentionPolicies)
+    {
+      super(logDirectory, rotationPolicies, retentionPolicies);
+    }
+  }
+
+  /**
+   * Contains common parameters for the CSV handler.
+   * <p>
+   * Adds CSV specific configuration to a CAUD handler.
+   */
+  private static class CsvConfigData extends HandlerConfigData
+  {
     private final String eolSymbols;
     private final String delimiterChar;
     private final String quoteChar;
@@ -879,14 +1016,12 @@
     private final long signatureTimeInterval;
     private final String keystoreFile;
     private final String keystorePinFile;
-    private final SortedSet<String> rotationPolicies;
-    private final SortedSet<String> retentionPolicies;
 
     CsvConfigData(String logDirectory, String quoteChar, String delimiterChar, String eolSymbols, boolean asynchronous,
         boolean autoFlush, boolean tamperEvident, long signatureTimeInterval, String keystoreFile,
         String keystorePinFile, SortedSet<String> rotationPolicies, SortedSet<String> retentionPolicies)
     {
-      this.logDirectory = logDirectory;
+      super(logDirectory, rotationPolicies, retentionPolicies);
       this.quoteChar = quoteChar;
       this.delimiterChar = delimiterChar;
       this.eolSymbols = eolSymbols;
@@ -896,8 +1031,6 @@
       this.signatureTimeInterval = signatureTimeInterval;
       this.keystoreFile = keystoreFile;
       this.keystorePinFile = keystorePinFile;
-      this.rotationPolicies = rotationPolicies;
-      this.retentionPolicies = retentionPolicies;
     }
 
     String getEndOfLineSymbols()
@@ -925,11 +1058,6 @@
       return filtered.charAt(0);
     }
 
-    String getLogDirectory()
-    {
-      return logDirectory;
-    }
-
     boolean isAsynchronous()
     {
       return asynchronous;
@@ -959,16 +1087,6 @@
     {
       return keystorePinFile;
     }
-
-    SortedSet<String> getRotationPolicies()
-    {
-      return rotationPolicies;
-    }
-
-    SortedSet<String> getRetentionPolicies()
-    {
-      return retentionPolicies;
-    }
   }
 
   /**
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/loggers/JsonFileAccessLogPublisher.java b/opendj-server-legacy/src/main/java/org/opends/server/loggers/JsonFileAccessLogPublisher.java
new file mode 100644
index 0000000..eb2c5a3
--- /dev/null
+++ b/opendj-server-legacy/src/main/java/org/opends/server/loggers/JsonFileAccessLogPublisher.java
@@ -0,0 +1,52 @@
+/*
+ * The contents of this file are subject to the terms of the Common Development and
+ * Distribution License (the License). You may not use this file except in compliance with the
+ * License.
+ *
+ * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
+ * specific language governing permission and limitations under the License.
+ *
+ * When distributing Covered Software, include this CDDL Header Notice in each file and include
+ * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
+ * Header, with the fields enclosed by brackets [] replaced by your own identifying
+ * information: "Portions Copyright [year] [name of copyright owner]".
+ *
+ * Copyright 2016 ForgeRock AS.
+ */
+package org.opends.server.loggers;
+
+import org.forgerock.i18n.LocalizableMessage;
+import org.forgerock.opendj.config.server.ConfigChangeResult;
+import org.forgerock.opendj.config.server.ConfigurationChangeListener;
+import org.forgerock.opendj.server.config.server.JsonFileAccessLogPublisherCfg;
+
+import java.util.List;
+
+/**
+ * Common Audit publisher which publishes access events to Json files.
+ */
+final class JsonFileAccessLogPublisher
+  extends CommonAuditAccessLogPublisher<JsonFileAccessLogPublisherCfg>
+  implements ConfigurationChangeListener<JsonFileAccessLogPublisherCfg>
+{
+
+  @Override
+  boolean shouldLogControlOids()
+  {
+    return getConfig().isLogControlOids();
+  }
+
+  @Override
+  public ConfigChangeResult applyConfigurationChange(final JsonFileAccessLogPublisherCfg config)
+  {
+    setConfig(config);
+    return new ConfigChangeResult();
+  }
+
+  @Override
+  public boolean isConfigurationChangeAcceptable(final JsonFileAccessLogPublisherCfg config,
+                                                 final List<LocalizableMessage> unacceptableReasons)
+  {
+    return true;
+  }
+}
diff --git a/opendj-server-legacy/src/messages/org/opends/messages/logger.properties b/opendj-server-legacy/src/messages/org/opends/messages/logger.properties
index fa55b79..de90779 100644
--- a/opendj-server-legacy/src/messages/org/opends/messages/logger.properties
+++ b/opendj-server-legacy/src/messages/org/opends/messages/logger.properties
@@ -11,9 +11,7 @@
 # information: "Portions Copyright [year] [name of copyright owner]".
 #
 # Copyright 2006-2008 Sun Microsystems, Inc.
-# Portions Copyright 2015 ForgeRock AS.
-
-
+# Portions Copyright 2015-2016 ForgeRock AS.
 
 #
 # Global directives
@@ -72,12 +70,11 @@
  JSON configuration file %s while creating common audit external log publisher %s: %s
 ERR_COMMON_AUDIT_EXTERNAL_HANDLER_CREATION_18=Error while creating \
  common audit external log publisher %s: %s
-ERR_COMMON_AUDIT_CSV_HANDLER_CREATION_19=Error while creating \
- CSV log publisher %s: %s
+ERR_COMMON_AUDIT_FILE_BASED_HANDLER_CREATION_19=Error while creating common audit log publisher %s: %s
 ERR_COMMON_AUDIT_UNSUPPORTED_LOG_ROTATION_POLICY_20=Error while adding common audit \
- CSV log publisher %s, the publisher defines an unsupported log rotation policy %s
+ log publisher %s, the publisher defines an unsupported log rotation policy %s
 ERR_COMMON_AUDIT_UNSUPPORTED_LOG_RETENTION_POLICY_21=Error while adding common audit \
- CSV log publisher %s, the publisher defines an unsupported log retention policy %s
+ log publisher %s, the publisher defines an unsupported log retention policy %s
 ERR_COMMON_AUDIT_UNSUPPORTED_LOG_PUBLISHER_22=Error while processing common audit \
  log publisher %s, this type of log publisher is unsupported
 ERR_COMMON_AUDIT_CSV_HANDLER_DELIMITER_CHAR_23=Error while processing common audit \

--
Gitblit v1.10.0