From 770ca32cb4c4bc9d3d66ee3fd5778e5e43803b95 Mon Sep 17 00:00:00 2001 From: Josh Smith Date: Fri, 14 Feb 2025 19:16:50 -0600 Subject: [PATCH 01/27] Backported changes from the 3.x branch to 2.x --- .../mongodb/MongoDbCollectionNameIT.java | 36 ++++++ .../MongoDbDatabaseAndCollectionNameIT.java | 36 ++++++ .../resources/MongoDbCollectionNameIT.xml | 37 ++++++ .../MongoDbDatabaseAndCollectionNameIT.xml | 39 ++++++ .../log4j/mongodb4/MongoDb4Connection.java | 14 +- .../log4j/mongodb4/MongoDb4Provider.java | 70 +++++++++- .../mongodb4/MongoDb4CollectionNameIT.java | 36 ++++++ .../MongoDb4DatabaseAndCollectionNameIT.java | 36 ++++++ .../log4j/mongodb4/MongoDb4ProviderTest.java | 121 ++++++++++++++++++ .../resources/MongoDb4AdditionalFields.xml | 4 +- .../test/resources/MongoDb4AuthFailureIT.xml | 4 +- .../test/resources/MongoDb4CappedIntIT.xml | 7 +- .../test/resources/MongoDb4CappedLongIT.xml | 6 +- .../resources/MongoDb4CollectionNameIT.xml | 37 ++++++ .../MongoDb4DatabaseAndCollectionNameIT.xml | 39 ++++++ .../src/test/resources/MongoDb4IT.xml | 4 +- .../test/resources/MongoDb4MapMessageIT.xml | 4 +- .../.2.x.x/update_org_log4j_mongodb.xml | 8 ++ .../appenders/database/nosql-mongo-keys.json | 4 +- .../database/nosql-mongo-keys.properties | 4 +- .../appenders/database/nosql-mongo-keys.xml | 4 +- .../appenders/database/nosql-mongo-keys.yaml | 4 +- .../appenders/database/nosql-mongo.json | 4 +- .../appenders/database/nosql-mongo.properties | 4 +- .../manual/appenders/database/nosql-mongo.xml | 4 +- .../appenders/database/nosql-mongo.yaml | 4 +- .../ROOT/pages/manual/appenders/database.adoc | 20 +++ 27 files changed, 566 insertions(+), 24 deletions(-) create mode 100644 log4j-mongodb/src/test/java/org/apache/logging/log4j/mongodb/MongoDbCollectionNameIT.java create mode 100644 log4j-mongodb/src/test/java/org/apache/logging/log4j/mongodb/MongoDbDatabaseAndCollectionNameIT.java create mode 100644 log4j-mongodb/src/test/resources/MongoDbCollectionNameIT.xml create mode 100644 log4j-mongodb/src/test/resources/MongoDbDatabaseAndCollectionNameIT.xml create mode 100644 log4j-mongodb4/src/test/java/org/apache/logging/log4j/mongodb4/MongoDb4CollectionNameIT.java create mode 100644 log4j-mongodb4/src/test/java/org/apache/logging/log4j/mongodb4/MongoDb4DatabaseAndCollectionNameIT.java create mode 100644 log4j-mongodb4/src/test/java/org/apache/logging/log4j/mongodb4/MongoDb4ProviderTest.java create mode 100644 log4j-mongodb4/src/test/resources/MongoDb4CollectionNameIT.xml create mode 100644 log4j-mongodb4/src/test/resources/MongoDb4DatabaseAndCollectionNameIT.xml create mode 100644 src/changelog/.2.x.x/update_org_log4j_mongodb.xml diff --git a/log4j-mongodb/src/test/java/org/apache/logging/log4j/mongodb/MongoDbCollectionNameIT.java b/log4j-mongodb/src/test/java/org/apache/logging/log4j/mongodb/MongoDbCollectionNameIT.java new file mode 100644 index 00000000000..60c74dff597 --- /dev/null +++ b/log4j-mongodb/src/test/java/org/apache/logging/log4j/mongodb/MongoDbCollectionNameIT.java @@ -0,0 +1,36 @@ +/* + * 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.mongodb; + +import com.mongodb.client.MongoClient; +import org.apache.logging.log4j.core.LoggerContext; +import org.apache.logging.log4j.core.test.junit.LoggerContextSource; +import org.apache.logging.log4j.test.junit.UsingStatusListener; +import org.junit.jupiter.api.Test; + +@UsingMongoDb +@LoggerContextSource("MongoDbCollectionNameIT.xml") +// Print debug status logger output upon failure +@UsingStatusListener +class MongoDbCollectionNameIT extends AbstractMongoDbCappedIT { + + @Test + @Override + protected void test(LoggerContext ctx, MongoClient mongoClient) { + super.test(ctx, mongoClient); + } +} diff --git a/log4j-mongodb/src/test/java/org/apache/logging/log4j/mongodb/MongoDbDatabaseAndCollectionNameIT.java b/log4j-mongodb/src/test/java/org/apache/logging/log4j/mongodb/MongoDbDatabaseAndCollectionNameIT.java new file mode 100644 index 00000000000..8d399d10ac9 --- /dev/null +++ b/log4j-mongodb/src/test/java/org/apache/logging/log4j/mongodb/MongoDbDatabaseAndCollectionNameIT.java @@ -0,0 +1,36 @@ +/* + * 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.mongodb; + +import com.mongodb.client.MongoClient; +import org.apache.logging.log4j.core.LoggerContext; +import org.apache.logging.log4j.core.test.junit.LoggerContextSource; +import org.apache.logging.log4j.test.junit.UsingStatusListener; +import org.junit.jupiter.api.Test; + +@UsingMongoDb +@LoggerContextSource("MongoDbDatabaseAndCollectionNameIT.xml") +// Print debug status logger output upon failure +@UsingStatusListener +class MongoDbDatabaseAndCollectionNameIT extends AbstractMongoDbCappedIT { + + @Test + @Override + protected void test(LoggerContext ctx, MongoClient mongoClient) { + super.test(ctx, mongoClient); + } +} diff --git a/log4j-mongodb/src/test/resources/MongoDbCollectionNameIT.xml b/log4j-mongodb/src/test/resources/MongoDbCollectionNameIT.xml new file mode 100644 index 00000000000..ef84c991cae --- /dev/null +++ b/log4j-mongodb/src/test/resources/MongoDbCollectionNameIT.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + diff --git a/log4j-mongodb/src/test/resources/MongoDbDatabaseAndCollectionNameIT.xml b/log4j-mongodb/src/test/resources/MongoDbDatabaseAndCollectionNameIT.xml new file mode 100644 index 00000000000..adf32a000d9 --- /dev/null +++ b/log4j-mongodb/src/test/resources/MongoDbDatabaseAndCollectionNameIT.xml @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + diff --git a/log4j-mongodb4/src/main/java/org/apache/logging/log4j/mongodb4/MongoDb4Connection.java b/log4j-mongodb4/src/main/java/org/apache/logging/log4j/mongodb4/MongoDb4Connection.java index 1d9537978c4..1a202e43d99 100644 --- a/log4j-mongodb4/src/main/java/org/apache/logging/log4j/mongodb4/MongoDb4Connection.java +++ b/log4j-mongodb4/src/main/java/org/apache/logging/log4j/mongodb4/MongoDb4Connection.java @@ -67,21 +67,23 @@ public MongoDb4Connection( final ConnectionString connectionString, final MongoClient mongoClient, final MongoDatabase mongoDatabase, + final String collectionName, final boolean isCapped, final Integer sizeInBytes) { - this(connectionString, mongoClient, mongoDatabase, isCapped, Long.valueOf(sizeInBytes)); + this(connectionString, mongoClient, mongoDatabase, collectionName, isCapped, Long.valueOf(sizeInBytes)); } public MongoDb4Connection( final ConnectionString connectionString, final MongoClient mongoClient, final MongoDatabase mongoDatabase, + final String collectionName, final boolean isCapped, final Long sizeInBytes) { this.connectionString = connectionString; this.mongoClient = mongoClient; this.collection = - getOrCreateMongoCollection(mongoDatabase, connectionString.getCollection(), isCapped, sizeInBytes); + getOrCreateMongoCollection(mongoDatabase, collectionName, isCapped, sizeInBytes); } @Override @@ -119,4 +121,12 @@ public String toString() { "Mongo4Connection [connectionString=%s, collection=%s, mongoClient=%s]", connectionString, collection, mongoClient); } + + /* + * This method is exposed to help support unit tests for the MongoDbProvider class. + * + */ + public MongoCollection getCollection() { + return this.collection; + } } diff --git a/log4j-mongodb4/src/main/java/org/apache/logging/log4j/mongodb4/MongoDb4Provider.java b/log4j-mongodb4/src/main/java/org/apache/logging/log4j/mongodb4/MongoDb4Provider.java index 99e392237b4..0cd4d1cebf0 100644 --- a/log4j-mongodb4/src/main/java/org/apache/logging/log4j/mongodb4/MongoDb4Provider.java +++ b/log4j-mongodb4/src/main/java/org/apache/logging/log4j/mongodb4/MongoDb4Provider.java @@ -18,6 +18,7 @@ import com.mongodb.ConnectionString; import com.mongodb.MongoClientSettings; +import com.mongodb.MongoNamespace; import com.mongodb.client.MongoClient; import com.mongodb.client.MongoClients; import com.mongodb.client.MongoDatabase; @@ -60,14 +61,47 @@ public static class Builder> extends AbstractFilterable.Bui @PluginBuilderAttribute("capped") private boolean capped = false; + @PluginBuilderAttribute("collectionName") + private String collectionName; + + @PluginBuilderAttribute("databaseName") + private String databaseName; + + + @Override public MongoDb4Provider build() { StatusLogger.getLogger().warn("The {} Appender is deprecated, use the MongoDb Appender.", PLUGIN_NAME); + + ConnectionString connectionString; + try { + connectionString = new ConnectionString(connectionStringSource); + } catch (final IllegalArgumentException e) { + LOGGER.error("Invalid MongoDB connection string `{}`.", connectionStringSource, e); + return null; + } + + String effectiveDatabaseName = databaseName != null ? databaseName : connectionString.getDatabase(); + String effectiveCollectionName = collectionName != null ? collectionName : connectionString.getCollection(); + // Validate the provided databaseName property + try { + MongoNamespace.checkDatabaseNameValidity(effectiveDatabaseName); + } catch (final IllegalArgumentException e) { + LOGGER.error("Invalid MongoDB database name `{}`.", effectiveDatabaseName, e); + return null; + } + // Validate the provided collectionName property + try { + MongoNamespace.checkCollectionNameValidity(effectiveCollectionName); + } catch (final IllegalArgumentException e) { + LOGGER.error("Invalid MongoDB collection name `{}`.", effectiveCollectionName, e); + return null; + } return newMongoDb4Provider(); } protected MongoDb4Provider newMongoDb4Provider() { - return new MongoDb4Provider(connectionStringSource, capped, collectionSize); + return new MongoDb4Provider(connectionStringSource, databaseName, collectionName, capped, collectionSize); } /** @@ -113,6 +147,28 @@ public B setCollectionSize(final long sizeInBytes) { this.collectionSize = sizeInBytes; return asBuilder(); } + + /** + * Sets name of the collection for the appender to output to + * + * @param collectionName the name of the collection for the appender to output to + * @return this instance. + */ + public B setCollectionName(final String collectionName) { + this.collectionName = collectionName; + return asBuilder(); + } + + /** + * Sets the name of the logical database for the appender to output to. + * + * @param databaseName the name of the DB for the appender to output to + * @return this instance. + */ + public B setDatabaseName(final String databaseName) { + this.databaseName = databaseName; + return asBuilder(); + } } private static final Logger LOGGER = StatusLogger.getLogger(); @@ -140,11 +196,12 @@ public static > B newBuilder() { private final Long collectionSize; private final boolean isCapped; + private final String collectionName; private final MongoClient mongoClient; private final MongoDatabase mongoDatabase; private final ConnectionString connectionString; - private MongoDb4Provider(final String connectionStringSource, final boolean isCapped, final Long collectionSize) { + private MongoDb4Provider(final String connectionStringSource, final String databaseName, final String collectionName, final boolean isCapped, final Long collectionSize) { LOGGER.debug("Creating ConnectionString {}...", connectionStringSource); this.connectionString = new ConnectionString(connectionStringSource); LOGGER.debug("Created ConnectionString {}", connectionString); @@ -159,28 +216,29 @@ private MongoDb4Provider(final String connectionStringSource, final boolean isCa LOGGER.debug("Creating MongoClient {}...", settings); this.mongoClient = MongoClients.create(settings); LOGGER.debug("Created MongoClient {}", mongoClient); - final String databaseName = this.connectionString.getDatabase(); LOGGER.debug("Getting MongoDatabase {}...", databaseName); this.mongoDatabase = this.mongoClient.getDatabase(databaseName); LOGGER.debug("Got MongoDatabase {}", mongoDatabase); this.isCapped = isCapped; this.collectionSize = collectionSize; + this.collectionName = collectionName; } @Override public MongoDb4Connection getConnection() { - return new MongoDb4Connection(connectionString, mongoClient, mongoDatabase, isCapped, collectionSize); + return new MongoDb4Connection(connectionString, mongoClient, mongoDatabase, collectionName, isCapped, collectionSize); } @Override public String toString() { return String.format( - "%s [connectionString=%s, collectionSize=%s, isCapped=%s, mongoClient=%s, mongoDatabase=%s]", + "%s [connectionString=%s, collectionSize=%s, isCapped=%s, mongoClient=%s, mongoDatabase=%s, collectionName=%s]", MongoDb4Provider.class.getSimpleName(), connectionString, collectionSize, isCapped, mongoClient, - mongoDatabase); + mongoDatabase, + collectionName); } } diff --git a/log4j-mongodb4/src/test/java/org/apache/logging/log4j/mongodb4/MongoDb4CollectionNameIT.java b/log4j-mongodb4/src/test/java/org/apache/logging/log4j/mongodb4/MongoDb4CollectionNameIT.java new file mode 100644 index 00000000000..f714ee2eb82 --- /dev/null +++ b/log4j-mongodb4/src/test/java/org/apache/logging/log4j/mongodb4/MongoDb4CollectionNameIT.java @@ -0,0 +1,36 @@ +/* + * 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.mongodb4; + +import com.mongodb.client.MongoClient; +import org.apache.logging.log4j.core.LoggerContext; +import org.apache.logging.log4j.core.test.junit.LoggerContextSource; +import org.apache.logging.log4j.test.junit.UsingStatusListener; +import org.junit.jupiter.api.Test; + +@UsingMongoDb4 +@LoggerContextSource("MongoDb4CollectionNameIT.xml") +// Print debug status logger output upon failure +@UsingStatusListener +class MongoDb4CollectionNameIT extends AbstractMongoDb4CappedIT { + + @Test + @Override + protected void test(LoggerContext ctx, MongoClient mongoClient) { + super.test(ctx, mongoClient); + } +} diff --git a/log4j-mongodb4/src/test/java/org/apache/logging/log4j/mongodb4/MongoDb4DatabaseAndCollectionNameIT.java b/log4j-mongodb4/src/test/java/org/apache/logging/log4j/mongodb4/MongoDb4DatabaseAndCollectionNameIT.java new file mode 100644 index 00000000000..3c06692a64a --- /dev/null +++ b/log4j-mongodb4/src/test/java/org/apache/logging/log4j/mongodb4/MongoDb4DatabaseAndCollectionNameIT.java @@ -0,0 +1,36 @@ +/* + * 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.mongodb4; + +import com.mongodb.client.MongoClient; +import org.apache.logging.log4j.core.LoggerContext; +import org.apache.logging.log4j.core.test.junit.LoggerContextSource; +import org.apache.logging.log4j.test.junit.UsingStatusListener; +import org.junit.jupiter.api.Test; + +@UsingMongoDb4 +@LoggerContextSource("MongoDb4DatabaseAndCollectionNameIT.xml") +// Print debug status logger output upon failure +@UsingStatusListener +class MongoDb4DatabaseAndCollectionNameIT extends AbstractMongoDb4CappedIT { + + @Test + @Override + protected void test(LoggerContext ctx, MongoClient mongoClient) { + super.test(ctx, mongoClient); + } +} diff --git a/log4j-mongodb4/src/test/java/org/apache/logging/log4j/mongodb4/MongoDb4ProviderTest.java b/log4j-mongodb4/src/test/java/org/apache/logging/log4j/mongodb4/MongoDb4ProviderTest.java new file mode 100644 index 00000000000..af38da74d9e --- /dev/null +++ b/log4j-mongodb4/src/test/java/org/apache/logging/log4j/mongodb4/MongoDb4ProviderTest.java @@ -0,0 +1,121 @@ +/* + * 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.mongodb4; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +class MongoDb4ProviderTest { + + private String validConnectionStringWithoutDatabase = "mongodb://localhost:27017"; + private String validConnectionStringWithDatabase = "mongodb://localhost:27017/logging"; + private String validConnectionStringWithDatabaseAndCollection = "mongodb://localhost:27017/logging.logs"; + + private String collectionName = "logsTest"; + private String databaseName = "loggingTest"; + + @Test + void createProviderWithDatabaseAndCollectionProvidedViaConfig() { + + MongoDb4Provider provider = MongoDb4Provider.newBuilder() + .setConnectionStringSource(this.validConnectionStringWithoutDatabase) + .setDatabaseName(this.databaseName) + .setCollectionName(this.collectionName) + .build(); + + assertNotNull(provider, "Returned provider is null"); + assertEquals( + this.collectionName, + provider.getConnection().getCollection().getNamespace().getCollectionName(), + "Collection names do not match"); + assertEquals( + this.databaseName, + provider.getConnection().getCollection().getNamespace().getDatabaseName(), + "Database names do not match"); + } + + @Test + void createProviderWithoutDatabaseName() { + + MongoDb4Provider provider = MongoDb4Provider.newBuilder() + .setConnectionStringSource(this.validConnectionStringWithoutDatabase) + .build(); + + assertNull(provider, "Provider should be null but was not"); + } + + @Test + void createProviderWithoutDatabaseNameWithCollectionName() { + + MongoDb4Provider provider = MongoDb4Provider.newBuilder() + .setConnectionStringSource(this.validConnectionStringWithoutDatabase) + .setCollectionName(this.collectionName) + .build(); + + assertNull(provider, "Provider should be null but was not"); + } + + @Test + void createProviderWithoutCollectionName() { + + MongoDb4Provider provider = MongoDb4Provider.newBuilder() + .setConnectionStringSource(this.validConnectionStringWithoutDatabase) + .setDatabaseName(this.databaseName) + .build(); + + assertNull(provider, "Provider should be null but was not"); + } + + @Test + void createProviderWithDatabaseOnConnectionString() { + MongoDb4Provider provider = MongoDb4Provider.newBuilder() + .setConnectionStringSource(this.validConnectionStringWithDatabase) + .setCollectionName(this.collectionName) + .build(); + + assertNotNull(provider, "Provider should not be null"); + assertEquals( + this.collectionName, + provider.getConnection().getCollection().getNamespace().getCollectionName(), + "Provider should be null but was not"); + assertEquals( + "logging", + provider.getConnection().getCollection().getNamespace().getDatabaseName(), + "Database names do not match"); + } + + @Test + void createProviderConfigOverridesConnectionString() { + + MongoDb4Provider provider = MongoDb4Provider.newBuilder() + .setConnectionStringSource(this.validConnectionStringWithDatabaseAndCollection) + .setCollectionName(this.collectionName) + .setDatabaseName(this.databaseName) + .build(); + + assertNotNull(provider, "Provider should not be null"); + assertEquals( + this.collectionName, + provider.getConnection().getCollection().getNamespace().getCollectionName(), + "Collection name does not match provided configuration"); + assertEquals( + this.databaseName, + provider.getConnection().getCollection().getNamespace().getDatabaseName(), + "Database name does not match provided configuration"); + } +} diff --git a/log4j-mongodb4/src/test/resources/MongoDb4AdditionalFields.xml b/log4j-mongodb4/src/test/resources/MongoDb4AdditionalFields.xml index 6892bcac508..c1766983551 100644 --- a/log4j-mongodb4/src/test/resources/MongoDb4AdditionalFields.xml +++ b/log4j-mongodb4/src/test/resources/MongoDb4AdditionalFields.xml @@ -22,7 +22,9 @@ https://logging.apache.org/xml/ns/log4j-config-2.xsd"> - + diff --git a/log4j-mongodb4/src/test/resources/MongoDb4AuthFailureIT.xml b/log4j-mongodb4/src/test/resources/MongoDb4AuthFailureIT.xml index fa8a46bbebe..a0ee4d3529a 100644 --- a/log4j-mongodb4/src/test/resources/MongoDb4AuthFailureIT.xml +++ b/log4j-mongodb4/src/test/resources/MongoDb4AuthFailureIT.xml @@ -23,7 +23,9 @@ + connection="mongodb://log4jUser:12345678@localhost:${sys:log4j.mongo.port:-27017}/" + databaseName="testDb" + collectionName="MongoDb4AuthFailureIT" /> diff --git a/log4j-mongodb4/src/test/resources/MongoDb4CappedIntIT.xml b/log4j-mongodb4/src/test/resources/MongoDb4CappedIntIT.xml index 2e9a11cb68a..25b338d96c3 100644 --- a/log4j-mongodb4/src/test/resources/MongoDb4CappedIntIT.xml +++ b/log4j-mongodb4/src/test/resources/MongoDb4CappedIntIT.xml @@ -23,9 +23,12 @@ + collectionSize="1073741824" + databaseName="testDb" + collectionName="MongoDb4CappedIntIT" /> + /> diff --git a/log4j-mongodb4/src/test/resources/MongoDb4CappedLongIT.xml b/log4j-mongodb4/src/test/resources/MongoDb4CappedLongIT.xml index b79a4dc59e8..30b50a2fa71 100644 --- a/log4j-mongodb4/src/test/resources/MongoDb4CappedLongIT.xml +++ b/log4j-mongodb4/src/test/resources/MongoDb4CappedLongIT.xml @@ -24,9 +24,11 @@ + collectionSize="2147483657" + databaseName="testDb" + collectionName="MongoDb4CappedLongIT" /> diff --git a/log4j-mongodb4/src/test/resources/MongoDb4CollectionNameIT.xml b/log4j-mongodb4/src/test/resources/MongoDb4CollectionNameIT.xml new file mode 100644 index 00000000000..ef84c991cae --- /dev/null +++ b/log4j-mongodb4/src/test/resources/MongoDb4CollectionNameIT.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + diff --git a/log4j-mongodb4/src/test/resources/MongoDb4DatabaseAndCollectionNameIT.xml b/log4j-mongodb4/src/test/resources/MongoDb4DatabaseAndCollectionNameIT.xml new file mode 100644 index 00000000000..adf32a000d9 --- /dev/null +++ b/log4j-mongodb4/src/test/resources/MongoDb4DatabaseAndCollectionNameIT.xml @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + diff --git a/log4j-mongodb4/src/test/resources/MongoDb4IT.xml b/log4j-mongodb4/src/test/resources/MongoDb4IT.xml index 6ab35f8765a..8431fb7a2be 100644 --- a/log4j-mongodb4/src/test/resources/MongoDb4IT.xml +++ b/log4j-mongodb4/src/test/resources/MongoDb4IT.xml @@ -22,7 +22,9 @@ https://logging.apache.org/xml/ns/log4j-config-2.xsd"> - + diff --git a/log4j-mongodb4/src/test/resources/MongoDb4MapMessageIT.xml b/log4j-mongodb4/src/test/resources/MongoDb4MapMessageIT.xml index 8990a64afcc..813510c63c0 100644 --- a/log4j-mongodb4/src/test/resources/MongoDb4MapMessageIT.xml +++ b/log4j-mongodb4/src/test/resources/MongoDb4MapMessageIT.xml @@ -23,7 +23,9 @@ - + diff --git a/src/changelog/.2.x.x/update_org_log4j_mongodb.xml b/src/changelog/.2.x.x/update_org_log4j_mongodb.xml new file mode 100644 index 00000000000..5d61aded215 --- /dev/null +++ b/src/changelog/.2.x.x/update_org_log4j_mongodb.xml @@ -0,0 +1,8 @@ + + + + Add `collectionName` and `databaseName` arguments to the MongoDB appender + \ No newline at end of file diff --git a/src/site/antora/modules/ROOT/examples/manual/appenders/database/nosql-mongo-keys.json b/src/site/antora/modules/ROOT/examples/manual/appenders/database/nosql-mongo-keys.json index 2b47690c0b5..702a4c3591c 100644 --- a/src/site/antora/modules/ROOT/examples/manual/appenders/database/nosql-mongo-keys.json +++ b/src/site/antora/modules/ROOT/examples/manual/appenders/database/nosql-mongo-keys.json @@ -5,7 +5,9 @@ "NoSql": { "name": "MONGO", "MongoDb": { - "connection": "mongodb://${env:DB_USER}:${env:DB_PASS}@localhost:27017/logging.logs" + "connection": "mongodb://${env:DB_USER}:${env:DB_PASS}@localhost:27017/", + "databaseName": "logging", + "collectionName": "logs" }, "KeyValuePair": [ { diff --git a/src/site/antora/modules/ROOT/examples/manual/appenders/database/nosql-mongo-keys.properties b/src/site/antora/modules/ROOT/examples/manual/appenders/database/nosql-mongo-keys.properties index e0e97ac2872..ba3112e8951 100644 --- a/src/site/antora/modules/ROOT/examples/manual/appenders/database/nosql-mongo-keys.properties +++ b/src/site/antora/modules/ROOT/examples/manual/appenders/database/nosql-mongo-keys.properties @@ -19,7 +19,9 @@ appender.0.type = NoSql appender.0.name = MONGO appender.0.provider.type = MongoDB -appender.0.provider.connection = mongodb://${env:DB_USER}:${env:DB_PASS}@localhost:27017/logging.logs +appender.0.provider.connection = mongodb://${env:DB_USER}:${env:DB_PASS}@localhost:27017 +appender.0.provider.databaseName = logging +appender.0.provider.collectionName = logs appender.0.kv[0].type = KeyValuePair appender.0.kv[0].key = startTime diff --git a/src/site/antora/modules/ROOT/examples/manual/appenders/database/nosql-mongo-keys.xml b/src/site/antora/modules/ROOT/examples/manual/appenders/database/nosql-mongo-keys.xml index cd9f458ac3a..fc4e3b06972 100644 --- a/src/site/antora/modules/ROOT/examples/manual/appenders/database/nosql-mongo-keys.xml +++ b/src/site/antora/modules/ROOT/examples/manual/appenders/database/nosql-mongo-keys.xml @@ -23,7 +23,9 @@ - + diff --git a/src/site/antora/modules/ROOT/examples/manual/appenders/database/nosql-mongo-keys.yaml b/src/site/antora/modules/ROOT/examples/manual/appenders/database/nosql-mongo-keys.yaml index 2cb5df2c85f..1b286eec629 100644 --- a/src/site/antora/modules/ROOT/examples/manual/appenders/database/nosql-mongo-keys.yaml +++ b/src/site/antora/modules/ROOT/examples/manual/appenders/database/nosql-mongo-keys.yaml @@ -20,7 +20,9 @@ Configuration: NoSql: name: "MONGO" MongoDb: - connection: "mongodb://${env:DB_USER}:${env:DB_PASS}@localhost:27017/logging.logs" + connection: "mongodb://${env:DB_USER}:${env:DB_PASS}@localhost:27017/" + databaseName: "logging" + collectionName: "logs" KeyValuePair: - key: "startTime" value: "${date:yyyy-MM-dd hh:mm:ss.SSS}" # <1> diff --git a/src/site/antora/modules/ROOT/examples/manual/appenders/database/nosql-mongo.json b/src/site/antora/modules/ROOT/examples/manual/appenders/database/nosql-mongo.json index d06b3a190f6..b8bd82389e6 100644 --- a/src/site/antora/modules/ROOT/examples/manual/appenders/database/nosql-mongo.json +++ b/src/site/antora/modules/ROOT/examples/manual/appenders/database/nosql-mongo.json @@ -10,7 +10,9 @@ "NoSql": { "name": "MONGO", "MongoDb": { - "connection": "mongodb://${env:DB_USER}:${env:DB_PASS}@localhost:27017/logging.logs" + "connection": "mongodb://${env:DB_USER}:${env:DB_PASS}@localhost:27017/", + "databaseName": "logging", + "collectionName": "logs" } } // end::appender[] diff --git a/src/site/antora/modules/ROOT/examples/manual/appenders/database/nosql-mongo.properties b/src/site/antora/modules/ROOT/examples/manual/appenders/database/nosql-mongo.properties index 6a1e188310c..ab06837d8b9 100644 --- a/src/site/antora/modules/ROOT/examples/manual/appenders/database/nosql-mongo.properties +++ b/src/site/antora/modules/ROOT/examples/manual/appenders/database/nosql-mongo.properties @@ -22,7 +22,9 @@ appender.0.layout.type = JsonTemplateLayout appender.1.type = NoSql appender.1.name = MONGO appender.1.provider.type = MongoDB -appender.1.provider.connection = mongodb://${env:DB_USER}:${env:DB_PASS}@localhost:27017/logging.logs +appender.1.provider.connection = mongodb://${env:DB_USER}:${env:DB_PASS}@localhost:27017/ +appender.1.provider.databaseName = logging +appender.1.provider.collectionName = logs # end::appender[] # tag::loggers[] rootLogger.level = INFO diff --git a/src/site/antora/modules/ROOT/examples/manual/appenders/database/nosql-mongo.xml b/src/site/antora/modules/ROOT/examples/manual/appenders/database/nosql-mongo.xml index 31fe89f2f19..d5a22a1134b 100644 --- a/src/site/antora/modules/ROOT/examples/manual/appenders/database/nosql-mongo.xml +++ b/src/site/antora/modules/ROOT/examples/manual/appenders/database/nosql-mongo.xml @@ -27,7 +27,9 @@ - + diff --git a/src/site/antora/modules/ROOT/examples/manual/appenders/database/nosql-mongo.yaml b/src/site/antora/modules/ROOT/examples/manual/appenders/database/nosql-mongo.yaml index f5bd4b66121..86874f8d1a6 100644 --- a/src/site/antora/modules/ROOT/examples/manual/appenders/database/nosql-mongo.yaml +++ b/src/site/antora/modules/ROOT/examples/manual/appenders/database/nosql-mongo.yaml @@ -24,7 +24,9 @@ Configuration: NoSql: name: "MONGO" MongoDb: - connection: "mongodb://${env:DB_USER}:${env:DB_PASS}@localhost:27017/logging.logs" + connection: "mongodb://${env:DB_USER}:${env:DB_PASS}@localhost:27017/" + databaseName: "logging" + collectionName: "logs" # end::appender[] Loggers: # tag::loggers[] diff --git a/src/site/antora/modules/ROOT/pages/manual/appenders/database.adoc b/src/site/antora/modules/ROOT/pages/manual/appenders/database.adoc index cf42f454d9a..1fb6c813d5c 100644 --- a/src/site/antora/modules/ROOT/pages/manual/appenders/database.adoc +++ b/src/site/antora/modules/ROOT/pages/manual/appenders/database.adoc @@ -1175,6 +1175,26 @@ for its format. **Required** +| [[MongoDbProvider-attr-databaseName]]databaseName +| `string` +| +| +It specifies the name of the database for the appender to use + +Overrides the value provided in the connection string if present + +**Required** + +| [[MongoDbProvider-attr-collectionName]]collectionName +| `string` +| +| +It specifies the name of the collection for the appender to use +For backward compatibility, the collection name can also be specified in the +https://mongodb.github.io/mongo-java-driver/5.0/apidocs/mongodb-driver-core/com/mongodb/ConnectionString.html[Java-specific connection string] + +**Required** + | [[MongoDbProvider-attr-capped]]capped | `boolean` | `false` From 821b77f1e8e70cc4b94292b7e6499a20096f6570 Mon Sep 17 00:00:00 2001 From: Josh Smith Date: Fri, 14 Feb 2025 23:19:13 -0600 Subject: [PATCH 02/27] Fixed some details in unit tests --- .../MongoDbNoDatabaseAndCollectionNameIT.java | 36 +++++++++ .../MongoDbNoDatabaseAndCollectionNameIT.xml | 37 +++++++++ .../log4j/mongodb4/MongoDb4ProviderTest.java | 76 +++++++++---------- 3 files changed, 108 insertions(+), 41 deletions(-) create mode 100644 log4j-mongodb/src/test/java/org/apache/logging/log4j/mongodb/MongoDbNoDatabaseAndCollectionNameIT.java create mode 100644 log4j-mongodb/src/test/resources/MongoDbNoDatabaseAndCollectionNameIT.xml diff --git a/log4j-mongodb/src/test/java/org/apache/logging/log4j/mongodb/MongoDbNoDatabaseAndCollectionNameIT.java b/log4j-mongodb/src/test/java/org/apache/logging/log4j/mongodb/MongoDbNoDatabaseAndCollectionNameIT.java new file mode 100644 index 00000000000..ba6a654fdb9 --- /dev/null +++ b/log4j-mongodb/src/test/java/org/apache/logging/log4j/mongodb/MongoDbNoDatabaseAndCollectionNameIT.java @@ -0,0 +1,36 @@ +/* + * 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.mongodb; + +import com.mongodb.client.MongoClient; +import org.apache.logging.log4j.core.LoggerContext; +import org.apache.logging.log4j.core.test.junit.LoggerContextSource; +import org.apache.logging.log4j.test.junit.UsingStatusListener; +import org.junit.jupiter.api.Test; + +@UsingMongoDb +@LoggerContextSource("MongoDbNoDatabaseAndCollectionNameIT.xml") +// Print debug status logger output upon failure +@UsingStatusListener +class MongoDbNoDatabaseAndCollectionNameIT extends AbstractMongoDbCappedIT { + + @Test + @Override + protected void test(LoggerContext ctx, MongoClient mongoClient) { + super.test(ctx, mongoClient); + } +} diff --git a/log4j-mongodb/src/test/resources/MongoDbNoDatabaseAndCollectionNameIT.xml b/log4j-mongodb/src/test/resources/MongoDbNoDatabaseAndCollectionNameIT.xml new file mode 100644 index 00000000000..56fd03ab9f4 --- /dev/null +++ b/log4j-mongodb/src/test/resources/MongoDbNoDatabaseAndCollectionNameIT.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + diff --git a/log4j-mongodb4/src/test/java/org/apache/logging/log4j/mongodb4/MongoDb4ProviderTest.java b/log4j-mongodb4/src/test/java/org/apache/logging/log4j/mongodb4/MongoDb4ProviderTest.java index af38da74d9e..611914ad9cf 100644 --- a/log4j-mongodb4/src/test/java/org/apache/logging/log4j/mongodb4/MongoDb4ProviderTest.java +++ b/log4j-mongodb4/src/test/java/org/apache/logging/log4j/mongodb4/MongoDb4ProviderTest.java @@ -22,100 +22,94 @@ class MongoDb4ProviderTest { - private String validConnectionStringWithoutDatabase = "mongodb://localhost:27017"; - private String validConnectionStringWithDatabase = "mongodb://localhost:27017/logging"; - private String validConnectionStringWithDatabaseAndCollection = "mongodb://localhost:27017/logging.logs"; + private static final String CON_STR_WO_DB = "mongodb://localhost:27017"; + private static final String CON_STR_W_DB = "mongodb://localhost:27017/logging"; + private static final String CON_STR_DB_COLL = "mongodb://localhost:27017/logging.logs"; - private String collectionName = "logsTest"; - private String databaseName = "loggingTest"; + private static final String collectionName = "logsTest"; + private static final String databaseName = "loggingTest"; @Test void createProviderWithDatabaseAndCollectionProvidedViaConfig() { MongoDb4Provider provider = MongoDb4Provider.newBuilder() - .setConnectionStringSource(this.validConnectionStringWithoutDatabase) - .setDatabaseName(this.databaseName) - .setCollectionName(this.collectionName) + .setConnectionStringSource(CON_STR_WO_DB) + .setDatabaseName(databaseName) + .setCollectionName(collectionName) .build(); - assertNotNull(provider, "Returned provider is null"); + assertNotNull(provider); assertEquals( - this.collectionName, - provider.getConnection().getCollection().getNamespace().getCollectionName(), - "Collection names do not match"); + collectionName, + provider.getConnection().getCollection().getNamespace().getCollectionName()); assertEquals( - this.databaseName, - provider.getConnection().getCollection().getNamespace().getDatabaseName(), - "Database names do not match"); + databaseName, + provider.getConnection().getCollection().getNamespace().getDatabaseName()); } @Test void createProviderWithoutDatabaseName() { MongoDb4Provider provider = MongoDb4Provider.newBuilder() - .setConnectionStringSource(this.validConnectionStringWithoutDatabase) + .setConnectionStringSource(CON_STR_WO_DB) .build(); - assertNull(provider, "Provider should be null but was not"); + assertNull(provider); } @Test void createProviderWithoutDatabaseNameWithCollectionName() { MongoDb4Provider provider = MongoDb4Provider.newBuilder() - .setConnectionStringSource(this.validConnectionStringWithoutDatabase) - .setCollectionName(this.collectionName) + .setConnectionStringSource(CON_STR_WO_DB) + .setCollectionName(collectionName) .build(); - assertNull(provider, "Provider should be null but was not"); + assertNull(provider); } @Test void createProviderWithoutCollectionName() { MongoDb4Provider provider = MongoDb4Provider.newBuilder() - .setConnectionStringSource(this.validConnectionStringWithoutDatabase) - .setDatabaseName(this.databaseName) + .setConnectionStringSource(CON_STR_WO_DB) + .setDatabaseName(databaseName) .build(); - assertNull(provider, "Provider should be null but was not"); + assertNull(provider); } @Test void createProviderWithDatabaseOnConnectionString() { MongoDb4Provider provider = MongoDb4Provider.newBuilder() - .setConnectionStringSource(this.validConnectionStringWithDatabase) - .setCollectionName(this.collectionName) + .setConnectionStringSource(CON_STR_W_DB) + .setCollectionName(collectionName) .build(); - assertNotNull(provider, "Provider should not be null"); + assertNotNull(provider); assertEquals( - this.collectionName, - provider.getConnection().getCollection().getNamespace().getCollectionName(), - "Provider should be null but was not"); + collectionName, + provider.getConnection().getCollection().getNamespace().getCollectionName()); assertEquals( "logging", - provider.getConnection().getCollection().getNamespace().getDatabaseName(), - "Database names do not match"); + provider.getConnection().getCollection().getNamespace().getDatabaseName()); } @Test void createProviderConfigOverridesConnectionString() { MongoDb4Provider provider = MongoDb4Provider.newBuilder() - .setConnectionStringSource(this.validConnectionStringWithDatabaseAndCollection) - .setCollectionName(this.collectionName) - .setDatabaseName(this.databaseName) + .setConnectionStringSource(CON_STR_DB_COLL) + .setCollectionName(collectionName) + .setDatabaseName(databaseName) .build(); - assertNotNull(provider, "Provider should not be null"); + assertNotNull(provider); assertEquals( - this.collectionName, - provider.getConnection().getCollection().getNamespace().getCollectionName(), - "Collection name does not match provided configuration"); + collectionName, + provider.getConnection().getCollection().getNamespace().getCollectionName()); assertEquals( - this.databaseName, - provider.getConnection().getCollection().getNamespace().getDatabaseName(), - "Database name does not match provided configuration"); + databaseName, + provider.getConnection().getCollection().getNamespace().getDatabaseName()); } } From 8c0e3c6c4f32ba97985efc05286e5425bfe36742 Mon Sep 17 00:00:00 2001 From: Suvrat Acharya <140749446+Suvrat1629@users.noreply.github.com> Date: Sun, 16 Feb 2025 13:59:16 +0530 Subject: [PATCH 03/27] Improve configuration error handling of HttpAppender (#3438) This PR introduces improvements to `HttpAppender` and adds a new test class, `HttpAppenderBuilderTest`, to enhance test coverage. The changes include: * Updating `HttpAppender` to improve validating behavior. * Adding HttpAppenderBuilderTest.java to verify the builder logic for HttpAppender. Ensuring that missing configurations (e.g., URL, Layout) correctly log errors. Co-authored-by: Piotr P. Karwasz --- .../appender/HttpAppenderBuilderTest.java | 130 ++++++++++++++++++ .../log4j/core/appender/HttpAppender.java | 24 +++- .../.2.x.x/3011_http_appender_validation.xml | 8 ++ 3 files changed, 155 insertions(+), 7 deletions(-) create mode 100644 log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/HttpAppenderBuilderTest.java create mode 100644 src/changelog/.2.x.x/3011_http_appender_validation.xml diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/HttpAppenderBuilderTest.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/HttpAppenderBuilderTest.java new file mode 100644 index 00000000000..2680961d19c --- /dev/null +++ b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/HttpAppenderBuilderTest.java @@ -0,0 +1,130 @@ +/* + * 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; + +import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import java.net.MalformedURLException; +import java.net.URL; +import org.apache.logging.log4j.Level; +import org.apache.logging.log4j.core.Layout; +import org.apache.logging.log4j.core.config.Configuration; +import org.apache.logging.log4j.core.config.DefaultConfiguration; +import org.apache.logging.log4j.core.config.Property; +import org.apache.logging.log4j.core.layout.JsonLayout; +import org.apache.logging.log4j.core.net.ssl.SslConfiguration; +import org.apache.logging.log4j.test.ListStatusListener; +import org.apache.logging.log4j.test.junit.UsingStatusListener; +import org.junit.jupiter.api.Test; + +class HttpAppenderBuilderTest { + + private HttpAppender.Builder getBuilder() { + Configuration mockConfig = new DefaultConfiguration(); + return HttpAppender.newBuilder().setConfiguration(mockConfig).setName("TestHttpAppender"); // Name is required + } + + @Test + @UsingStatusListener + void testBuilderWithoutUrl(final ListStatusListener listener) throws Exception { + HttpAppender appender = HttpAppender.newBuilder() + .setConfiguration(new DefaultConfiguration()) + .setName("TestAppender") + .setLayout(JsonLayout.createDefaultLayout()) // Providing a layout here + .build(); + + assertThat(listener.findStatusData(Level.ERROR)) + .anyMatch(statusData -> + statusData.getMessage().getFormattedMessage().contains("HttpAppender requires URL to be set.")); + } + + @Test + @UsingStatusListener + void testBuilderWithUrlAndWithoutLayout(final ListStatusListener listener) throws Exception { + HttpAppender appender = HttpAppender.newBuilder() + .setConfiguration(new DefaultConfiguration()) + .setName("TestAppender") + .setUrl(new URL("http://localhost:8080/logs")) + .build(); + + assertThat(listener.findStatusData(Level.ERROR)).anyMatch(statusData -> statusData + .getMessage() + .getFormattedMessage() + .contains("HttpAppender requires a layout to be set.")); + } + + @Test + void testBuilderWithValidConfiguration() throws Exception { + URL url = new URL("http://example.com"); + Layout layout = JsonLayout.createDefaultLayout(); + + HttpAppender.Builder builder = getBuilder().setUrl(url).setLayout(layout); + + HttpAppender appender = builder.build(); + assertNotNull(appender, "HttpAppender should be created with valid configuration."); + } + + @Test + void testBuilderWithCustomMethod() throws Exception { + URL url = new URL("http://example.com"); + Layout layout = JsonLayout.createDefaultLayout(); + String customMethod = "PUT"; + + HttpAppender.Builder builder = + getBuilder().setUrl(url).setLayout(layout).setMethod(customMethod); + + HttpAppender appender = builder.build(); + assertNotNull(appender, "HttpAppender should be created with a custom HTTP method."); + } + + @Test + void testBuilderWithHeaders() throws Exception { + URL url = new URL("http://example.com"); + Layout layout = JsonLayout.createDefaultLayout(); + Property[] headers = new Property[] { + Property.createProperty("Header1", "Value1"), Property.createProperty("Header2", "Value2") + }; + + HttpAppender.Builder builder = + getBuilder().setUrl(url).setLayout(layout).setHeaders(headers); + + HttpAppender appender = builder.build(); + assertNotNull(appender, "HttpAppender should be created with headers."); + } + + @Test + void testBuilderWithSslConfiguration() throws Exception { + URL url = new URL("https://example.com"); + Layout layout = JsonLayout.createDefaultLayout(); + + // Use real SslConfiguration instead of Mockito mock + SslConfiguration sslConfig = SslConfiguration.createSSLConfiguration(null, null, null, false); + + HttpAppender.Builder builder = + getBuilder().setUrl(url).setLayout(layout).setSslConfiguration(sslConfig); + + HttpAppender appender = builder.build(); + assertNotNull(appender, "HttpAppender should be created with SSL configuration."); + } + + @Test + void testBuilderWithInvalidUrl() { + assertThrows(MalformedURLException.class, () -> new URL("invalid-url")); + } +} diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/HttpAppender.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/HttpAppender.java index b24e165b3e1..56d1ffb5e37 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/HttpAppender.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/HttpAppender.java @@ -32,16 +32,15 @@ import org.apache.logging.log4j.core.config.plugins.PluginElement; import org.apache.logging.log4j.core.config.plugins.validation.constraints.Required; import org.apache.logging.log4j.core.net.ssl.SslConfiguration; +import org.apache.logging.log4j.status.StatusLogger; -/** - * Sends log events over HTTP. - */ @Plugin(name = "Http", category = Node.CATEGORY, elementType = Appender.ELEMENT_TYPE, printObject = true) public final class HttpAppender extends AbstractAppender { + private static final StatusLogger LOGGER = StatusLogger.getLogger(); + /** * Builds HttpAppender instances. - * @param The type to build */ public static class Builder> extends AbstractAppender.Builder implements org.apache.logging.log4j.core.util.Builder { @@ -70,6 +69,18 @@ public static class Builder> extends AbstractAppender.Build @Override public HttpAppender build() { + // Validate URL presence + if (url == null) { + LOGGER.error("HttpAppender requires URL to be set."); + return null; // Return null if URL is missing + } + + // Validate layout presence + if (getLayout() == null) { + LOGGER.error("HttpAppender requires a layout to be set."); + return null; // Return null if layout is missing + } + final HttpManager httpManager = new HttpURLConnectionManager( getConfiguration(), getConfiguration().getLoggerContext(), @@ -81,10 +92,12 @@ public HttpAppender build() { headers, sslConfiguration, verifyHostname); + return new HttpAppender( getName(), getLayout(), getFilter(), isIgnoreExceptions(), httpManager, getPropertyArray()); } + // Getter and Setter methods public URL getUrl() { return url; } @@ -149,9 +162,6 @@ public B setVerifyHostname(final boolean verifyHostname) { } } - /** - * @return a builder for a HttpAppender. - */ @PluginBuilderFactory public static > B newBuilder() { return new Builder().asBuilder(); diff --git a/src/changelog/.2.x.x/3011_http_appender_validation.xml b/src/changelog/.2.x.x/3011_http_appender_validation.xml new file mode 100644 index 00000000000..5038a378d17 --- /dev/null +++ b/src/changelog/.2.x.x/3011_http_appender_validation.xml @@ -0,0 +1,8 @@ + + + + Improves validation of HTTP Appender. + From 180b050fd913490bc32ad024a2145359e23f6426 Mon Sep 17 00:00:00 2001 From: Josh Smith Date: Sun, 16 Feb 2025 08:31:01 -0600 Subject: [PATCH 04/27] Removed wildcard imports from tests --- .../apache/logging/log4j/mongodb4/MongoDb4ProviderTest.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/log4j-mongodb4/src/test/java/org/apache/logging/log4j/mongodb4/MongoDb4ProviderTest.java b/log4j-mongodb4/src/test/java/org/apache/logging/log4j/mongodb4/MongoDb4ProviderTest.java index 611914ad9cf..6c12c737b63 100644 --- a/log4j-mongodb4/src/test/java/org/apache/logging/log4j/mongodb4/MongoDb4ProviderTest.java +++ b/log4j-mongodb4/src/test/java/org/apache/logging/log4j/mongodb4/MongoDb4ProviderTest.java @@ -18,7 +18,9 @@ import org.junit.jupiter.api.Test; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; class MongoDb4ProviderTest { From 82b30c53e0e28d546af6901d279b72a7ca081efc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Volkan=20Yaz=C4=B1c=C4=B1?= Date: Mon, 17 Feb 2025 22:01:04 +0100 Subject: [PATCH 05/27] Improve `database.adoc` --- .../ROOT/pages/manual/appenders/database.adoc | 24 +++++++------------ 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/src/site/antora/modules/ROOT/pages/manual/appenders/database.adoc b/src/site/antora/modules/ROOT/pages/manual/appenders/database.adoc index 1fb6c813d5c..901c37ba25a 100644 --- a/src/site/antora/modules/ROOT/pages/manual/appenders/database.adoc +++ b/src/site/antora/modules/ROOT/pages/manual/appenders/database.adoc @@ -1164,24 +1164,21 @@ It supports the following configuration options: | Attribute | Type | Default value | Description | [[MongoDbProvider-attr-connection]]connection -| https://mongodb.github.io/mongo-java-driver/5.1/apidocs/mongodb-driver-core/com/mongodb/ConnectionString.html[`ConnectionString`] +| https://www.mongodb.com/docs/manual/reference/connection-string/#standard-connection-string-format[Connection String] | | It specifies the connection URI used to reach the server. -See -https://www.mongodb.com/docs/drivers/java/sync/current/fundamentals/connection/connect/#connection-uri[Connection URI documentation] -for its format. - **Required** | [[MongoDbProvider-attr-databaseName]]databaseName | `string` | | -It specifies the name of the database for the appender to use +It specifies the name of the database for the appender to use. -Overrides the value provided in the connection string if present +The database name can also be specified in <>. +If both are provided, this `databaseName` attribute will be used. **Required** @@ -1189,9 +1186,10 @@ Overrides the value provided in the connection string if present | `string` | | -It specifies the name of the collection for the appender to use -For backward compatibility, the collection name can also be specified in the -https://mongodb.github.io/mongo-java-driver/5.0/apidocs/mongodb-driver-core/com/mongodb/ConnectionString.html[Java-specific connection string] +It specifies the name of the collection for the appender to use. + +For backward compatibility, the collection name can also be specified in <> per https://mongodb.github.io/mongo-java-driver/5.3/apidocs/mongodb-driver-core/com/mongodb/ConnectionString.html[`ConnectionString` of the MongoDB Java Driver]. +If both are provided, this `collectionName` attribute will be used. **Required** @@ -1230,15 +1228,11 @@ It supports the following configuration attributes: | Attribute | Type | Default value | Description | [[MongoDb4Provider-attr-connection]]connection -| https://mongodb.github.io/mongo-java-driver/5.1/apidocs/mongodb-driver-core/com/mongodb/ConnectionString.html[`ConnectionString`] +| https://mongodb.github.io/mongo-java-driver/5.3/apidocs/mongodb-driver-core/com/mongodb/ConnectionString.html[`ConnectionString`] | | It specifies the connection URI used to reach the server. -See -https://www.mongodb.com/docs/drivers/java/sync/current/fundamentals/connection/connect/#connection-uri[Connection URI documentation] -for its format. - **Required** | [[MongoDb4Provider-attr-capped]]capped From 1c2bcf8fd96c566768544373a9e79a27d7b87419 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Volkan=20Yaz=C4=B1c=C4=B1?= Date: Mon, 17 Feb 2025 22:06:44 +0100 Subject: [PATCH 06/27] Fix changelog entry --- ...rg_log4j_mongodb.xml => 3467_add_mongodb_conn_db_name.xml} | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) rename src/changelog/.2.x.x/{update_org_log4j_mongodb.xml => 3467_add_mongodb_conn_db_name.xml} (82%) diff --git a/src/changelog/.2.x.x/update_org_log4j_mongodb.xml b/src/changelog/.2.x.x/3467_add_mongodb_conn_db_name.xml similarity index 82% rename from src/changelog/.2.x.x/update_org_log4j_mongodb.xml rename to src/changelog/.2.x.x/3467_add_mongodb_conn_db_name.xml index 5d61aded215..ecf5d7e625b 100644 --- a/src/changelog/.2.x.x/update_org_log4j_mongodb.xml +++ b/src/changelog/.2.x.x/3467_add_mongodb_conn_db_name.xml @@ -3,6 +3,6 @@ xmlns="https://logging.apache.org/xml/ns" xsi:schemaLocation="https://logging.apache.org/xml/ns https://logging.apache.org/xml/ns/log4j-changelog-0.xsd" type="added"> - + Add `collectionName` and `databaseName` arguments to the MongoDB appender - \ No newline at end of file + From 140aa29cf10b28d73c5983886c390c4224d0354d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Volkan=20Yaz=C4=B1c=C4=B1?= Date: Mon, 17 Feb 2025 22:13:40 +0100 Subject: [PATCH 07/27] Fix XSD versions --- log4j-mongodb/src/test/resources/MongoDbCollectionNameIT.xml | 2 +- .../src/test/resources/MongoDbDatabaseAndCollectionNameIT.xml | 2 +- .../src/test/resources/MongoDbNoDatabaseAndCollectionNameIT.xml | 2 +- log4j-mongodb4/src/test/resources/MongoDb4CollectionNameIT.xml | 2 +- .../src/test/resources/MongoDb4DatabaseAndCollectionNameIT.xml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/log4j-mongodb/src/test/resources/MongoDbCollectionNameIT.xml b/log4j-mongodb/src/test/resources/MongoDbCollectionNameIT.xml index ef84c991cae..4b9b53842ed 100644 --- a/log4j-mongodb/src/test/resources/MongoDbCollectionNameIT.xml +++ b/log4j-mongodb/src/test/resources/MongoDbCollectionNameIT.xml @@ -19,7 +19,7 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" https://logging.apache.org/xml/ns - https://logging.apache.org/xml/ns/log4j-config-3.xsd"> + https://logging.apache.org/xml/ns/log4j-config-2.xsd"> + https://logging.apache.org/xml/ns/log4j-config-2.xsd"> + https://logging.apache.org/xml/ns/log4j-config-2.xsd"> + https://logging.apache.org/xml/ns/log4j-config-2.xsd"> + https://logging.apache.org/xml/ns/log4j-config-2.xsd"> Date: Mon, 17 Feb 2025 22:14:01 +0100 Subject: [PATCH 08/27] Revert changes to resources of old tests --- .../src/test/resources/MongoDb4AdditionalFields.xml | 4 +--- .../src/test/resources/MongoDb4AuthFailureIT.xml | 4 +--- log4j-mongodb4/src/test/resources/MongoDb4CappedIntIT.xml | 7 ++----- log4j-mongodb4/src/test/resources/MongoDb4CappedLongIT.xml | 6 ++---- log4j-mongodb4/src/test/resources/MongoDb4IT.xml | 4 +--- log4j-mongodb4/src/test/resources/MongoDb4MapMessageIT.xml | 4 +--- 6 files changed, 8 insertions(+), 21 deletions(-) diff --git a/log4j-mongodb4/src/test/resources/MongoDb4AdditionalFields.xml b/log4j-mongodb4/src/test/resources/MongoDb4AdditionalFields.xml index c1766983551..6892bcac508 100644 --- a/log4j-mongodb4/src/test/resources/MongoDb4AdditionalFields.xml +++ b/log4j-mongodb4/src/test/resources/MongoDb4AdditionalFields.xml @@ -22,9 +22,7 @@ https://logging.apache.org/xml/ns/log4j-config-2.xsd"> - + diff --git a/log4j-mongodb4/src/test/resources/MongoDb4AuthFailureIT.xml b/log4j-mongodb4/src/test/resources/MongoDb4AuthFailureIT.xml index a0ee4d3529a..fa8a46bbebe 100644 --- a/log4j-mongodb4/src/test/resources/MongoDb4AuthFailureIT.xml +++ b/log4j-mongodb4/src/test/resources/MongoDb4AuthFailureIT.xml @@ -23,9 +23,7 @@ + connection="mongodb://log4jUser:12345678@localhost:${sys:log4j.mongo.port:-27017}/testDb.MongoDb4AuthFailureIT" /> diff --git a/log4j-mongodb4/src/test/resources/MongoDb4CappedIntIT.xml b/log4j-mongodb4/src/test/resources/MongoDb4CappedIntIT.xml index 25b338d96c3..2e9a11cb68a 100644 --- a/log4j-mongodb4/src/test/resources/MongoDb4CappedIntIT.xml +++ b/log4j-mongodb4/src/test/resources/MongoDb4CappedIntIT.xml @@ -23,12 +23,9 @@ - /> + collectionSize="1073741824"/> diff --git a/log4j-mongodb4/src/test/resources/MongoDb4CappedLongIT.xml b/log4j-mongodb4/src/test/resources/MongoDb4CappedLongIT.xml index 30b50a2fa71..b79a4dc59e8 100644 --- a/log4j-mongodb4/src/test/resources/MongoDb4CappedLongIT.xml +++ b/log4j-mongodb4/src/test/resources/MongoDb4CappedLongIT.xml @@ -24,11 +24,9 @@ + collectionSize="2147483657"/> diff --git a/log4j-mongodb4/src/test/resources/MongoDb4IT.xml b/log4j-mongodb4/src/test/resources/MongoDb4IT.xml index 8431fb7a2be..6ab35f8765a 100644 --- a/log4j-mongodb4/src/test/resources/MongoDb4IT.xml +++ b/log4j-mongodb4/src/test/resources/MongoDb4IT.xml @@ -22,9 +22,7 @@ https://logging.apache.org/xml/ns/log4j-config-2.xsd"> - + diff --git a/log4j-mongodb4/src/test/resources/MongoDb4MapMessageIT.xml b/log4j-mongodb4/src/test/resources/MongoDb4MapMessageIT.xml index 813510c63c0..8990a64afcc 100644 --- a/log4j-mongodb4/src/test/resources/MongoDb4MapMessageIT.xml +++ b/log4j-mongodb4/src/test/resources/MongoDb4MapMessageIT.xml @@ -23,9 +23,7 @@ - + From eac41a5c4029a859de704b050346f30ab161b544 Mon Sep 17 00:00:00 2001 From: Josh Smith Date: Tue, 18 Feb 2025 07:16:11 -0600 Subject: [PATCH 09/27] Fixed formatting --- .../logging/log4j/mongodb4/MongoDb4Connection.java | 3 +-- .../logging/log4j/mongodb4/MongoDb4Provider.java | 12 ++++++++---- .../logging/log4j/mongodb4/MongoDb4ProviderTest.java | 4 ++-- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/log4j-mongodb4/src/main/java/org/apache/logging/log4j/mongodb4/MongoDb4Connection.java b/log4j-mongodb4/src/main/java/org/apache/logging/log4j/mongodb4/MongoDb4Connection.java index 1a202e43d99..d3d3b572450 100644 --- a/log4j-mongodb4/src/main/java/org/apache/logging/log4j/mongodb4/MongoDb4Connection.java +++ b/log4j-mongodb4/src/main/java/org/apache/logging/log4j/mongodb4/MongoDb4Connection.java @@ -82,8 +82,7 @@ public MongoDb4Connection( final Long sizeInBytes) { this.connectionString = connectionString; this.mongoClient = mongoClient; - this.collection = - getOrCreateMongoCollection(mongoDatabase, collectionName, isCapped, sizeInBytes); + this.collection = getOrCreateMongoCollection(mongoDatabase, collectionName, isCapped, sizeInBytes); } @Override diff --git a/log4j-mongodb4/src/main/java/org/apache/logging/log4j/mongodb4/MongoDb4Provider.java b/log4j-mongodb4/src/main/java/org/apache/logging/log4j/mongodb4/MongoDb4Provider.java index 0cd4d1cebf0..349e22f91c2 100644 --- a/log4j-mongodb4/src/main/java/org/apache/logging/log4j/mongodb4/MongoDb4Provider.java +++ b/log4j-mongodb4/src/main/java/org/apache/logging/log4j/mongodb4/MongoDb4Provider.java @@ -67,8 +67,6 @@ public static class Builder> extends AbstractFilterable.Bui @PluginBuilderAttribute("databaseName") private String databaseName; - - @Override public MongoDb4Provider build() { StatusLogger.getLogger().warn("The {} Appender is deprecated, use the MongoDb Appender.", PLUGIN_NAME); @@ -201,7 +199,12 @@ public static > B newBuilder() { private final MongoDatabase mongoDatabase; private final ConnectionString connectionString; - private MongoDb4Provider(final String connectionStringSource, final String databaseName, final String collectionName, final boolean isCapped, final Long collectionSize) { + private MongoDb4Provider( + final String connectionStringSource, + final String databaseName, + final String collectionName, + final boolean isCapped, + final Long collectionSize) { LOGGER.debug("Creating ConnectionString {}...", connectionStringSource); this.connectionString = new ConnectionString(connectionStringSource); LOGGER.debug("Created ConnectionString {}", connectionString); @@ -226,7 +229,8 @@ private MongoDb4Provider(final String connectionStringSource, final String datab @Override public MongoDb4Connection getConnection() { - return new MongoDb4Connection(connectionString, mongoClient, mongoDatabase, collectionName, isCapped, collectionSize); + return new MongoDb4Connection( + connectionString, mongoClient, mongoDatabase, collectionName, isCapped, collectionSize); } @Override diff --git a/log4j-mongodb4/src/test/java/org/apache/logging/log4j/mongodb4/MongoDb4ProviderTest.java b/log4j-mongodb4/src/test/java/org/apache/logging/log4j/mongodb4/MongoDb4ProviderTest.java index 6c12c737b63..9a35f07b4a2 100644 --- a/log4j-mongodb4/src/test/java/org/apache/logging/log4j/mongodb4/MongoDb4ProviderTest.java +++ b/log4j-mongodb4/src/test/java/org/apache/logging/log4j/mongodb4/MongoDb4ProviderTest.java @@ -16,12 +16,12 @@ */ package org.apache.logging.log4j.mongodb4; -import org.junit.jupiter.api.Test; - import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; +import org.junit.jupiter.api.Test; + class MongoDb4ProviderTest { private static final String CON_STR_WO_DB = "mongodb://localhost:27017"; From 01d0b8131187429a16849daef3cf872174e61bd4 Mon Sep 17 00:00:00 2001 From: Josh Smith Date: Tue, 18 Feb 2025 08:05:30 -0600 Subject: [PATCH 10/27] Fixed constructors to prevent potential backwards compat issues --- .../log4j/mongodb4/MongoDb4Connection.java | 29 +++++++ .../log4j/mongodb4/MongoDb4Provider.java | 79 ++++++++++++++++++- .../log4j/mongodb4/MongoDb4ProviderTest.java | 35 +++++--- 3 files changed, 128 insertions(+), 15 deletions(-) diff --git a/log4j-mongodb4/src/main/java/org/apache/logging/log4j/mongodb4/MongoDb4Connection.java b/log4j-mongodb4/src/main/java/org/apache/logging/log4j/mongodb4/MongoDb4Connection.java index d3d3b572450..ed7989275c0 100644 --- a/log4j-mongodb4/src/main/java/org/apache/logging/log4j/mongodb4/MongoDb4Connection.java +++ b/log4j-mongodb4/src/main/java/org/apache/logging/log4j/mongodb4/MongoDb4Connection.java @@ -85,6 +85,35 @@ public MongoDb4Connection( this.collection = getOrCreateMongoCollection(mongoDatabase, collectionName, isCapped, sizeInBytes); } + @Deprecated + public MongoDb4Connection( + final ConnectionString connectionString, + final MongoClient mongoClient, + final MongoDatabase mongoDatabase, + final boolean isCapped, + final Long sizeInBytes) { + this.connectionString = connectionString; + this.mongoClient = mongoClient; + this.collection = + getOrCreateMongoCollection(mongoDatabase, connectionString.getCollection(), isCapped, sizeInBytes); + } + + @Deprecated + public MongoDb4Connection( + final ConnectionString connectionString, + final MongoClient mongoClient, + final MongoDatabase mongoDatabase, + final boolean isCapped, + final Integer sizeInBytes) { + this( + connectionString, + mongoClient, + mongoDatabase, + connectionString.getCollection(), + isCapped, + Long.valueOf(sizeInBytes)); + } + @Override public void closeImpl() { // LOG4J2-1196 diff --git a/log4j-mongodb4/src/main/java/org/apache/logging/log4j/mongodb4/MongoDb4Provider.java b/log4j-mongodb4/src/main/java/org/apache/logging/log4j/mongodb4/MongoDb4Provider.java index 349e22f91c2..851d96e4ee8 100644 --- a/log4j-mongodb4/src/main/java/org/apache/logging/log4j/mongodb4/MongoDb4Provider.java +++ b/log4j-mongodb4/src/main/java/org/apache/logging/log4j/mongodb4/MongoDb4Provider.java @@ -205,6 +205,79 @@ private MongoDb4Provider( final String collectionName, final boolean isCapped, final Long collectionSize) { + ConnectionString connectionString; + try { + connectionString = new ConnectionString(connectionStringSource); + } catch (final IllegalArgumentException e) { + LOGGER.error("Invalid MongoDB connection string `{}`.", connectionStringSource, e); + throw e; + } + + String effectiveDatabaseName = databaseName != null ? databaseName : connectionString.getDatabase(); + String effectiveCollectionName = collectionName != null ? collectionName : connectionString.getCollection(); + // Validate the provided databaseName property + try { + MongoNamespace.checkDatabaseNameValidity(effectiveDatabaseName); + } catch (final IllegalArgumentException e) { + LOGGER.error("Invalid MongoDB database name `{}`.", effectiveDatabaseName, e); + throw e; + } + // Validate the provided collectionName property + try { + MongoNamespace.checkCollectionNameValidity(effectiveCollectionName); + } catch (final IllegalArgumentException e) { + LOGGER.error("Invalid MongoDB collection name `{}`.", effectiveCollectionName, e); + throw e; + } + LOGGER.debug("Creating ConnectionString {}...", connectionStringSource); + this.connectionString = new ConnectionString(connectionStringSource); + LOGGER.debug("Created ConnectionString {}", connectionString); + LOGGER.debug("Creating MongoClientSettings..."); + // @formatter:off + final MongoClientSettings settings = MongoClientSettings.builder() + .applyConnectionString(this.connectionString) + .codecRegistry(CODEC_REGISTRIES) + .build(); + // @formatter:on + LOGGER.debug("Created MongoClientSettings {}", settings); + LOGGER.debug("Creating MongoClient {}...", settings); + this.mongoClient = MongoClients.create(settings); + LOGGER.debug("Created MongoClient {}", mongoClient); + LOGGER.debug("Getting MongoDatabase {}...", effectiveDatabaseName); + this.mongoDatabase = this.mongoClient.getDatabase(effectiveDatabaseName); + LOGGER.debug("Got MongoDatabase {}", mongoDatabase); + this.isCapped = isCapped; + this.collectionSize = collectionSize; + this.collectionName = effectiveCollectionName; + } + + private MongoDb4Provider(final String connectionStringSource, final boolean isCapped, final Long collectionSize) { + + ConnectionString connectionString; + try { + connectionString = new ConnectionString(connectionStringSource); + } catch (final IllegalArgumentException e) { + LOGGER.error("Invalid MongoDB connection string `{}`.", connectionStringSource, e); + throw e; + } + + String effectiveDatabaseName = connectionString.getDatabase(); + String effectiveCollectionName = connectionString.getCollection(); + // Validate the provided databaseName property + try { + MongoNamespace.checkDatabaseNameValidity(effectiveDatabaseName); + } catch (final IllegalArgumentException e) { + LOGGER.error("Invalid MongoDB database name `{}`.", effectiveDatabaseName, e); + throw e; + } + // Validate the provided collectionName property + try { + MongoNamespace.checkCollectionNameValidity(effectiveCollectionName); + } catch (final IllegalArgumentException e) { + LOGGER.error("Invalid MongoDB collection name `{}`.", effectiveCollectionName, e); + throw e; + } + LOGGER.debug("Creating ConnectionString {}...", connectionStringSource); this.connectionString = new ConnectionString(connectionStringSource); LOGGER.debug("Created ConnectionString {}", connectionString); @@ -219,12 +292,12 @@ private MongoDb4Provider( LOGGER.debug("Creating MongoClient {}...", settings); this.mongoClient = MongoClients.create(settings); LOGGER.debug("Created MongoClient {}", mongoClient); - LOGGER.debug("Getting MongoDatabase {}...", databaseName); - this.mongoDatabase = this.mongoClient.getDatabase(databaseName); + LOGGER.debug("Getting MongoDatabase {}...", effectiveDatabaseName); + this.mongoDatabase = this.mongoClient.getDatabase(effectiveCollectionName); LOGGER.debug("Got MongoDatabase {}", mongoDatabase); this.isCapped = isCapped; this.collectionSize = collectionSize; - this.collectionName = collectionName; + this.collectionName = effectiveCollectionName; } @Override diff --git a/log4j-mongodb4/src/test/java/org/apache/logging/log4j/mongodb4/MongoDb4ProviderTest.java b/log4j-mongodb4/src/test/java/org/apache/logging/log4j/mongodb4/MongoDb4ProviderTest.java index 9a35f07b4a2..89fea17123d 100644 --- a/log4j-mongodb4/src/test/java/org/apache/logging/log4j/mongodb4/MongoDb4ProviderTest.java +++ b/log4j-mongodb4/src/test/java/org/apache/logging/log4j/mongodb4/MongoDb4ProviderTest.java @@ -20,6 +20,9 @@ import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; +import com.mongodb.MongoNamespace; +import com.mongodb.client.MongoCollection; +import java.lang.reflect.Field; import org.junit.jupiter.api.Test; class MongoDb4ProviderTest { @@ -89,12 +92,11 @@ void createProviderWithDatabaseOnConnectionString() { .build(); assertNotNull(provider); - assertEquals( - collectionName, - provider.getConnection().getCollection().getNamespace().getCollectionName()); - assertEquals( - "logging", - provider.getConnection().getCollection().getNamespace().getDatabaseName()); + + MongoNamespace namespace = findProviderNamespace(provider); + assertEquals(collectionName, namespace.getCollectionName()); + + assertEquals("logging", namespace.getDatabaseName()); } @Test @@ -107,11 +109,20 @@ void createProviderConfigOverridesConnectionString() { .build(); assertNotNull(provider); - assertEquals( - collectionName, - provider.getConnection().getCollection().getNamespace().getCollectionName()); - assertEquals( - databaseName, - provider.getConnection().getCollection().getNamespace().getDatabaseName()); + MongoNamespace namespace = findProviderNamespace(provider); + assertEquals(collectionName, namespace.getCollectionName()); + assertEquals(databaseName, namespace.getDatabaseName()); + } + + private static MongoNamespace findProviderNamespace(final MongoDb4Provider provider) { + MongoDb4Connection connection = provider.getConnection(); + try { + Field collectionField = connection.getClass().getDeclaredField("collection"); + collectionField.setAccessible(true); + MongoCollection collection = (MongoCollection) collectionField.get(connection); + return collection.getNamespace(); + } catch (Exception exception) { + throw new RuntimeException(exception); + } } } From f3281479dcc20ea0666cead84474cbc55242974d Mon Sep 17 00:00:00 2001 From: Josh Smith Date: Tue, 18 Feb 2025 08:06:41 -0600 Subject: [PATCH 11/27] Rewmoving maven wrapper that got created locally to solve build issues --- .mvn/wrapper/maven-wrapper.properties | 20 -------------------- 1 file changed, 20 deletions(-) delete mode 100644 .mvn/wrapper/maven-wrapper.properties diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties deleted file mode 100644 index c76af40b2f9..00000000000 --- a/.mvn/wrapper/maven-wrapper.properties +++ /dev/null @@ -1,20 +0,0 @@ -# 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. -distributionSha256Sum=8351955a9acf2f83c136c4eee0f6db894ab6265fdbe0a94b32a380307dbaa3e1 -distributionType=only-script -distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.8/apache-maven-3.9.8-bin.zip -wrapperVersion=3.3.2 From d79431b818a7cc688893e8542633e3bc0d123733 Mon Sep 17 00:00:00 2001 From: Clay Johnson Date: Tue, 18 Feb 2025 13:58:49 -0600 Subject: [PATCH 12/27] Publish build scans to develocity.apache.org (#3396) * Publish build scans to develocity.apache.org * Use `DEVELOCITY_ACCESS_KEY` to authenticate to `develocity.apache.org` --- .github/workflows/build.yaml | 2 +- .github/workflows/develocity-publish-build-scans.yaml | 4 ++-- .github/workflows/merge-dependabot.yaml | 2 +- .mvn/develocity.xml | 2 +- pom.xml | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index ac7d6128ffc..bf3be134349 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -32,7 +32,7 @@ jobs: if: github.actor != 'dependabot[bot]' uses: apache/logging-parent/.github/workflows/build-reusable.yaml@rel/11.3.0 secrets: - DV_ACCESS_TOKEN: ${{ startsWith(github.ref_name, 'release/') && '' || secrets.GE_ACCESS_TOKEN }} + DV_ACCESS_TOKEN: ${{ startsWith(github.ref_name, 'release/') && '' || secrets.DEVELOCITY_ACCESS_KEY }} with: java-version: | 8 diff --git a/.github/workflows/develocity-publish-build-scans.yaml b/.github/workflows/develocity-publish-build-scans.yaml index 78069943bb0..31fa075ac2f 100644 --- a/.github/workflows/develocity-publish-build-scans.yaml +++ b/.github/workflows/develocity-publish-build-scans.yaml @@ -38,5 +38,5 @@ jobs: - name: Publish Build Scans uses: gradle/develocity-actions/maven-publish-build-scan@b8d3a572314ffff3b940a2c1b7b384d4983d422d # 1.3 with: - develocity-url: 'https://ge.apache.org' - develocity-access-key: ${{ secrets.GE_ACCESS_TOKEN }} + develocity-url: 'https://develocity.apache.org' + develocity-access-key: ${{ secrets.DEVELOCITY_ACCESS_KEY }} diff --git a/.github/workflows/merge-dependabot.yaml b/.github/workflows/merge-dependabot.yaml index 4e35def4b67..c81076e1860 100644 --- a/.github/workflows/merge-dependabot.yaml +++ b/.github/workflows/merge-dependabot.yaml @@ -32,7 +32,7 @@ jobs: if: github.repository == 'apache/logging-log4j2' && github.event_name == 'pull_request_target' && github.actor == 'dependabot[bot]' uses: apache/logging-parent/.github/workflows/build-reusable.yaml@rel/11.3.0 secrets: - DV_ACCESS_TOKEN: ${{ secrets.GE_ACCESS_TOKEN }} + DV_ACCESS_TOKEN: ${{ secrets.DEVELOCITY_ACCESS_KEY }} with: java-version: | 8 diff --git a/.mvn/develocity.xml b/.mvn/develocity.xml index 84def1dec34..caa112766a0 100644 --- a/.mvn/develocity.xml +++ b/.mvn/develocity.xml @@ -2,7 +2,7 @@ logging-log4j2 - https://ge.apache.org + https://develocity.apache.org diff --git a/pom.xml b/pom.xml index bcc6f1b9c75..41283036545 100644 --- a/pom.xml +++ b/pom.xml @@ -370,7 +370,7 @@ ${maven.multiModuleProjectDirectory}/target/plugin-descriptors/phase1 ${maven.multiModuleProjectDirectory}/target/plugin-descriptors/phase2 - + 3.2.5 From fdb3e7d9fc49327934f100f7156a549e8c029f2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Volkan=20Yaz=C4=B1c=C4=B1?= Date: Tue, 18 Feb 2025 22:06:41 +0100 Subject: [PATCH 13/27] Fix null termination advice for SOA and JTL --- .../antora/modules/ROOT/examples/cloud/logstash/log4j2.json | 4 +--- .../modules/ROOT/examples/cloud/logstash/log4j2.properties | 1 - .../antora/modules/ROOT/examples/cloud/logstash/log4j2.xml | 2 +- .../antora/modules/ROOT/examples/cloud/logstash/log4j2.yaml | 3 +-- src/site/antora/modules/ROOT/pages/soa.adoc | 3 +-- 5 files changed, 4 insertions(+), 9 deletions(-) diff --git a/src/site/antora/modules/ROOT/examples/cloud/logstash/log4j2.json b/src/site/antora/modules/ROOT/examples/cloud/logstash/log4j2.json index 14512de6346..3ebdb0994eb 100644 --- a/src/site/antora/modules/ROOT/examples/cloud/logstash/log4j2.json +++ b/src/site/antora/modules/ROOT/examples/cloud/logstash/log4j2.json @@ -6,9 +6,7 @@ "name": "SOCKET", "host": "localhost", "port": 12345, - "JsonTemplateLayout": { - "nullEventDelimiterEnabled": true - } + "JsonTemplateLayout": {} } // end::socketAppender[] }, diff --git a/src/site/antora/modules/ROOT/examples/cloud/logstash/log4j2.properties b/src/site/antora/modules/ROOT/examples/cloud/logstash/log4j2.properties index b3aa633b9f2..c25e660b87a 100644 --- a/src/site/antora/modules/ROOT/examples/cloud/logstash/log4j2.properties +++ b/src/site/antora/modules/ROOT/examples/cloud/logstash/log4j2.properties @@ -21,7 +21,6 @@ appender.0.name = SOCKET appender.0.host = localhost appender.0.port = 12345 appender.0.layout.type = JsonTemplateLayout -appender.0.layout.nullEventDelimiterEnabled = true # end::socketAppender[] rootLogger.level = WARN diff --git a/src/site/antora/modules/ROOT/examples/cloud/logstash/log4j2.xml b/src/site/antora/modules/ROOT/examples/cloud/logstash/log4j2.xml index bc7e6e3697e..13b960ec2b9 100644 --- a/src/site/antora/modules/ROOT/examples/cloud/logstash/log4j2.xml +++ b/src/site/antora/modules/ROOT/examples/cloud/logstash/log4j2.xml @@ -24,7 +24,7 @@ - + diff --git a/src/site/antora/modules/ROOT/examples/cloud/logstash/log4j2.yaml b/src/site/antora/modules/ROOT/examples/cloud/logstash/log4j2.yaml index 60cc47d586d..d6e0a44787c 100644 --- a/src/site/antora/modules/ROOT/examples/cloud/logstash/log4j2.yaml +++ b/src/site/antora/modules/ROOT/examples/cloud/logstash/log4j2.yaml @@ -22,8 +22,7 @@ Configuration: name: "SOCKET" host: "localhost" port: 12345 - JsonTemplateLayout: - nullEventDelimiterEnabled: true + JsonTemplateLayout: {} # end::socketAppender[] Loggers: diff --git a/src/site/antora/modules/ROOT/pages/soa.adoc b/src/site/antora/modules/ROOT/pages/soa.adoc index 5db72c82478..063909ae495 100644 --- a/src/site/antora/modules/ROOT/pages/soa.adoc +++ b/src/site/antora/modules/ROOT/pages/soa.adoc @@ -99,8 +99,7 @@ Nevertheless, there are some tips we recommend you to practice: * *For writing to console*, use a xref:manual/appenders.adoc#ConsoleAppender[Console Appender] and make sure to configure its `direct` attribute to `true` for the maximum efficiency. -* *For writing to an external service*, use a xref:manual/appenders/network.adoc#SocketAppender[Socket Appender] and make sure to set the protocol to TCP and configure the null delimiter of the associated layout. -For instance, see xref:manual/json-template-layout.adoc#plugin-attr-nullEventDelimiterEnabled[the `nullEventDelimiterEnabled` configuration attribute of JSON Template Layout]. +* *For writing to an external service*, use a xref:manual/appenders/network.adoc#SocketAppender[Socket Appender] and make sure to configure the protocol and layout's null termination (e.g., see xref:manual/json-template-layout.adoc#plugin-attr-nullEventDelimiterEnabled[the `nullEventDelimiterEnabled` configuration attribute of JSON Template Layout]) appropriately. [#file] === Avoid writing to files From 81ba7a45fbaf2ef6abd4d32a0dd06515a50ea752 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 18 Feb 2025 22:36:24 +0100 Subject: [PATCH 14/27] Bump org.apache.logging:logging-parent from 11.3.0 to 12.0.0 in /log4j-parent (#3452) * Bump org.apache.logging:logging-parent in /log4j-parent Bumps [org.apache.logging:logging-parent](https://github.com/apache/logging-parent) from 11.3.0 to 12.0.0. - [Release notes](https://github.com/apache/logging-parent/releases) - [Commits](https://github.com/apache/logging-parent/compare/rel/11.3.0...rel/12.0.0) --- updated-dependencies: - dependency-name: org.apache.logging:logging-parent dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] * Necessary fixes for `12.0.0` upgrade. Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Piotr P. Karwasz --- .github/workflows/build.yaml | 6 ++-- .github/workflows/codeql-analysis.yaml | 2 +- .github/workflows/deploy-site.yaml | 6 ++-- .github/workflows/merge-dependabot.yaml | 4 +-- log4j-parent/pom.xml | 28 +++++++++++++++++-- pom.xml | 4 ++- ...date_org_apache_logging_logging_parent.xml | 2 +- 7 files changed, 39 insertions(+), 13 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index bf3be134349..e4046edb7c3 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -30,7 +30,7 @@ jobs: build: if: github.actor != 'dependabot[bot]' - uses: apache/logging-parent/.github/workflows/build-reusable.yaml@rel/11.3.0 + uses: apache/logging-parent/.github/workflows/build-reusable.yaml@rel/12.0.0 secrets: DV_ACCESS_TOKEN: ${{ startsWith(github.ref_name, 'release/') && '' || secrets.DEVELOCITY_ACCESS_KEY }} with: @@ -44,7 +44,7 @@ jobs: deploy-snapshot: needs: build if: github.repository == 'apache/logging-log4j2' && github.ref_name == '2.x' - uses: apache/logging-parent/.github/workflows/deploy-snapshot-reusable.yaml@rel/11.3.0 + uses: apache/logging-parent/.github/workflows/deploy-snapshot-reusable.yaml@rel/12.0.0 # Secrets for deployments secrets: NEXUS_USERNAME: ${{ secrets.NEXUS_USER }} @@ -57,7 +57,7 @@ jobs: deploy-release: needs: build if: github.repository == 'apache/logging-log4j2' && startsWith(github.ref_name, 'release/') - uses: apache/logging-parent/.github/workflows/deploy-release-reusable.yaml@rel/11.3.0 + uses: apache/logging-parent/.github/workflows/deploy-release-reusable.yaml@rel/12.0.0 # Secrets for deployments secrets: GPG_SECRET_KEY: ${{ secrets.LOGGING_GPG_SECRET_KEY }} diff --git a/.github/workflows/codeql-analysis.yaml b/.github/workflows/codeql-analysis.yaml index cc2dbcaaf85..05a37e02f99 100644 --- a/.github/workflows/codeql-analysis.yaml +++ b/.github/workflows/codeql-analysis.yaml @@ -30,7 +30,7 @@ permissions: read-all jobs: analyze: - uses: apache/logging-parent/.github/workflows/codeql-analysis-reusable.yaml@rel/11.3.0 + uses: apache/logging-parent/.github/workflows/codeql-analysis-reusable.yaml@rel/12.0.0 with: java-version: | 8 diff --git a/.github/workflows/deploy-site.yaml b/.github/workflows/deploy-site.yaml index 365b8fc2901..604ac5f63aa 100644 --- a/.github/workflows/deploy-site.yaml +++ b/.github/workflows/deploy-site.yaml @@ -33,7 +33,7 @@ jobs: deploy-site-stg: if: github.repository == 'apache/logging-log4j2' && github.ref_name == '2.x' - uses: apache/logging-parent/.github/workflows/deploy-site-reusable.yaml@rel/11.3.0 + uses: apache/logging-parent/.github/workflows/deploy-site-reusable.yaml@rel/12.0.0 # Secrets for committing the generated site secrets: GPG_SECRET_KEY: ${{ secrets.LOGGING_GPG_SECRET_KEY }} @@ -51,7 +51,7 @@ jobs: deploy-site-pro: if: github.repository == 'apache/logging-log4j2' && github.ref_name == '2.x-site-pro' - uses: apache/logging-parent/.github/workflows/deploy-site-reusable.yaml@rel/11.3.0 + uses: apache/logging-parent/.github/workflows/deploy-site-reusable.yaml@rel/12.0.0 # Secrets for committing the generated site secrets: GPG_SECRET_KEY: ${{ secrets.LOGGING_GPG_SECRET_KEY }} @@ -81,7 +81,7 @@ jobs: deploy-site-rel: needs: export-version - uses: apache/logging-parent/.github/workflows/deploy-site-reusable.yaml@rel/11.3.0 + uses: apache/logging-parent/.github/workflows/deploy-site-reusable.yaml@rel/12.0.0 # Secrets for committing the generated site secrets: GPG_SECRET_KEY: ${{ secrets.LOGGING_GPG_SECRET_KEY }} diff --git a/.github/workflows/merge-dependabot.yaml b/.github/workflows/merge-dependabot.yaml index c81076e1860..cfb0b1d63dd 100644 --- a/.github/workflows/merge-dependabot.yaml +++ b/.github/workflows/merge-dependabot.yaml @@ -30,7 +30,7 @@ jobs: build: if: github.repository == 'apache/logging-log4j2' && github.event_name == 'pull_request_target' && github.actor == 'dependabot[bot]' - uses: apache/logging-parent/.github/workflows/build-reusable.yaml@rel/11.3.0 + uses: apache/logging-parent/.github/workflows/build-reusable.yaml@rel/12.0.0 secrets: DV_ACCESS_TOKEN: ${{ secrets.DEVELOCITY_ACCESS_KEY }} with: @@ -42,7 +42,7 @@ jobs: merge-dependabot: needs: build - uses: apache/logging-parent/.github/workflows/merge-dependabot-reusable.yaml@rel/11.3.0 + uses: apache/logging-parent/.github/workflows/merge-dependabot-reusable.yaml@rel/12.0.0 with: java-version: 17 permissions: diff --git a/log4j-parent/pom.xml b/log4j-parent/pom.xml index c429feaf95a..d72e426442c 100644 --- a/log4j-parent/pom.xml +++ b/log4j-parent/pom.xml @@ -66,6 +66,7 @@ 3.27.3 4.2.2 2.0b6 + 7.1.0 3.11.18 3.11.5 1.17.1 @@ -125,8 +126,11 @@ 2.0.8 6.0.0 + 2.0.0 + 1.1.2 4.14.0 3.6.0 + 4.9.1 2.7.18 5.3.39 2.0.3 @@ -574,6 +578,12 @@ ${jna.version} + + org.jspecify + jspecify + ${jspecify.version} + + junit junit @@ -829,6 +839,7 @@ biz.aQute.bnd biz.aQute.bnd.annotation + ${bnd.annotation.version} provided @@ -841,19 +852,22 @@ org.osgi - osgi.annotation + org.osgi.annotation.bundle + ${osgi.annotation.bundle.version} provided org.osgi - org.osgi.annotation.bundle + org.osgi.annotation.versioning + ${osgi.annotation.versioning.version} provided com.github.spotbugs spotbugs-annotations + ${spotbugs-annotations.version} provided @@ -977,6 +991,16 @@ + + org.apache.maven.plugins + maven-compiler-plugin + + + --should-stop=ifError=FLOW + + + + diff --git a/pom.xml b/pom.xml index 41283036545..177b0531d2c 100644 --- a/pom.xml +++ b/pom.xml @@ -31,7 +31,7 @@ org.apache.logging logging-parent - 11.3.0 + 12.0.0 @@ -357,6 +357,7 @@ + 1.0.0 0.9.0 21.7.1 10.5.0 @@ -993,6 +994,7 @@ org.jspecify jspecify ${jspecify.version} + test diff --git a/src/changelog/.2.x.x/update_org_apache_logging_logging_parent.xml b/src/changelog/.2.x.x/update_org_apache_logging_logging_parent.xml index 5b17082960b..0ea7b563939 100644 --- a/src/changelog/.2.x.x/update_org_apache_logging_logging_parent.xml +++ b/src/changelog/.2.x.x/update_org_apache_logging_logging_parent.xml @@ -3,5 +3,5 @@ xmlns="https://logging.apache.org/xml/ns" xsi:schemaLocation="https://logging.apache.org/xml/ns https://logging.apache.org/xml/ns/log4j-changelog-0.xsd" type="updated"> - Update `org.apache.logging:logging-parent` to version `11.3.0` + Update `org.apache.logging:logging-parent` to version `12.0.0` From 00eb8f458796a33a1fa677e64e9fbb8279e03a6e Mon Sep 17 00:00:00 2001 From: "Piotr P. Karwasz" Date: Thu, 17 Oct 2024 12:11:24 +0200 Subject: [PATCH 15/27] Run reproducibility check after each deployment This PR starts a separate `verify-reproducibility` job, whenever a snapshot or release is deployed. --- .github/workflows/build.yaml | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index e4046edb7c3..721a7f8a375 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -38,7 +38,7 @@ jobs: 8 17 site-enabled: true - reproducibility-check-enabled: ${{ startsWith(github.ref_name, 'release/') }} + reproducibility-check-enabled: false develocity-enabled: ${{ ! startsWith(github.ref_name, 'release/') }} deploy-snapshot: @@ -73,3 +73,14 @@ jobs: 8 17 project-id: log4j + + verify-reproducibility: + needs: [ deploy-snapshot, deploy-release ] + if: ${{ always() && (needs.deploy-snapshot.result == 'success' || needs.deploy-release.result == 'success') }} + uses: apache/logging-parent/.github/workflows/verify-reproducibility-reusable.yaml@rel/12.0.0 + with: + nexus-url: ${{ needs.deploy-release.result == 'success' && needs.deploy-release.outputs.nexus-url || needs.deploy-snapshot.outputs.nexus-url }} + # Checkout the repository by branch name, since the deployment job might add commits to the branch + ref: ${{ github.ref_name }} + # Encode the `runs-on` input as JSON array + runs-on: '["ubuntu-latest", "macos-latest", "windows-latest"]' From 4276c2b73702e49432aa202962fe7caa8cfc2f8b Mon Sep 17 00:00:00 2001 From: "Piotr P. Karwasz" Date: Tue, 18 Feb 2025 22:38:36 +0100 Subject: [PATCH 16/27] Run integration tests after each deployment (#3105) This PR starts an `integration-test` job, whenever a snapshot or release is deployed. --- .github/workflows/build.yaml | 15 +++++++++++++-- pom.xml | 2 +- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 721a7f8a375..ddc88be30d9 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -77,10 +77,21 @@ jobs: verify-reproducibility: needs: [ deploy-snapshot, deploy-release ] if: ${{ always() && (needs.deploy-snapshot.result == 'success' || needs.deploy-release.result == 'success') }} + name: "verify-reproducibility (${{ needs.deploy-release.result == 'success' && needs.deploy-release.outputs.project-version || needs.deploy-snapshot.outputs.project-version }})" uses: apache/logging-parent/.github/workflows/verify-reproducibility-reusable.yaml@rel/12.0.0 with: nexus-url: ${{ needs.deploy-release.result == 'success' && needs.deploy-release.outputs.nexus-url || needs.deploy-snapshot.outputs.nexus-url }} - # Checkout the repository by branch name, since the deployment job might add commits to the branch - ref: ${{ github.ref_name }} # Encode the `runs-on` input as JSON array runs-on: '["ubuntu-latest", "macos-latest", "windows-latest"]' + + # Run integration-tests automatically after a snapshot or RC is published + integration-test: + needs: [ deploy-snapshot, deploy-release ] + if: ${{ always() && (needs.deploy-snapshot.result == 'success' || needs.deploy-release.result == 'success') }} + name: "integration-test (${{ needs.deploy-release.result == 'success' && needs.deploy-release.outputs.project-version || needs.deploy-snapshot.outputs.project-version }})" + uses: apache/logging-log4j-samples/.github/workflows/integration-test.yaml@main + with: + log4j-version: ${{ needs.deploy-release.result == 'success' && needs.deploy-release.outputs.project-version || needs.deploy-snapshot.outputs.project-version }} + log4j-repository-url: ${{ needs.deploy-release.result == 'success' && needs.deploy-release.outputs.nexus-url || needs.deploy-snapshot.outputs.nexus-url }} + # Use the `main` branch of `logging-log4j-samples` + samples-ref: 'refs/heads/main' diff --git a/pom.xml b/pom.xml index 177b0531d2c..31f27d334be 100644 --- a/pom.xml +++ b/pom.xml @@ -307,7 +307,7 @@ - 2.25.0-SNAPSHOT + 2.25.0.pr3105-SNAPSHOT 2.24.3 2.24.3 From 701845f3a9035da135a8ef2cf3f28089ed9e473a Mon Sep 17 00:00:00 2001 From: "Piotr P. Karwasz" Date: Tue, 18 Feb 2025 23:05:34 +0100 Subject: [PATCH 17/27] Fix revision to `2.25.0-SNAPSHOT` --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 31f27d334be..177b0531d2c 100644 --- a/pom.xml +++ b/pom.xml @@ -307,7 +307,7 @@ - 2.25.0.pr3105-SNAPSHOT + 2.25.0-SNAPSHOT 2.24.3 2.24.3 From cb8c7ec406cdb96b9bf27ce9a4e6bb5d679c14e6 Mon Sep 17 00:00:00 2001 From: "Piotr P. Karwasz" Date: Tue, 18 Feb 2025 23:55:11 +0100 Subject: [PATCH 18/27] Fix Nexus URL for snapshots --- .github/workflows/build.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index ddc88be30d9..3e5377d03c1 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -80,7 +80,7 @@ jobs: name: "verify-reproducibility (${{ needs.deploy-release.result == 'success' && needs.deploy-release.outputs.project-version || needs.deploy-snapshot.outputs.project-version }})" uses: apache/logging-parent/.github/workflows/verify-reproducibility-reusable.yaml@rel/12.0.0 with: - nexus-url: ${{ needs.deploy-release.result == 'success' && needs.deploy-release.outputs.nexus-url || needs.deploy-snapshot.outputs.nexus-url }} + nexus-url: ${{ needs.deploy-release.result == 'success' && needs.deploy-release.outputs.nexus-url || 'https://repository.apache.org/content/groups/snapshots' }} # Encode the `runs-on` input as JSON array runs-on: '["ubuntu-latest", "macos-latest", "windows-latest"]' From 0a2566ca3749e4861d67798d81af7d8a5d08ffe7 Mon Sep 17 00:00:00 2001 From: ASF Logging Services RM Date: Tue, 18 Feb 2025 23:11:28 +0000 Subject: [PATCH 19/27] Update `org.apache.cassandra:cassandra-all` to version `3.11.19` (#3440) --- log4j-parent/pom.xml | 2 +- .../.2.x.x/update_org_apache_cassandra_cassandra_all.xml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/log4j-parent/pom.xml b/log4j-parent/pom.xml index d72e426442c..1c6846a594e 100644 --- a/log4j-parent/pom.xml +++ b/log4j-parent/pom.xml @@ -67,7 +67,7 @@ 4.2.2 2.0b6 7.1.0 - 3.11.18 + 3.11.19 3.11.5 1.17.1 1.27.1 diff --git a/src/changelog/.2.x.x/update_org_apache_cassandra_cassandra_all.xml b/src/changelog/.2.x.x/update_org_apache_cassandra_cassandra_all.xml index 01c4737997c..40a9dcfbec6 100644 --- a/src/changelog/.2.x.x/update_org_apache_cassandra_cassandra_all.xml +++ b/src/changelog/.2.x.x/update_org_apache_cassandra_cassandra_all.xml @@ -3,6 +3,6 @@ xmlns="https://logging.apache.org/xml/ns" xsi:schemaLocation="https://logging.apache.org/xml/ns https://logging.apache.org/xml/ns/log4j-changelog-0.xsd" type="updated"> - - Update `org.apache.cassandra:cassandra-all` to version `3.11.18` + + Update `org.apache.cassandra:cassandra-all` to version `3.11.19` From e4982fda743ec3265863826858d7daf596787064 Mon Sep 17 00:00:00 2001 From: "Piotr P. Karwasz" Date: Wed, 19 Feb 2025 07:49:29 +0100 Subject: [PATCH 20/27] Activate `bom` profile in `log4j-bom` Adds a `.logging-parent-bom-activator` file to activate the `bom` profile. --- .logging-parent-bom-activator | 16 ++++++++++++++++ pom.xml | 17 ----------------- 2 files changed, 16 insertions(+), 17 deletions(-) create mode 100644 .logging-parent-bom-activator diff --git a/.logging-parent-bom-activator b/.logging-parent-bom-activator new file mode 100644 index 00000000000..e7980a6d13b --- /dev/null +++ b/.logging-parent-bom-activator @@ -0,0 +1,16 @@ +# 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. +## +This file activates the `flatten-bom` profile. \ No newline at end of file diff --git a/pom.xml b/pom.xml index 177b0531d2c..bb67727f5fe 100644 --- a/pom.xml +++ b/pom.xml @@ -563,23 +563,6 @@ - - - org.codehaus.mojo - flatten-maven-plugin - ${flatten-maven-plugin.version} - - - flatten-bom - - flatten - - process-resources - false - - - - From 645502af6ede6916e647522e4c101d92a6c542fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Volkan=20Yaz=C4=B1c=C4=B1?= Date: Wed, 19 Feb 2025 11:19:42 +0100 Subject: [PATCH 21/27] Add Nexus URL argument to `generate-email.sh` per `logging-parent` upgrade --- .github/generate-email.sh | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/generate-email.sh b/.github/generate-email.sh index e825293af6d..469023ad819 100755 --- a/.github/generate-email.sh +++ b/.github/generate-email.sh @@ -28,12 +28,12 @@ stderr() { fail_for_invalid_args() { stderr "Invalid arguments!" - stderr "Expected arguments: " + stderr "Expected arguments: " exit 1 } # Check arguments -[ $# -ne 3 ] && fail_for_invalid_args +[ $# -ne 4 ] && fail_for_invalid_args # Constants PROJECT_NAME="Apache Log4j" @@ -43,6 +43,7 @@ PROJECT_SITE="https://logging.apache.org/$PROJECT_ID" PROJECT_STAGING_SITE="${PROJECT_SITE/apache.org/staged.apache.org}" PROJECT_REPO="https://github.com/apache/logging-log4j2" COMMIT_ID="$3" +NEXUS_URL="$4" PROJECT_DIST_URL="https://dist.apache.org/repos/dist/dev/logging/$PROJECT_ID/$PROJECT_VERSION" # Check release notes file @@ -71,7 +72,7 @@ Website: $PROJECT_STAGING_SITE/$PROJECT_VERSION/index.html GitHub: $PROJECT_REPO Commit: $COMMIT_ID Distribution: $PROJECT_DIST_URL -Nexus: https://repository.apache.org/content/repositories/orgapachelogging- +Nexus: $NEXUS_URL Signing key: 0x077e8893a6dcc33dd4a4d5b256e73ba9a0b592d0 Review kit: https://logging.apache.org/logging-parent/release-review-instructions.html From 8aaf2883e17e3baf3ba9d6a2b29019b66091a729 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Volkan=20Yaz=C4=B1c=C4=B1?= Date: Wed, 19 Feb 2025 11:23:57 +0100 Subject: [PATCH 22/27] Document `maven-compiler-plugin` override --- log4j-parent/pom.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/log4j-parent/pom.xml b/log4j-parent/pom.xml index 1c6846a594e..7b7ddeb8766 100644 --- a/log4j-parent/pom.xml +++ b/log4j-parent/pom.xml @@ -991,6 +991,9 @@ + org.apache.maven.plugins maven-compiler-plugin From 0289d63aabb4eb1f15a4aba747c75dc6689b2635 Mon Sep 17 00:00:00 2001 From: ASF Logging Services RM Date: Wed, 19 Feb 2025 11:47:02 +0000 Subject: [PATCH 23/27] Update `org.mongodb:bson` to version `5.3.1` (#3409) --- log4j-mongodb/pom.xml | 2 +- src/changelog/.2.x.x/update_org_mongodb_bson.xml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/log4j-mongodb/pom.xml b/log4j-mongodb/pom.xml index 4991ab5ac83..822f4d382db 100644 --- a/log4j-mongodb/pom.xml +++ b/log4j-mongodb/pom.xml @@ -30,7 +30,7 @@ org.apache.logging.log4j.core - 5.2.1 + 5.3.1 2.0.16 diff --git a/src/changelog/.2.x.x/update_org_mongodb_bson.xml b/src/changelog/.2.x.x/update_org_mongodb_bson.xml index 02f463185e0..ce86df17157 100644 --- a/src/changelog/.2.x.x/update_org_mongodb_bson.xml +++ b/src/changelog/.2.x.x/update_org_mongodb_bson.xml @@ -3,6 +3,6 @@ xmlns="https://logging.apache.org/xml/ns" xsi:schemaLocation="https://logging.apache.org/xml/ns https://logging.apache.org/xml/ns/log4j-changelog-0.xsd" type="updated"> - - Update `org.mongodb:bson` to version `4.11.5` + + Update `org.mongodb:bson` to version `5.3.1` From 530d85088fdfe603b8bd7a46040a4f237dec8a3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Volkan=20Yaz=C4=B1c=C4=B1?= Date: Wed, 19 Feb 2025 16:08:43 +0100 Subject: [PATCH 24/27] Implement review feedback --- log4j-mongodb4/pom.xml | 15 -- .../log4j/mongodb4/MongoDb4Connection.java | 52 +++---- .../log4j/mongodb4/MongoDb4Provider.java | 136 ++++-------------- .../log4j/mongodb4/MongoDb4ProviderTest.java | 98 ++++++------- .../log4j/mongodb4/MongoDb4Resolver.java | 2 - 5 files changed, 93 insertions(+), 210 deletions(-) diff --git a/log4j-mongodb4/pom.xml b/log4j-mongodb4/pom.xml index fc25d4ace9a..9115fe4175f 100644 --- a/log4j-mongodb4/pom.xml +++ b/log4j-mongodb4/pom.xml @@ -134,16 +134,6 @@ org.apache.maven.plugins maven-surefire-plugin - - true - - - - org.junit.jupiter - junit-jupiter-engine - ${junit-jupiter.version} - - @@ -236,11 +226,6 @@ **/*IT.java - - OFF ${mongo.port} diff --git a/log4j-mongodb4/src/main/java/org/apache/logging/log4j/mongodb4/MongoDb4Connection.java b/log4j-mongodb4/src/main/java/org/apache/logging/log4j/mongodb4/MongoDb4Connection.java index ed7989275c0..dd7a3a927c1 100644 --- a/log4j-mongodb4/src/main/java/org/apache/logging/log4j/mongodb4/MongoDb4Connection.java +++ b/log4j-mongodb4/src/main/java/org/apache/logging/log4j/mongodb4/MongoDb4Connection.java @@ -41,7 +41,7 @@ public final class MongoDb4Connection extends AbstractNoSqlConnection getOrCreateMongoCollection( final MongoDatabase database, final String collectionName, final boolean isCapped, final Long sizeInBytes) { try { - LOGGER.debug("Gettting collection '{}'...", collectionName); + LOGGER.debug("Getting collection '{}'...", collectionName); // throws IllegalArgumentException if collectionName is invalid final MongoCollection found = database.getCollection(collectionName); LOGGER.debug("Got collection {}", found); @@ -63,28 +63,28 @@ private static MongoCollection getOrCreateMongoCollection( private final MongoCollection collection; private final MongoClient mongoClient; + /** + * @deprecated Use {@link #MongoDb4Connection(ConnectionString, MongoClient, MongoDatabase, String, boolean, Long)} instead + */ + @Deprecated public MongoDb4Connection( final ConnectionString connectionString, final MongoClient mongoClient, final MongoDatabase mongoDatabase, - final String collectionName, final boolean isCapped, final Integer sizeInBytes) { - this(connectionString, mongoClient, mongoDatabase, collectionName, isCapped, Long.valueOf(sizeInBytes)); - } - - public MongoDb4Connection( - final ConnectionString connectionString, - final MongoClient mongoClient, - final MongoDatabase mongoDatabase, - final String collectionName, - final boolean isCapped, - final Long sizeInBytes) { - this.connectionString = connectionString; - this.mongoClient = mongoClient; - this.collection = getOrCreateMongoCollection(mongoDatabase, collectionName, isCapped, sizeInBytes); + this( + connectionString, + mongoClient, + mongoDatabase, + connectionString.getCollection(), + isCapped, + Long.valueOf(sizeInBytes)); } + /** + * @deprecated Use {@link #MongoDb4Connection(ConnectionString, MongoClient, MongoDatabase, String, boolean, Long)} instead + */ @Deprecated public MongoDb4Connection( final ConnectionString connectionString, @@ -98,20 +98,16 @@ public MongoDb4Connection( getOrCreateMongoCollection(mongoDatabase, connectionString.getCollection(), isCapped, sizeInBytes); } - @Deprecated public MongoDb4Connection( final ConnectionString connectionString, final MongoClient mongoClient, final MongoDatabase mongoDatabase, + final String collectionName, final boolean isCapped, - final Integer sizeInBytes) { - this( - connectionString, - mongoClient, - mongoDatabase, - connectionString.getCollection(), - isCapped, - Long.valueOf(sizeInBytes)); + final Long sizeInBytes) { + this.connectionString = connectionString; + this.mongoClient = mongoClient; + this.collection = getOrCreateMongoCollection(mongoDatabase, collectionName, isCapped, sizeInBytes); } @Override @@ -149,12 +145,4 @@ public String toString() { "Mongo4Connection [connectionString=%s, collection=%s, mongoClient=%s]", connectionString, collection, mongoClient); } - - /* - * This method is exposed to help support unit tests for the MongoDbProvider class. - * - */ - public MongoCollection getCollection() { - return this.collection; - } } diff --git a/log4j-mongodb4/src/main/java/org/apache/logging/log4j/mongodb4/MongoDb4Provider.java b/log4j-mongodb4/src/main/java/org/apache/logging/log4j/mongodb4/MongoDb4Provider.java index 851d96e4ee8..e8522658d85 100644 --- a/log4j-mongodb4/src/main/java/org/apache/logging/log4j/mongodb4/MongoDb4Provider.java +++ b/log4j-mongodb4/src/main/java/org/apache/logging/log4j/mongodb4/MongoDb4Provider.java @@ -22,7 +22,6 @@ import com.mongodb.client.MongoClient; import com.mongodb.client.MongoClients; import com.mongodb.client.MongoDatabase; -import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.core.Core; import org.apache.logging.log4j.core.appender.nosql.NoSqlProvider; import org.apache.logging.log4j.core.config.plugins.Plugin; @@ -69,32 +68,8 @@ public static class Builder> extends AbstractFilterable.Bui @Override public MongoDb4Provider build() { - StatusLogger.getLogger().warn("The {} Appender is deprecated, use the MongoDb Appender.", PLUGIN_NAME); - - ConnectionString connectionString; - try { - connectionString = new ConnectionString(connectionStringSource); - } catch (final IllegalArgumentException e) { - LOGGER.error("Invalid MongoDB connection string `{}`.", connectionStringSource, e); - return null; - } - - String effectiveDatabaseName = databaseName != null ? databaseName : connectionString.getDatabase(); - String effectiveCollectionName = collectionName != null ? collectionName : connectionString.getCollection(); - // Validate the provided databaseName property - try { - MongoNamespace.checkDatabaseNameValidity(effectiveDatabaseName); - } catch (final IllegalArgumentException e) { - LOGGER.error("Invalid MongoDB database name `{}`.", effectiveDatabaseName, e); - return null; - } - // Validate the provided collectionName property - try { - MongoNamespace.checkCollectionNameValidity(effectiveCollectionName); - } catch (final IllegalArgumentException e) { - LOGGER.error("Invalid MongoDB collection name `{}`.", effectiveCollectionName, e); - return null; - } + StatusLogger.getLogger() + .warn("The {} Appender is deprecated, use the MongoDb Appender instead.", PLUGIN_NAME); return newMongoDb4Provider(); } @@ -169,14 +144,10 @@ public B setDatabaseName(final String databaseName) { } } - private static final Logger LOGGER = StatusLogger.getLogger(); - - // @formatter:off private static final CodecRegistry CODEC_REGISTRIES = CodecRegistries.fromRegistries( MongoClientSettings.getDefaultCodecRegistry(), CodecRegistries.fromCodecs(MongoDb4LevelCodec.INSTANCE), CodecRegistries.fromCodecs(new MongoDb4DocumentObjectCodec())); - // @formatter:on // TODO Where does this number come from? private static final long DEFAULT_COLLECTION_SIZE = 536_870_912; @@ -205,99 +176,52 @@ private MongoDb4Provider( final String collectionName, final boolean isCapped, final Long collectionSize) { - ConnectionString connectionString; - try { - connectionString = new ConnectionString(connectionStringSource); - } catch (final IllegalArgumentException e) { - LOGGER.error("Invalid MongoDB connection string `{}`.", connectionStringSource, e); - throw e; - } - - String effectiveDatabaseName = databaseName != null ? databaseName : connectionString.getDatabase(); - String effectiveCollectionName = collectionName != null ? collectionName : connectionString.getCollection(); - // Validate the provided databaseName property - try { - MongoNamespace.checkDatabaseNameValidity(effectiveDatabaseName); - } catch (final IllegalArgumentException e) { - LOGGER.error("Invalid MongoDB database name `{}`.", effectiveDatabaseName, e); - throw e; - } - // Validate the provided collectionName property - try { - MongoNamespace.checkCollectionNameValidity(effectiveCollectionName); - } catch (final IllegalArgumentException e) { - LOGGER.error("Invalid MongoDB collection name `{}`.", effectiveCollectionName, e); - throw e; - } - LOGGER.debug("Creating ConnectionString {}...", connectionStringSource); - this.connectionString = new ConnectionString(connectionStringSource); - LOGGER.debug("Created ConnectionString {}", connectionString); - LOGGER.debug("Creating MongoClientSettings..."); - // @formatter:off + this.connectionString = createConnectionString(connectionStringSource); final MongoClientSettings settings = MongoClientSettings.builder() .applyConnectionString(this.connectionString) .codecRegistry(CODEC_REGISTRIES) .build(); - // @formatter:on - LOGGER.debug("Created MongoClientSettings {}", settings); - LOGGER.debug("Creating MongoClient {}...", settings); this.mongoClient = MongoClients.create(settings); - LOGGER.debug("Created MongoClient {}", mongoClient); - LOGGER.debug("Getting MongoDatabase {}...", effectiveDatabaseName); - this.mongoDatabase = this.mongoClient.getDatabase(effectiveDatabaseName); - LOGGER.debug("Got MongoDatabase {}", mongoDatabase); + this.mongoDatabase = createDatabase(connectionString, databaseName, mongoClient); this.isCapped = isCapped; this.collectionSize = collectionSize; - this.collectionName = effectiveCollectionName; + this.collectionName = getEffectiveCollectionName(connectionString, collectionName); } - private MongoDb4Provider(final String connectionStringSource, final boolean isCapped, final Long collectionSize) { - - ConnectionString connectionString; + private static ConnectionString createConnectionString(final String connectionStringSource) { try { - connectionString = new ConnectionString(connectionStringSource); - } catch (final IllegalArgumentException e) { - LOGGER.error("Invalid MongoDB connection string `{}`.", connectionStringSource, e); - throw e; + return new ConnectionString(connectionStringSource); + } catch (final IllegalArgumentException error) { + final String message = String.format("Invalid MongoDB connection string: `%s`", connectionStringSource); + throw new IllegalArgumentException(message, error); } + } - String effectiveDatabaseName = connectionString.getDatabase(); - String effectiveCollectionName = connectionString.getCollection(); - // Validate the provided databaseName property + private static MongoDatabase createDatabase( + final ConnectionString connectionString, final String databaseName, final MongoClient client) { + final String effectiveDatabaseName = databaseName != null ? databaseName : connectionString.getDatabase(); try { + // noinspection DataFlowIssue MongoNamespace.checkDatabaseNameValidity(effectiveDatabaseName); - } catch (final IllegalArgumentException e) { - LOGGER.error("Invalid MongoDB database name `{}`.", effectiveDatabaseName, e); - throw e; + } catch (final IllegalArgumentException error) { + final String message = String.format("Invalid MongoDB database name: `%s`", effectiveDatabaseName); + throw new IllegalArgumentException(message, error); } - // Validate the provided collectionName property + return client.getDatabase(effectiveDatabaseName); + } + + private static String getEffectiveCollectionName( + final ConnectionString connectionString, final String collectionName) { + final String effectiveCollectionName = + collectionName != null ? collectionName : connectionString.getCollection(); try { + // noinspection DataFlowIssue MongoNamespace.checkCollectionNameValidity(effectiveCollectionName); - } catch (final IllegalArgumentException e) { - LOGGER.error("Invalid MongoDB collection name `{}`.", effectiveCollectionName, e); - throw e; + } catch (final IllegalArgumentException error) { + final String message = String.format("Invalid MongoDB collection name: `%s`", effectiveCollectionName); + throw new IllegalArgumentException(message, error); } - - LOGGER.debug("Creating ConnectionString {}...", connectionStringSource); - this.connectionString = new ConnectionString(connectionStringSource); - LOGGER.debug("Created ConnectionString {}", connectionString); - LOGGER.debug("Creating MongoClientSettings..."); - // @formatter:off - final MongoClientSettings settings = MongoClientSettings.builder() - .applyConnectionString(this.connectionString) - .codecRegistry(CODEC_REGISTRIES) - .build(); - // @formatter:on - LOGGER.debug("Created MongoClientSettings {}", settings); - LOGGER.debug("Creating MongoClient {}...", settings); - this.mongoClient = MongoClients.create(settings); - LOGGER.debug("Created MongoClient {}", mongoClient); - LOGGER.debug("Getting MongoDatabase {}...", effectiveDatabaseName); - this.mongoDatabase = this.mongoClient.getDatabase(effectiveCollectionName); - LOGGER.debug("Got MongoDatabase {}", mongoDatabase); - this.isCapped = isCapped; - this.collectionSize = collectionSize; - this.collectionName = effectiveCollectionName; + return effectiveCollectionName; } @Override diff --git a/log4j-mongodb4/src/test/java/org/apache/logging/log4j/mongodb4/MongoDb4ProviderTest.java b/log4j-mongodb4/src/test/java/org/apache/logging/log4j/mongodb4/MongoDb4ProviderTest.java index 89fea17123d..8588ead05ec 100644 --- a/log4j-mongodb4/src/test/java/org/apache/logging/log4j/mongodb4/MongoDb4ProviderTest.java +++ b/log4j-mongodb4/src/test/java/org/apache/logging/log4j/mongodb4/MongoDb4ProviderTest.java @@ -16,110 +16,98 @@ */ package org.apache.logging.log4j.mongodb4; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertNull; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; import com.mongodb.MongoNamespace; import com.mongodb.client.MongoCollection; import java.lang.reflect.Field; +import org.bson.Document; import org.junit.jupiter.api.Test; class MongoDb4ProviderTest { private static final String CON_STR_WO_DB = "mongodb://localhost:27017"; + private static final String CON_STR_W_DB = "mongodb://localhost:27017/logging"; + private static final String CON_STR_DB_COLL = "mongodb://localhost:27017/logging.logs"; - private static final String collectionName = "logsTest"; - private static final String databaseName = "loggingTest"; + private static final String COLLECTION_NAME = "logsTest"; + + private static final String DATABASE_NAME = "loggingTest"; @Test void createProviderWithDatabaseAndCollectionProvidedViaConfig() { - MongoDb4Provider provider = MongoDb4Provider.newBuilder() .setConnectionStringSource(CON_STR_WO_DB) - .setDatabaseName(databaseName) - .setCollectionName(collectionName) + .setDatabaseName(DATABASE_NAME) + .setCollectionName(COLLECTION_NAME) .build(); - - assertNotNull(provider); - assertEquals( - collectionName, - provider.getConnection().getCollection().getNamespace().getCollectionName()); - assertEquals( - databaseName, - provider.getConnection().getCollection().getNamespace().getDatabaseName()); + assertThat(provider).isNotNull(); + assertProviderNamespace(provider, DATABASE_NAME, COLLECTION_NAME); } @Test void createProviderWithoutDatabaseName() { - - MongoDb4Provider provider = MongoDb4Provider.newBuilder() - .setConnectionStringSource(CON_STR_WO_DB) - .build(); - - assertNull(provider); + assertThatThrownBy(() -> MongoDb4Provider.newBuilder() + .setConnectionStringSource(CON_STR_WO_DB) + .build()) + .hasMessage("Invalid MongoDB database name: `null`"); } @Test void createProviderWithoutDatabaseNameWithCollectionName() { - - MongoDb4Provider provider = MongoDb4Provider.newBuilder() - .setConnectionStringSource(CON_STR_WO_DB) - .setCollectionName(collectionName) - .build(); - - assertNull(provider); + assertThatThrownBy(() -> MongoDb4Provider.newBuilder() + .setConnectionStringSource(CON_STR_WO_DB) + .setCollectionName(COLLECTION_NAME) + .build()) + .hasMessage("Invalid MongoDB database name: `null`"); } @Test void createProviderWithoutCollectionName() { - - MongoDb4Provider provider = MongoDb4Provider.newBuilder() - .setConnectionStringSource(CON_STR_WO_DB) - .setDatabaseName(databaseName) - .build(); - - assertNull(provider); + assertThatThrownBy(() -> MongoDb4Provider.newBuilder() + .setConnectionStringSource(CON_STR_WO_DB) + .setDatabaseName(DATABASE_NAME) + .build()) + .hasMessage("Invalid MongoDB collection name: `null`"); } @Test void createProviderWithDatabaseOnConnectionString() { MongoDb4Provider provider = MongoDb4Provider.newBuilder() .setConnectionStringSource(CON_STR_W_DB) - .setCollectionName(collectionName) + .setCollectionName(COLLECTION_NAME) .build(); - - assertNotNull(provider); - - MongoNamespace namespace = findProviderNamespace(provider); - assertEquals(collectionName, namespace.getCollectionName()); - - assertEquals("logging", namespace.getDatabaseName()); + assertThat(provider).isNotNull(); + assertProviderNamespace(provider, "logging", COLLECTION_NAME); } @Test void createProviderConfigOverridesConnectionString() { - MongoDb4Provider provider = MongoDb4Provider.newBuilder() .setConnectionStringSource(CON_STR_DB_COLL) - .setCollectionName(collectionName) - .setDatabaseName(databaseName) + .setCollectionName(COLLECTION_NAME) + .setDatabaseName(DATABASE_NAME) .build(); + assertThat(provider).isNotNull(); + assertProviderNamespace(provider, DATABASE_NAME, COLLECTION_NAME); + } - assertNotNull(provider); - MongoNamespace namespace = findProviderNamespace(provider); - assertEquals(collectionName, namespace.getCollectionName()); - assertEquals(databaseName, namespace.getDatabaseName()); + private static void assertProviderNamespace(MongoDb4Provider provider, String databaseName, String collectionName) { + MongoNamespace namespace = providerNamespace(provider); + assertThat(namespace.getDatabaseName()).isEqualTo(databaseName); + assertThat(namespace.getCollectionName()).isEqualTo(collectionName); } - private static MongoNamespace findProviderNamespace(final MongoDb4Provider provider) { - MongoDb4Connection connection = provider.getConnection(); + private static MongoNamespace providerNamespace(MongoDb4Provider provider) { try { - Field collectionField = connection.getClass().getDeclaredField("collection"); + MongoDb4Connection connection = provider.getConnection(); + Field collectionField = MongoDb4Connection.class.getDeclaredField("collection"); collectionField.setAccessible(true); - MongoCollection collection = (MongoCollection) collectionField.get(connection); + @SuppressWarnings("unchecked") + MongoCollection collection = (MongoCollection) collectionField.get(connection); return collection.getNamespace(); } catch (Exception exception) { throw new RuntimeException(exception); diff --git a/log4j-mongodb4/src/test/java/org/apache/logging/log4j/mongodb4/MongoDb4Resolver.java b/log4j-mongodb4/src/test/java/org/apache/logging/log4j/mongodb4/MongoDb4Resolver.java index 0534c09631a..c4e1628db4b 100644 --- a/log4j-mongodb4/src/test/java/org/apache/logging/log4j/mongodb4/MongoDb4Resolver.java +++ b/log4j-mongodb4/src/test/java/org/apache/logging/log4j/mongodb4/MongoDb4Resolver.java @@ -30,8 +30,6 @@ class MongoDb4Resolver extends TypeBasedParameterResolver implements BeforeAllCallback { - static final String PORT_PROPERTY = "log4j2.mongo.port"; - public MongoDb4Resolver() { super(MongoClient.class); } From 0712caea89f840ca5f487a05cceecdcbae7fa28f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Volkan=20Yaz=C4=B1c=C4=B1?= Date: Wed, 19 Feb 2025 16:19:19 +0100 Subject: [PATCH 25/27] Restore `maven-wrapper.properties` --- .mvn/wrapper/maven-wrapper.properties | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 .mvn/wrapper/maven-wrapper.properties diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties new file mode 100644 index 00000000000..c76af40b2f9 --- /dev/null +++ b/.mvn/wrapper/maven-wrapper.properties @@ -0,0 +1,20 @@ +# 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. +distributionSha256Sum=8351955a9acf2f83c136c4eee0f6db894ab6265fdbe0a94b32a380307dbaa3e1 +distributionType=only-script +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.8/apache-maven-3.9.8-bin.zip +wrapperVersion=3.3.2 From 8eef677560c8203cc4f592a0d4bf63db7ae47187 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Volkan=20Yaz=C4=B1c=C4=B1?= Date: Wed, 19 Feb 2025 17:10:53 +0100 Subject: [PATCH 26/27] Fix plugin names --- log4j-mongodb4/src/test/resources/MongoDb4CollectionNameIT.xml | 2 +- .../src/test/resources/MongoDb4DatabaseAndCollectionNameIT.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/log4j-mongodb4/src/test/resources/MongoDb4CollectionNameIT.xml b/log4j-mongodb4/src/test/resources/MongoDb4CollectionNameIT.xml index 4b9b53842ed..82c2de68b6c 100644 --- a/log4j-mongodb4/src/test/resources/MongoDb4CollectionNameIT.xml +++ b/log4j-mongodb4/src/test/resources/MongoDb4CollectionNameIT.xml @@ -22,7 +22,7 @@ https://logging.apache.org/xml/ns/log4j-config-2.xsd"> - - Date: Thu, 20 Feb 2025 14:26:27 +0100 Subject: [PATCH 27/27] Fix test resource files --- .../logging/log4j/mongodb4/MongoDb4Provider.java | 11 ++++++----- .../log4j/mongodb4/AbstractMongoDb4CappedIT.java | 6 ++++-- .../src/test/resources/MongoDb4CollectionNameIT.xml | 3 +-- .../resources/MongoDb4DatabaseAndCollectionNameIT.xml | 3 +-- 4 files changed, 12 insertions(+), 11 deletions(-) diff --git a/log4j-mongodb4/src/main/java/org/apache/logging/log4j/mongodb4/MongoDb4Provider.java b/log4j-mongodb4/src/main/java/org/apache/logging/log4j/mongodb4/MongoDb4Provider.java index e8522658d85..18cf93f2356 100644 --- a/log4j-mongodb4/src/main/java/org/apache/logging/log4j/mongodb4/MongoDb4Provider.java +++ b/log4j-mongodb4/src/main/java/org/apache/logging/log4j/mongodb4/MongoDb4Provider.java @@ -40,6 +40,8 @@ @Plugin(name = MongoDb4Provider.PLUGIN_NAME, category = Core.CATEGORY_NAME, printObject = true) public final class MongoDb4Provider implements NoSqlProvider { + private static final StatusLogger LOGGER = StatusLogger.getLogger(); + static final String PLUGIN_NAME = "MongoDb4"; /** @@ -68,8 +70,7 @@ public static class Builder> extends AbstractFilterable.Bui @Override public MongoDb4Provider build() { - StatusLogger.getLogger() - .warn("The {} Appender is deprecated, use the MongoDb Appender instead.", PLUGIN_NAME); + LOGGER.warn("The {} Appender is deprecated, use the MongoDb Appender instead.", PLUGIN_NAME); return newMongoDb4Provider(); } @@ -186,6 +187,7 @@ private MongoDb4Provider( this.isCapped = isCapped; this.collectionSize = collectionSize; this.collectionName = getEffectiveCollectionName(connectionString, collectionName); + LOGGER.debug("instantiated {}", this); } private static ConnectionString createConnectionString(final String connectionStringSource) { @@ -233,13 +235,12 @@ public MongoDb4Connection getConnection() { @Override public String toString() { return String.format( - "%s [connectionString=%s, collectionSize=%s, isCapped=%s, mongoClient=%s, mongoDatabase=%s, collectionName=%s]", + "%s [connectionString=`%s`, collectionSize=%s, isCapped=%s, databaseName=`%s`, collectionName=`%s`]", MongoDb4Provider.class.getSimpleName(), connectionString, collectionSize, isCapped, - mongoClient, - mongoDatabase, + mongoDatabase.getName(), collectionName); } } diff --git a/log4j-mongodb4/src/test/java/org/apache/logging/log4j/mongodb4/AbstractMongoDb4CappedIT.java b/log4j-mongodb4/src/test/java/org/apache/logging/log4j/mongodb4/AbstractMongoDb4CappedIT.java index 07483dd3cf2..caac94e6b5e 100644 --- a/log4j-mongodb4/src/test/java/org/apache/logging/log4j/mongodb4/AbstractMongoDb4CappedIT.java +++ b/log4j-mongodb4/src/test/java/org/apache/logging/log4j/mongodb4/AbstractMongoDb4CappedIT.java @@ -24,6 +24,7 @@ import com.mongodb.client.MongoDatabase; import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.core.LoggerContext; +import org.apache.logging.log4j.status.StatusLogger; import org.bson.Document; abstract class AbstractMongoDb4CappedIT { @@ -33,8 +34,9 @@ protected void test(final LoggerContext ctx, final MongoClient mongoClient) { logger.info("Hello log"); final MongoDatabase database = mongoClient.getDatabase(MongoDb4TestConstants.DATABASE_NAME); assertNotNull(database); - final MongoCollection collection = - database.getCollection(getClass().getSimpleName()); + final String collectionName = getClass().getSimpleName(); + StatusLogger.getLogger().debug("Using collection name: {}", collectionName); + final MongoCollection collection = database.getCollection(collectionName); assertNotNull(collection); final Document first = collection.find().first(); assertNotNull(first); diff --git a/log4j-mongodb4/src/test/resources/MongoDb4CollectionNameIT.xml b/log4j-mongodb4/src/test/resources/MongoDb4CollectionNameIT.xml index 82c2de68b6c..09834dc526c 100644 --- a/log4j-mongodb4/src/test/resources/MongoDb4CollectionNameIT.xml +++ b/log4j-mongodb4/src/test/resources/MongoDb4CollectionNameIT.xml @@ -25,8 +25,7 @@ + collectionName="MongoDb4CollectionNameIT"/> diff --git a/log4j-mongodb4/src/test/resources/MongoDb4DatabaseAndCollectionNameIT.xml b/log4j-mongodb4/src/test/resources/MongoDb4DatabaseAndCollectionNameIT.xml index f50ed40e584..790c991ccf7 100644 --- a/log4j-mongodb4/src/test/resources/MongoDb4DatabaseAndCollectionNameIT.xml +++ b/log4j-mongodb4/src/test/resources/MongoDb4DatabaseAndCollectionNameIT.xml @@ -25,9 +25,8 @@