LOG4J2-1984 - Allow user to specify maxLength of StructuredData names
authorRalph Goers <rgoers@nextiva.com>
Fri, 21 Jul 2017 20:29:14 +0000 (13:29 -0700)
committerRalph Goers <rgoers@nextiva.com>
Fri, 21 Jul 2017 20:29:14 +0000 (13:29 -0700)
log4j-api/src/main/java/org/apache/logging/log4j/message/StructuredDataId.java
log4j-api/src/main/java/org/apache/logging/log4j/message/StructuredDataMessage.java
src/changes/changes.xml

index 6b5fa99..232f156 100644 (file)
@@ -58,12 +58,50 @@ public class StructuredDataId implements Serializable, StringBuilderFormattable
     private final String[] required;\r
     private final String[] optional;\r
 \r
-    protected StructuredDataId(final String name, final String[] required, final String[] optional) {\r
+    /**\r
+     * Creates a StructuredDataId based on the name.\r
+     * @param name The Structured Data Element name (maximum length is 32)\r
+     * @since 2.9\r
+     */\r
+    public StructuredDataId(final String name) {\r
+        this(name, null, null, MAX_LENGTH);\r
+    }\r
+\r
+    /**\r
+     * Creates a StructuredDataId based on the name.\r
+     * @param name The Structured Data Element name.\r
+     * @param maxLength The maximum length of the name.\r
+     * @since 2.9\r
+     */\r
+    public StructuredDataId(final String name, final int maxLength) {\r
+        this(name, null, null, maxLength);\r
+    }\r
+\r
+    /**\r
+     *\r
+     * @param name\r
+     * @param required\r
+     * @param optional\r
+     */\r
+    public StructuredDataId(final String name, final String[] required, final String[] optional) {\r
+        this(name, required, optional, MAX_LENGTH);\r
+    }\r
+\r
+    /**\r
+     * A Constructor that helps conformance to RFC 5424.\r
+     *\r
+     * @param name The name portion of the id.\r
+     * @param required The list of keys that are required for this id.\r
+     * @param optional The list of keys that are optional for this id.\r
+     * @since 2.9\r
+     */\r
+    public StructuredDataId(final String name, final String[] required, final String[] optional,\r
+                               final int maxLength) {\r
         int index = -1;\r
         if (name != null) {\r
-            if (name.length() > MAX_LENGTH) {\r
+            if (maxLength > 0 && name.length() > MAX_LENGTH) {\r
                 throw new IllegalArgumentException(String.format("Length of id %s exceeds maximum of %d characters",\r
-                        name, MAX_LENGTH));\r
+                        name, maxLength));\r
             }\r
             index = name.indexOf(AT_SIGN);\r
         }\r
@@ -88,7 +126,22 @@ public class StructuredDataId implements Serializable, StringBuilderFormattable
      * @param optional The list of keys that are optional for this id.\r
      */\r
     public StructuredDataId(final String name, final int enterpriseNumber, final String[] required,\r
-            final String[] optional) {\r
+                            final String[] optional) {\r
+        this(name, enterpriseNumber, required, optional, MAX_LENGTH);\r
+    }\r
+\r
+    /**\r
+     * A Constructor that helps conformance to RFC 5424.\r
+     *\r
+     * @param name The name portion of the id.\r
+     * @param enterpriseNumber The enterprise number.\r
+     * @param required The list of keys that are required for this id.\r
+     * @param optional The list of keys that are optional for this id.\r
+     * @param maxLength The maximum length of the StructuredData Id key.\r
+     * @since 2.9\r
+     */\r
+    public StructuredDataId(final String name, final int enterpriseNumber, final String[] required,\r
+            final String[] optional, final int maxLength) {\r
         if (name == null) {\r
             throw new IllegalArgumentException("No structured id name was supplied");\r
         }\r
@@ -101,8 +154,8 @@ public class StructuredDataId implements Serializable, StringBuilderFormattable
         this.name = name;\r
         this.enterpriseNumber = enterpriseNumber;\r
         final String id = name + AT_SIGN + enterpriseNumber;\r
-        if (id.length() > MAX_LENGTH) {\r
-            throw new IllegalArgumentException("Length of id exceeds maximum of 32 characters: " + id);\r
+        if (maxLength > 0 && id.length() > maxLength) {\r
+            throw new IllegalArgumentException("Length of id exceeds maximum of " + maxLength + " characters: " + id);\r
         }\r
         this.required = required;\r
         this.optional = optional;\r
index f0a3a8b..74a4542 100644 (file)
@@ -47,6 +47,8 @@ public class StructuredDataMessage extends MapMessage<StructuredDataMessage, Str
 
     private String type;
 
+    private final int maxLength;
+
     /**
      * Supported formats.
      */
@@ -64,9 +66,23 @@ public class StructuredDataMessage extends MapMessage<StructuredDataMessage, Str
      * @param type The message type.
      */
     public StructuredDataMessage(final String id, final String msg, final String type) {
-        this.id = new StructuredDataId(id, null, null);
+        this(id, msg, type, MAX_LENGTH);
+    }
+
+    /**
+     * Creates a StructuredDataMessage using an ID (user specified max characters), message, and type (user specified
+     * maximum number of characters).
+     * @param id The String id.
+     * @param msg The message.
+     * @param type The message type.
+     * @param maxLength The maximum length of keys;
+     * @since 2.9
+     */
+    public StructuredDataMessage(final String id, final String msg, final String type, final int maxLength) {
+        this.id = new StructuredDataId(id, null, null, maxLength);
         this.message = msg;
         this.type = type;
+        this.maxLength = maxLength;
     }
     /**
      * Creates a StructuredDataMessage using an ID (max 32 characters), message, type (max 32 characters), and an
@@ -78,10 +94,26 @@ public class StructuredDataMessage extends MapMessage<StructuredDataMessage, Str
      */
     public StructuredDataMessage(final String id, final String msg, final String type,
                                  final Map<String, String> data) {
+        this(id, msg, type, data, MAX_LENGTH);
+    }
+
+    /**
+     * Creates a StructuredDataMessage using an (user specified max characters), message, and type (user specified
+     * maximum number of characters, and an initial map of structured data to include.
+     * @param id The String id.
+     * @param msg The message.
+     * @param type The message type.
+     * @param data The StructuredData map.
+     * @param maxLength The maximum length of keys;
+     * @since 2.9
+     */
+    public StructuredDataMessage(final String id, final String msg, final String type,
+                                 final Map<String, String> data, final int maxLength) {
         super(data);
-        this.id = new StructuredDataId(id, null, null);
+        this.id = new StructuredDataId(id, null, null, maxLength);
         this.message = msg;
         this.type = type;
+        this.maxLength = maxLength;
     }
 
     /**
@@ -91,9 +123,22 @@ public class StructuredDataMessage extends MapMessage<StructuredDataMessage, Str
      * @param type The message type.
      */
     public StructuredDataMessage(final StructuredDataId id, final String msg, final String type) {
+        this(id, msg, type, MAX_LENGTH);
+    }
+
+    /**
+     * Creates a StructuredDataMessage using a StructuredDataId, message, and type (max 32 characters).
+     * @param id The StructuredDataId.
+     * @param msg The message.
+     * @param type The message type.
+     * @param maxLength The maximum length of keys;
+     * @since 2.9
+     */
+    public StructuredDataMessage(final StructuredDataId id, final String msg, final String type, final int maxLength) {
         this.id = id;
         this.message = msg;
         this.type = type;
+        this.maxLength = maxLength;
     }
 
     /**
@@ -106,10 +151,26 @@ public class StructuredDataMessage extends MapMessage<StructuredDataMessage, Str
      */
     public StructuredDataMessage(final StructuredDataId id, final String msg, final String type,
                                  final Map<String, String> data) {
+        this(id, msg, type, data, MAX_LENGTH);
+    }
+
+    /**
+     * Creates a StructuredDataMessage using a StructuredDataId, message, type (max 32 characters), and an initial map
+     * of structured data to include.
+     * @param id The StructuredDataId.
+     * @param msg The message.
+     * @param type The message type.
+     * @param data The StructuredData map.
+     * @param maxLength The maximum length of keys;
+     * @since 2.9
+     */
+    public StructuredDataMessage(final StructuredDataId id, final String msg, final String type,
+                                 final Map<String, String> data, final int maxLength) {
         super(data);
         this.id = id;
         this.message = msg;
         this.type = type;
+        this.maxLength = maxLength;
     }
 
 
@@ -123,6 +184,7 @@ public class StructuredDataMessage extends MapMessage<StructuredDataMessage, Str
         this.id = msg.id;
         this.message = msg.message;
         this.type = msg.type;
+        this.maxLength = MAX_LENGTH;
     }
 
 
@@ -130,7 +192,7 @@ public class StructuredDataMessage extends MapMessage<StructuredDataMessage, Str
      * Basic constructor.
      */
     protected StructuredDataMessage() {
-
+        maxLength = MAX_LENGTH;
     }
 
     /**
@@ -454,9 +516,10 @@ public class StructuredDataMessage extends MapMessage<StructuredDataMessage, Str
         validateKey(key);
     }
 
-    private void validateKey(final String key) {
-        if (key.length() > MAX_LENGTH) {
-            throw new IllegalArgumentException("Structured data keys are limited to 32 characters. key: " + key);
+    protected void validateKey(final String key) {
+        if (maxLength > 0 && key.length() > maxLength) {
+            throw new IllegalArgumentException("Structured data keys are limited to " + maxLength +
+                    " characters. key: " + key);
         }
         for (int i = 0; i < key.length(); i++) {
             final char c = key.charAt(i);
index 762e66a..c480e32 100644 (file)
@@ -31,6 +31,9 @@
          - "remove" - Removed
     -->
     <release version="2.9.0" date="2017-MM-DD" description="GA Release 2.9.0">
+      <action issue="LOG4J2-1984" dev="rgoers" type="update">
+        Allow maxLength of StructuredData to be specified by the user.
+      </action>
       <action issue="LOG4J2-1864" dev="mattsicker" type="add" due-to="Matthias Kappeller">
         Support capped collections for MongoDb appender.
       </action>