This is an automated email from the ASF dual-hosted git repository.

pkarwasz pushed a commit to branch release/2.21.0
in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git

commit fd1d2b6ddd8fc59af341292f9fcff3aa297e094e
Author: Piotr P. Karwasz <[email protected]>
AuthorDate: Thu Oct 5 15:24:06 2023 +0200

    Add `columnType` as alias for column mapping `type` attribute
    
    Since the strict XML and properties format use the `type` attribute to
    indicate the plugin type of the element, no other attribute should be
    called `type`.
---
 .../JdbcAppenderColumnMappingPropertiesTest.java   | 66 ++++++++++++++++++++++
 ...cAppenderColumnMappingPropertiesTest.properties | 31 ++++++++++
 .../log4j/core/appender/db/ColumnMapping.java      | 45 +++++++++++----
 .../core/appender/db/jdbc/JdbcDatabaseManager.java |  7 ++-
 .../1405_column_mapping_rename_type_attribute.xml  | 27 +++++++++
 5 files changed, 163 insertions(+), 13 deletions(-)

diff --git 
a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/db/jdbc/JdbcAppenderColumnMappingPropertiesTest.java
 
b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/db/jdbc/JdbcAppenderColumnMappingPropertiesTest.java
new file mode 100644
index 0000000000..a897ebf04e
--- /dev/null
+++ 
b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/db/jdbc/JdbcAppenderColumnMappingPropertiesTest.java
@@ -0,0 +1,66 @@
+/*
+ * 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.core.appender.db.jdbc;
+
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.sql.Connection;
+import java.util.Date;
+
+import org.apache.logging.log4j.core.Appender;
+import org.apache.logging.log4j.core.appender.db.ColumnMapping;
+import org.apache.logging.log4j.core.config.Configuration;
+import 
org.apache.logging.log4j.core.config.properties.PropertiesConfigurationFactory;
+import org.apache.logging.log4j.test.junit.UsingStatusListener;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+@UsingStatusListener
+public class JdbcAppenderColumnMappingPropertiesTest {
+
+    public Connection getConnection() {
+        return null;
+    }
+
+    /**
+     * Tests the possibility to configure {@link 
org.apache.logging.log4j.core.appender.db.ColumnMapping} in a
+     * properties configuration.
+     * @see <a 
href="https://github.com/apache/logging-log4j2/issues/1405";>#1405</a>
+     */
+    @Test
+    void testColumnMapping() throws URISyntaxException {
+        final URL configLocation = 
JdbcAppenderColumnMappingPropertiesTest.class.getResource(
+                "JdbcAppenderColumnMappingPropertiesTest.properties");
+        assertThat(configLocation).isNotNull();
+        final Configuration config = 
PropertiesConfigurationFactory.getInstance()
+                .getConfiguration(null, null, configLocation.toURI());
+        assertThat(config).isNotNull();
+        config.initialize();
+        final Appender appender = config.getAppender("Jdbc");
+        assertThat(appender).isInstanceOf(JdbcAppender.class);
+        final JdbcAppender jdbcAppender = (JdbcAppender) appender;
+
+        final ColumnMapping expected = ColumnMapping.newBuilder()
+                .setName("timestamp")
+                .setColumnType(Date.class)
+                .build();
+        final ColumnMapping[] mappings = 
jdbcAppender.getManager().factoryData.columnMappings;
+        assertThat(mappings).hasSize(1);
+        assertThat(mappings[0]).isEqualTo(expected);
+    }
+}
diff --git 
a/log4j-core-test/src/test/resources/org/apache/logging/log4j/core/appender/db/jdbc/JdbcAppenderColumnMappingPropertiesTest.properties
 
b/log4j-core-test/src/test/resources/org/apache/logging/log4j/core/appender/db/jdbc/JdbcAppenderColumnMappingPropertiesTest.properties
new file mode 100644
index 0000000000..e44ec6d3b8
--- /dev/null
+++ 
b/log4j-core-test/src/test/resources/org/apache/logging/log4j/core/appender/db/jdbc/JdbcAppenderColumnMappingPropertiesTest.properties
@@ -0,0 +1,31 @@
+#
+# 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.
+#
+##
+status = OFF
+
+appender.jdbc.type = Jdbc
+appender.jdbc.name = Jdbc
+appender.jdbc.factory.type = ConnectionFactory
+appender.jdbc.factory.class = 
org.apache.logging.log4j.core.appender.db.jdbc.JdbcAppenderColumnMappingPropertiesTest
+appender.jdbc.factory.method = getConnection
+appender.jdbc.tableName = table
+appender.jdbc.col[1].type = ColumnMapping
+appender.jdbc.col[1].name = timestamp
+appender.jdbc.col[1].columnType = java.util.Date
+
+rootLogger.level = INFO
+rootLogger.appenderRef.1.ref = Jdbc
diff --git 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/ColumnMapping.java
 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/ColumnMapping.java
index 533904140e..31af35430f 100644
--- 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/ColumnMapping.java
+++ 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/ColumnMapping.java
@@ -17,6 +17,7 @@
 package org.apache.logging.log4j.core.appender.db;
 
 import java.util.Date;
+import java.util.Objects;
 
 import org.apache.logging.log4j.Logger;
 import org.apache.logging.log4j.core.Core;
