diff --git a/benchmark/commons/pom.xml b/benchmark/commons/pom.xml index d50d481..94ae1cd 100644 --- a/benchmark/commons/pom.xml +++ b/benchmark/commons/pom.xml @@ -7,7 +7,7 @@ org.springframework.data.benchmark spring-data-benchmark-parent - 2.2.0.BUILD-SNAPSHOT + 2.3.0.BUILD-SNAPSHOT spring-data-benchmark-commons diff --git a/benchmark/mongodb/pom.xml b/benchmark/mongodb/pom.xml index 659c2d1..96ccc5f 100644 --- a/benchmark/mongodb/pom.xml +++ b/benchmark/mongodb/pom.xml @@ -7,7 +7,7 @@ org.springframework.data.benchmark spring-data-benchmark-parent - 2.2.0.BUILD-SNAPSHOT + 2.3.0.BUILD-SNAPSHOT spring-data-benchmark-mongodb diff --git a/benchmark/mongodb/src/main/java/org/springframework/data/microbenchmark/mongodb/AfterConvertCallbacksBenchmark.java b/benchmark/mongodb/src/main/java/org/springframework/data/microbenchmark/mongodb/AfterConvertCallbacksBenchmark.java new file mode 100644 index 0000000..5a432a5 --- /dev/null +++ b/benchmark/mongodb/src/main/java/org/springframework/data/microbenchmark/mongodb/AfterConvertCallbacksBenchmark.java @@ -0,0 +1,115 @@ +/* + * Copyright 2020 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://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.springframework.data.microbenchmark.mongodb; + +import org.bson.Document; +import org.mockito.Mockito; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.Setup; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.microbenchmark.common.AbstractMicrobenchmark; +import org.springframework.data.microbenchmark.mongodb.ProjectionsBenchmark.Address; +import org.springframework.data.microbenchmark.mongodb.ProjectionsBenchmark.Person; +import org.springframework.data.mongodb.MongoDatabaseFactory; +import org.springframework.data.mongodb.core.MongoTemplate; +import org.springframework.data.mongodb.core.SimpleMongoClientDatabaseFactory; +import org.springframework.data.mongodb.core.mapping.event.AfterConvertCallback; + +import com.mongodb.client.MongoClient; +import com.mongodb.client.MongoCollection; +import com.mongodb.client.MongoDatabase; + +/** + * @author Roman Puchkovskiy + */ +public class AfterConvertCallbacksBenchmark extends AbstractMicrobenchmark { + + private MongoTemplate templateWithoutContext; + private MongoTemplate templateWithEmptyContext; + private MongoTemplate templateWithContext; + + private Person source; + + @Setup + public void setUp() { + + MongoClient client = Mockito.mock(MongoClient.class); + MongoDatabase db = Mockito.mock(MongoDatabase.class); + MongoCollection collection = Mockito.mock(MongoCollection.class); + + Mockito.when(client.getDatabase(Mockito.anyString())).thenReturn(db); + Mockito.when(db.getCollection(Mockito.anyString(), Mockito.eq(Document.class))).thenReturn(collection); + + MongoDatabaseFactory factory = new SimpleMongoClientDatabaseFactory(client, "mock-database"); + + templateWithoutContext = new MongoTemplate(factory); + + templateWithEmptyContext = new MongoTemplate(factory); + templateWithEmptyContext.setApplicationContext(new AnnotationConfigApplicationContext(EmptyConfig.class)); + + templateWithContext = new MongoTemplate(factory); + templateWithContext.setApplicationContext(new AnnotationConfigApplicationContext(EntityCallbackConfig.class)); + + source = new Person(); + source.id = "luke-skywalker"; + source.firstname = "luke"; + source.lastname = "skywalker"; + + source.address = new Address(); + source.address.street = "melenium falcon 1"; + source.address.city = "deathstar"; + } + + @Benchmark + public Object baseline() { + return templateWithoutContext.save(source); + } + + @Benchmark + public Object emptyContext() { + return templateWithEmptyContext.save(source); + } + + @Benchmark + public Object entityCallbacks() { + return templateWithContext.save(source); + } + + @Configuration + static class EmptyConfig { + + } + + @Configuration + static class EntityCallbackConfig { + + @Bean + AfterConvertCallback afterConvertCallback() { + return (it, document, collection) -> { + + Person target = new Person(); + target.id = it.id; + target.firstname = it.firstname = "luke"; + target.lastname = it.lastname = "skywalker"; + + target.address = it.address; + return target; + }; + } + } +} diff --git a/benchmark/mongodb/src/main/java/org/springframework/data/microbenchmark/mongodb/CallbacksBenchmark.java b/benchmark/mongodb/src/main/java/org/springframework/data/microbenchmark/mongodb/CallbacksBenchmark.java index b0a280f..02962cb 100644 --- a/benchmark/mongodb/src/main/java/org/springframework/data/microbenchmark/mongodb/CallbacksBenchmark.java +++ b/benchmark/mongodb/src/main/java/org/springframework/data/microbenchmark/mongodb/CallbacksBenchmark.java @@ -25,9 +25,9 @@ import org.springframework.context.annotation.Configuration; import org.springframework.data.microbenchmark.common.AbstractMicrobenchmark; import org.springframework.data.microbenchmark.mongodb.ProjectionsBenchmark.Address; import org.springframework.data.microbenchmark.mongodb.ProjectionsBenchmark.Person; -import org.springframework.data.mongodb.MongoDbFactory; +import org.springframework.data.mongodb.MongoDatabaseFactory; import org.springframework.data.mongodb.core.MongoTemplate; -import org.springframework.data.mongodb.core.SimpleMongoClientDbFactory; +import org.springframework.data.mongodb.core.SimpleMongoClientDatabaseFactory; import org.springframework.data.mongodb.core.mapping.event.BeforeConvertCallback; import com.mongodb.client.MongoClient; @@ -55,7 +55,7 @@ public class CallbacksBenchmark extends AbstractMicrobenchmark { Mockito.when(client.getDatabase(Mockito.anyString())).thenReturn(db); Mockito.when(db.getCollection(Mockito.anyString(), Mockito.eq(Document.class))).thenReturn(collection); - MongoDbFactory factory = new SimpleMongoClientDbFactory(client, "mock-database"); + MongoDatabaseFactory factory = new SimpleMongoClientDatabaseFactory(client, "mock-database"); templateWithoutContext = new MongoTemplate(factory); @@ -100,7 +100,7 @@ public class CallbacksBenchmark extends AbstractMicrobenchmark { @Bean BeforeConvertCallback convertCallback() { - return (it, Document) -> { + return (it, document) -> { Person target = new Person(); target.id = it.id; diff --git a/benchmark/mongodb/src/main/java/org/springframework/data/microbenchmark/mongodb/ProjectionsBenchmark.java b/benchmark/mongodb/src/main/java/org/springframework/data/microbenchmark/mongodb/ProjectionsBenchmark.java index 2808f93..cf7d17a 100644 --- a/benchmark/mongodb/src/main/java/org/springframework/data/microbenchmark/mongodb/ProjectionsBenchmark.java +++ b/benchmark/mongodb/src/main/java/org/springframework/data/microbenchmark/mongodb/ProjectionsBenchmark.java @@ -28,8 +28,8 @@ import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.data.mongodb.core.mapping.Field; import org.springframework.data.mongodb.core.query.BasicQuery; -import com.mongodb.MongoClient; -import com.mongodb.ServerAddress; +import com.mongodb.client.MongoClient; +import com.mongodb.client.MongoClients; import com.mongodb.client.MongoCollection; /** @@ -57,7 +57,7 @@ public class ProjectionsBenchmark extends AbstractMicrobenchmark { @Setup public void setUp() { - client = new MongoClient(new ServerAddress()); + client = MongoClients.create(); template = new MongoTemplate(client, DB_NAME); source = new Person(); @@ -84,7 +84,7 @@ public class ProjectionsBenchmark extends AbstractMicrobenchmark { @TearDown public void tearDown() { - client.dropDatabase(DB_NAME); + client.getDatabase(DB_NAME).drop(); client.close(); } diff --git a/benchmark/mongodb/src/main/java/org/springframework/data/microbenchmark/mongodb/convert/DbRefMappingBenchmark.java b/benchmark/mongodb/src/main/java/org/springframework/data/microbenchmark/mongodb/convert/DbRefMappingBenchmark.java index 60d820d..d675e77 100644 --- a/benchmark/mongodb/src/main/java/org/springframework/data/microbenchmark/mongodb/convert/DbRefMappingBenchmark.java +++ b/benchmark/mongodb/src/main/java/org/springframework/data/microbenchmark/mongodb/convert/DbRefMappingBenchmark.java @@ -15,8 +15,8 @@ */ package org.springframework.data.microbenchmark.mongodb.convert; -import static org.springframework.data.mongodb.core.query.Criteria.*; -import static org.springframework.data.mongodb.core.query.Query.*; +import static org.springframework.data.mongodb.core.query.Criteria.where; +import static org.springframework.data.mongodb.core.query.Query.query; import lombok.Data; @@ -24,19 +24,15 @@ import java.util.ArrayList; import java.util.List; import org.bson.types.ObjectId; -import org.openjdk.jmh.annotations.Benchmark; -import org.openjdk.jmh.annotations.Scope; -import org.openjdk.jmh.annotations.Setup; -import org.openjdk.jmh.annotations.State; -import org.openjdk.jmh.annotations.TearDown; +import org.openjdk.jmh.annotations.*; import org.springframework.data.annotation.Id; import org.springframework.data.microbenchmark.common.AbstractMicrobenchmark; import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.data.mongodb.core.mapping.DBRef; import org.springframework.data.mongodb.core.query.Query; -import com.mongodb.MongoClient; -import com.mongodb.ServerAddress; +import com.mongodb.client.MongoClient; +import com.mongodb.client.MongoClients; /** * @author Christoph Strobl @@ -55,7 +51,7 @@ public class DbRefMappingBenchmark extends AbstractMicrobenchmark { @Setup public void setUp() throws Exception { - client = new MongoClient(new ServerAddress()); + client = MongoClients.create(); template = new MongoTemplate(client, DB_NAME); List refObjects = new ArrayList<>(); @@ -80,7 +76,7 @@ public class DbRefMappingBenchmark extends AbstractMicrobenchmark { @TearDown public void tearDown() { - client.dropDatabase(DB_NAME); + client.getDatabase(DB_NAME).drop(); client.close(); } diff --git a/benchmark/mongodb/src/main/java/org/springframework/data/microbenchmark/mongodb/convert/MappingMongoConverterBenchmark.java b/benchmark/mongodb/src/main/java/org/springframework/data/microbenchmark/mongodb/convert/MappingMongoConverterBenchmark.java index 4fc209a..a8a4a69 100644 --- a/benchmark/mongodb/src/main/java/org/springframework/data/microbenchmark/mongodb/convert/MappingMongoConverterBenchmark.java +++ b/benchmark/mongodb/src/main/java/org/springframework/data/microbenchmark/mongodb/convert/MappingMongoConverterBenchmark.java @@ -20,24 +20,15 @@ import lombok.Data; import lombok.Getter; import lombok.RequiredArgsConstructor; -import java.util.Arrays; -import java.util.Collections; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.UUID; +import java.util.*; import org.bson.Document; import org.bson.types.ObjectId; -import org.openjdk.jmh.annotations.Benchmark; -import org.openjdk.jmh.annotations.Scope; -import org.openjdk.jmh.annotations.Setup; -import org.openjdk.jmh.annotations.State; -import org.openjdk.jmh.annotations.TearDown; +import org.openjdk.jmh.annotations.*; import org.springframework.data.annotation.Id; import org.springframework.data.geo.Point; import org.springframework.data.microbenchmark.common.AbstractMicrobenchmark; -import org.springframework.data.mongodb.core.SimpleMongoDbFactory; +import org.springframework.data.mongodb.core.SimpleMongoClientDatabaseFactory; import org.springframework.data.mongodb.core.convert.DbRefResolver; import org.springframework.data.mongodb.core.convert.DefaultDbRefResolver; import org.springframework.data.mongodb.core.convert.MappingMongoConverter; @@ -45,8 +36,8 @@ import org.springframework.data.mongodb.core.convert.MongoCustomConversions; import org.springframework.data.mongodb.core.mapping.Field; import org.springframework.data.mongodb.core.mapping.MongoMappingContext; -import com.mongodb.MongoClient; -import com.mongodb.ServerAddress; +import com.mongodb.client.MongoClient; +import com.mongodb.client.MongoClients; /** * @author Christoph Strobl @@ -68,13 +59,13 @@ public class MappingMongoConverterBenchmark extends AbstractMicrobenchmark { @Setup public void setUp() throws Exception { - client = new MongoClient(new ServerAddress()); + client = MongoClients.create(); this.mappingContext = new MongoMappingContext(); this.mappingContext.setInitialEntitySet(Collections.singleton(Customer.class)); this.mappingContext.afterPropertiesSet(); - DbRefResolver dbRefResolver = new DefaultDbRefResolver(new SimpleMongoDbFactory(client, DB_NAME)); + DbRefResolver dbRefResolver = new DefaultDbRefResolver(new SimpleMongoClientDatabaseFactory(client, DB_NAME)); this.converter = new MappingMongoConverter(dbRefResolver, mappingContext); this.converter.setCustomConversions(new MongoCustomConversions(Collections.emptyList())); @@ -120,7 +111,7 @@ public class MappingMongoConverterBenchmark extends AbstractMicrobenchmark { @TearDown public void tearDown() { - client.dropDatabase(DB_NAME); + client.getDatabase(DB_NAME).drop(); client.close(); } diff --git a/benchmark/pom.xml b/benchmark/pom.xml index d5d9f6a..e333141 100644 --- a/benchmark/pom.xml +++ b/benchmark/pom.xml @@ -15,7 +15,7 @@ org.springframework.data.build spring-data-parent - 2.2.0.BUILD-SNAPSHOT + 2.3.0.BUILD-SNAPSHOT @@ -35,7 +35,7 @@ org.springframework.boot spring-boot-dependencies - 2.2.0.BUILD-SNAPSHOT + 2.3.0.BUILD-SNAPSHOT pom import @@ -58,6 +58,12 @@ 0.2.0.RELEASE + + net.minidev + json-smart + 2.3 + + diff --git a/benchmark/relational/pom.xml b/benchmark/relational/pom.xml index 5866013..28eece7 100644 --- a/benchmark/relational/pom.xml +++ b/benchmark/relational/pom.xml @@ -7,7 +7,7 @@ org.springframework.data.benchmark spring-data-benchmark-parent - 2.2.0.BUILD-SNAPSHOT + 2.3.0.BUILD-SNAPSHOT spring-data-benchmark-relational diff --git a/benchmark/support/pom.xml b/benchmark/support/pom.xml index de98938..1c93370 100644 --- a/benchmark/support/pom.xml +++ b/benchmark/support/pom.xml @@ -7,7 +7,7 @@ org.springframework.data.benchmark spring-data-benchmark-parent - 2.2.0.BUILD-SNAPSHOT + 2.3.0.BUILD-SNAPSHOT spring-data-benchmark-support @@ -21,11 +21,21 @@ spring-data-mongodb + + org.mongodb + mongodb-driver-sync + + com.github.mp911de.microbenchmark-runner microbenchmark-runner-junit4 + + net.minidev + json-smart + + diff --git a/benchmark/support/src/main/java/org/springframework/data/microbenchmark/common/MongoResultsWriter.java b/benchmark/support/src/main/java/org/springframework/data/microbenchmark/common/MongoResultsWriter.java index 9ce7e9c..059da41 100644 --- a/benchmark/support/src/main/java/org/springframework/data/microbenchmark/common/MongoResultsWriter.java +++ b/benchmark/support/src/main/java/org/springframework/data/microbenchmark/common/MongoResultsWriter.java @@ -17,10 +17,14 @@ package org.springframework.data.microbenchmark.common; import jmh.mbr.core.ResultsWriter; import lombok.RequiredArgsConstructor; +import net.minidev.json.JSONArray; +import net.minidev.json.JSONObject; +import net.minidev.json.parser.JSONParser; +import net.minidev.json.parser.ParseException; import java.util.Collection; import java.util.Date; -import java.util.List; +import java.util.Map; import org.bson.Document; import org.openjdk.jmh.results.RunResult; @@ -30,17 +34,17 @@ import org.springframework.util.CollectionUtils; import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; -import com.mongodb.BasicDBObject; -import com.mongodb.MongoClient; -import com.mongodb.MongoClientURI; +import com.mongodb.ConnectionString; +import com.mongodb.client.MongoClient; +import com.mongodb.client.MongoClients; import com.mongodb.client.MongoDatabase; -import com.mongodb.util.JSON; /** - * MongoDB specific {@link ResultsWriterOld} implementation. + * MongoDB specific {@link ResultsWriter} implementation. * * @author Christoph Strobl * @author Mark Paluch + * @author Roman Puchkovskiy */ @RequiredArgsConstructor class MongoResultsWriter implements ResultsWriter { @@ -56,12 +60,12 @@ class MongoResultsWriter implements ResultsWriter { try { doWrite(results); - } catch (RuntimeException e) { + } catch (ParseException | RuntimeException e) { output.println("Failed to write results: " + e.toString()); } } - private void doWrite(Collection results) { + private void doWrite(Collection results) throws ParseException { Date now = new Date(); StandardEnvironment env = new StandardEnvironment(); @@ -71,13 +75,16 @@ class MongoResultsWriter implements ResultsWriter { String gitDirty = env.getProperty("git.dirty", "no"); String gitCommitId = env.getProperty("git.commit.id", "unknown"); - MongoClientURI uri = new MongoClientURI(this.uri); - MongoClient client = new MongoClient(uri); + ConnectionString uri = new ConnectionString(this.uri); + MongoClient client = MongoClients.create(); String dbName = StringUtils.hasText(uri.getDatabase()) ? uri.getDatabase() : "spring-data-mongodb-benchmarks"; MongoDatabase db = client.getDatabase(dbName); - for (BasicDBObject dbo : (List) JSON.parse(ResultsWriter.jsonifyResults(results))) { + String resultsJson = ResultsWriter.jsonifyResults(results).trim(); + JSONArray array = (JSONArray) new JSONParser(JSONParser.MODE_PERMISSIVE).parse(resultsJson); + for (Object object : array) { + JSONObject dbo = (JSONObject) object; String collectionName = extractClass(dbo.get("benchmark").toString()); @@ -113,8 +120,8 @@ class MongoResultsWriter implements ResultsWriter { Object value = doc.get(key); if (value instanceof Document) { value = fixDocumentKeys((Document) value); - } else if (value instanceof BasicDBObject) { - value = fixDocumentKeys(new Document((BasicDBObject) value)); + } else if (value instanceof Map) { + value = fixDocumentKeys(new Document((Map) value)); } if (key instanceof String) {