@@ -78,7 +79,7 @@ public final class ColumnMapping {
 
         @PluginBuilderAttribute
         @Required(message = "No conversion type provided")
-        private Class<?> type = String.class;
+        private Class<?> columnType = String.class;
 
         @Override
         public ColumnMapping build() {
@@ -91,18 +92,19 @@ public final class ColumnMapping {
             }
             if (!(layout == null
                 || literal == null
-                || Date.class.isAssignableFrom(type)
-                || ReadOnlyStringMap.class.isAssignableFrom(type)
-                || ThreadContextMap.class.isAssignableFrom(type)
-                || ThreadContextStack.class.isAssignableFrom(type))) {
-                LOGGER.error("No 'layout' or 'literal' value specified and 
type ({}) is not compatible with ThreadContextMap, ThreadContextStack, or 
java.util.Date for the mapping", type, this);
+                || Date.class.isAssignableFrom(columnType)
+                || ReadOnlyStringMap.class.isAssignableFrom(columnType)
+                || ThreadContextMap.class.isAssignableFrom(columnType)
+                || ThreadContextStack.class.isAssignableFrom(columnType))) {
+                LOGGER.error("No 'layout' or 'literal' value specified and 
type ({}) is not compatible with " +
+                        "ThreadContextMap, ThreadContextStack, or 
java.util.Date for the mapping", columnType, this);
                 return null;
             }
             if (literal != null && parameter != null) {
                 LOGGER.error("Only one of 'literal' or 'parameter' can be set 
on the column mapping {}", this);
                 return null;
             }
-            return new ColumnMapping(name, source, layout, literal, parameter, 
type);
+            return new ColumnMapping(name, source, layout, literal, parameter, 
columnType);
         }
 
         public Builder setConfiguration(final Configuration configuration) {
@@ -182,15 +184,24 @@ public final class ColumnMapping {
          *
          * @return this.
          */
+        public Builder setColumnType(final Class<?> columnType) {
+            this.columnType = columnType;
+            return this;
+        }
+
+        /**
+         * @see Builder#setColumnType(Class)
+         */
+        @Deprecated
         public Builder setType(final Class<?> type) {
-            this.type = type;
+            this.columnType = type;
             return this;
         }
 
         @Override
         public String toString() {
             return "Builder [name=" + name + ", source=" + source + ", 
literal=" + literal + ", parameter=" + parameter
-                    + ", pattern=" + pattern + ", type=" + type + ", layout=" 
+ layout + "]";
+                    + ", pattern=" + pattern + ", columnType=" + columnType + 
", layout=" + layout + "]";
         }
     }
 
@@ -214,7 +225,7 @@ public final class ColumnMapping {
     private final Class<?> type;
 
     private ColumnMapping(final String name, final String source, final 
StringLayout layout, final String literalValue, final String parameter, final 
Class<?> type) {
-        this.name = name;
+        this.name = Objects.requireNonNull(name);
         this.nameKey = toKey(name);
         this.source = source;
         this.layout = layout;
@@ -257,4 +268,18 @@ public final class ColumnMapping {
                 + parameter + ", type=" + type + ", layout=" + layout + "]";
     }
 
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        ColumnMapping that = (ColumnMapping) o;
+        return Objects.equals(layout, that.layout) && 
Objects.equals(literalValue, that.literalValue) && name.equals(
+                that.name) && Objects.equals(parameter, that.parameter) && 
Objects.equals(source,
+                that.source) && Objects.equals(type, that.type);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(layout, literalValue, name, parameter, source, 
type);
+    }
 }
diff --git 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jdbc/JdbcDatabaseManager.java
 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jdbc/JdbcDatabaseManager.java
index 283a51b6d9..f68f54c66b 100644
--- 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jdbc/JdbcDatabaseManager.java
+++ 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jdbc/JdbcDatabaseManager.java
@@ -66,11 +66,11 @@ public final class JdbcDatabaseManager extends 
AbstractDatabaseManager {
     /**
      * Encapsulates data that {@link JdbcDatabaseManagerFactory} uses to 
create managers.
      */
-    private static final class FactoryData extends 
AbstractDatabaseManager.AbstractFactoryData {
+    static final class FactoryData extends 
AbstractDatabaseManager.AbstractFactoryData {
         private final ConnectionSource connectionSource;
         private final String tableName;
         private final ColumnConfig[] columnConfigs;
-        private final ColumnMapping[] columnMappings;
+        final ColumnMapping[] columnMappings;
         private final boolean immediateFail;
         private final boolean retry;
         private final long reconnectIntervalMillis;
@@ -468,7 +468,8 @@ public final class JdbcDatabaseManager extends 
AbstractDatabaseManager {
     // NOTE: prepared statements are prepared in this order: column mappings, 
then column configs
     private final List<ColumnConfig> columnConfigs;
     private final String sqlStatement;
-    private final FactoryData factoryData;
+    // Used in tests
+    final FactoryData factoryData;
     private volatile Connection connection;
     private volatile PreparedStatement statement;
     private volatile Reconnector reconnector;
diff --git a/src/changelog/.2.x.x/1405_column_mapping_rename_type_attribute.xml 
b/src/changelog/.2.x.x/1405_column_mapping_rename_type_attribute.xml
new file mode 100644
index 0000000000..e84af133e1
--- /dev/null
+++ b/src/changelog/.2.x.x/1405_column_mapping_rename_type_attribute.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ 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.
+  -->
+<entry xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+       xmlns="http://logging.apache.org/log4j/changelog";
+       xsi:schemaLocation="http://logging.apache.org/log4j/changelog 
https://logging.apache.org/log4j/changelog-0.1.1.xsd";
+       type="fixed">
+  <issue id="1405" 
link="https://github.com/apache/logging-log4j2/issues/1405"/>
+  <author id="github:ppkarwasz"/>
+  <description format="asciidoc">
+    Add `columnType` as alias for the column mapping `type` attribute.
+  </description>
+</entry>

Reply via email to