From f72cd0dee77794b8e0b370bb45362d94b15aa520 Mon Sep 17 00:00:00 2001 From: chrisjaimes <45322800+chrisjaimes@users.noreply.github.com> Date: Wed, 6 Jul 2022 23:57:53 -0400 Subject: [PATCH] BAEL-5363 Mongodb crud by date (#12293) Created new mongo module, model, mongo client and unit test Co-authored-by: Christian Jaimes Co-authored-by: bipster --- .../java-mongodb-queries/README.md | 0 .../java-mongodb-queries/pom.xml | 34 ++++ .../com.baeldung.mongo/crud/CrudClient.java | 183 ++++++++++++++++++ .../com.baeldung.mongo/crud/model/Event.java | 28 +++ .../CrudClientLiveTest.java | 87 +++++++++ pom.xml | 5 +- 6 files changed, 336 insertions(+), 1 deletion(-) create mode 100644 persistence-modules/java-mongodb-queries/README.md create mode 100644 persistence-modules/java-mongodb-queries/pom.xml create mode 100644 persistence-modules/java-mongodb-queries/src/main/java/com.baeldung.mongo/crud/CrudClient.java create mode 100644 persistence-modules/java-mongodb-queries/src/main/java/com.baeldung.mongo/crud/model/Event.java create mode 100644 persistence-modules/java-mongodb-queries/src/test/java/com.baeldung.mongo.crud/CrudClientLiveTest.java diff --git a/persistence-modules/java-mongodb-queries/README.md b/persistence-modules/java-mongodb-queries/README.md new file mode 100644 index 0000000000..e69de29bb2 diff --git a/persistence-modules/java-mongodb-queries/pom.xml b/persistence-modules/java-mongodb-queries/pom.xml new file mode 100644 index 0000000000..731d61f013 --- /dev/null +++ b/persistence-modules/java-mongodb-queries/pom.xml @@ -0,0 +1,34 @@ + + + + parent-modules + com.baeldung + 1.0.0-SNAPSHOT + ../../pom.xml + + 4.0.0 + + java-mongodb-queries + + + + org.mongodb + mongodb-driver-sync + 4.6.0 + + + org.junit.jupiter + junit-jupiter-api + 5.8.1 + compile + + + + + 8 + 8 + + + \ No newline at end of file diff --git a/persistence-modules/java-mongodb-queries/src/main/java/com.baeldung.mongo/crud/CrudClient.java b/persistence-modules/java-mongodb-queries/src/main/java/com.baeldung.mongo/crud/CrudClient.java new file mode 100644 index 0000000000..b71b88406d --- /dev/null +++ b/persistence-modules/java-mongodb-queries/src/main/java/com.baeldung.mongo/crud/CrudClient.java @@ -0,0 +1,183 @@ +package com.baeldung.mongo.crud; + +import com.baeldung.mongo.crud.model.Event; +import com.mongodb.BasicDBObject; +import com.mongodb.BasicDBObjectBuilder; +import com.mongodb.MongoException; +import com.mongodb.client.MongoClient; +import com.mongodb.client.MongoClients; +import com.mongodb.client.MongoCollection; +import com.mongodb.client.MongoDatabase; +import com.mongodb.client.model.UpdateOptions; +import com.mongodb.client.model.Updates; +import com.mongodb.client.result.InsertOneResult; +import com.mongodb.client.result.DeleteResult; +import com.mongodb.client.result.UpdateResult; +import org.bson.BsonValue; +import org.bson.Document; +import org.bson.codecs.configuration.CodecProvider; +import org.bson.codecs.configuration.CodecRegistry; +import org.bson.codecs.pojo.PojoCodecProvider; +import org.bson.conversions.Bson; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.OffsetDateTime; +import java.time.ZoneId; +import java.time.ZoneOffset; +import java.time.ZonedDateTime; +import java.util.ArrayList; +import java.util.List; + +import static com.mongodb.client.model.Filters.and; +import static com.mongodb.client.model.Filters.eq; +import static com.mongodb.MongoClientSettings.getDefaultCodecRegistry; +import static com.mongodb.client.model.Filters.gte; +import static com.mongodb.client.model.Filters.lt; +import static org.bson.codecs.configuration.CodecRegistries.fromProviders; +import static org.bson.codecs.configuration.CodecRegistries.fromRegistries; + +public class CrudClient { + + private static String uri = "mongodb://localhost:27017"; + private static MongoClient mongoClient = MongoClients.create(uri); + private static MongoDatabase db; + private static MongoCollection collection; + + public static OffsetDateTime offsetDateTime = OffsetDateTime.of(LocalDateTime.of(2022, 6, 4, 11, 0, 0), + ZoneOffset.ofHours(2)); + + public static Event pianoLessons = new Event( + "Piano lessons", + "Foo Bvld", + LocalDateTime.of(2022, 6, 4, 11, 0, 0)); + + public static Event soccerGame = new Event( + "Soccer game", + "Bar Avenue", + LocalDateTime.of(2022, 6, 10, 17, 0, 0)); + + public static Event pianoLessonsTZ = new Event( + "Piano lessons", + "Baz Bvld", + LocalDateTime.of(2022, 12, 31, 12, 0, 0), + ZoneOffset.ofHours(2).toString()); + + public static LocalDateTime dateQuery = LocalDateTime.of(2022, 6, 10, 17, 0, 0); + public static LocalDateTime dateQueryEventWithTZ = LocalDateTime.of(2022, 12, 31, 12, 0, 0); + + public static LocalDateTime from = LocalDateTime.of(2022, 06, 04, 12, 0, 0); + public static LocalDateTime to = LocalDateTime.of(2022, 06, 10, 17, 0, 0); + + public static LocalDate updateManyFrom = LocalDate.of(2022, 1, 1); + public static LocalDate updateManyTo = LocalDate.of(2023, 1, 1); + + public static LocalDate deleteFrom = LocalDate.of(2022, 1, 1); + public static LocalDate deleteTo = LocalDate.of(2023, 01, 01); + + public static void setup() { + CodecProvider codecProvider = PojoCodecProvider.builder().automatic(true).build(); + CodecRegistry codecRegistry = fromRegistries(getDefaultCodecRegistry(), fromProviders(codecProvider)); + + db = mongoClient.getDatabase("calendar").withCodecRegistry(codecRegistry); + collection = db.getCollection("my_events", Event.class); + } + + public static void close() { + mongoClient.close(); + } + + public static BsonValue insertEventsWithDate(Event e) { + try { + InsertOneResult insertResult = collection.insertOne(e); + return insertResult.getInsertedId(); + } catch (MongoException me) { + System.err.println("Failed to insert with error: " + me); + throw me; + } + } + + public static Event readEventsByDate(LocalDateTime localDateTime) { + try { + Event event = collection + .find(eq("dateTime", localDateTime)) + .first(); + return event; + } catch (MongoException me) { + System.err.println("Failed to read with error: " + me); + throw me; + } + } + + public static List readEventsByDateRange(LocalDateTime from, LocalDateTime to) { + BasicDBObject object = new BasicDBObject(); + object.put("dateTime", BasicDBObjectBuilder + .start("$gte", from) + .add("$lte", to) + .get()); + try { + List list = new ArrayList(collection.find(object).into(new ArrayList())); + return list; + } catch (MongoException me) { + System.err.println("Failed to read with error: " + me); + throw me; + } + } + + public static LocalDateTime readEventsByDateWithTZ(LocalDateTime localDateTime) { + try { + Event event = collection + .find(eq("dateTime", localDateTime)) + .first(); + OffsetDateTime offsetDateTime = OffsetDateTime.of(event.dateTime, ZoneOffset.of(pianoLessonsTZ.timeZoneOffset)); + ZonedDateTime zoned = offsetDateTime.atZoneSameInstant(ZoneId.of("America/Toronto")); + return zoned.toLocalDateTime(); + } catch (MongoException me) { + System.err.println("Failed to read with error: " + me); + throw me; + } + } + + public static long updateDateField() { + Document document = new Document().append("title", "Piano lessons"); + Bson update = Updates.currentDate("updatedAt"); + UpdateOptions options = new UpdateOptions().upsert(false); + try { + UpdateResult result = collection.updateOne(document, update, options); + return result.getModifiedCount(); + } catch (MongoException me) { + System.err.println("Failed to update with error: " + me); + throw me; + } + } + + public static long updateManyEventsWithDateCriteria(LocalDate updateManyFrom, LocalDate updateManyTo) { + Bson query = and(gte("dateTime", updateManyFrom), lt("dateTime", updateManyTo)); + Bson updates = Updates.currentDate("dateTime"); + try { + UpdateResult result = collection.updateMany(query, updates); + return result.getModifiedCount(); + } catch(MongoException me) { + System.err.println("Failed to replace/update with error: " + me); + throw me; + } + } + + public static long deleteEventsByDate(LocalDate from, LocalDate to) { + Bson query = and(gte("dateTime", from), lt("dateTime", to)); + try { + DeleteResult result = collection.deleteMany(query); + return result.getDeletedCount(); + } catch (MongoException me) { + System.err.println("Failed to delete with error: " + me); + throw me; + } + } + + public static void dropDb() { + db.drop(); + } + + public static void main(String[] args) { + } +} diff --git a/persistence-modules/java-mongodb-queries/src/main/java/com.baeldung.mongo/crud/model/Event.java b/persistence-modules/java-mongodb-queries/src/main/java/com.baeldung.mongo/crud/model/Event.java new file mode 100644 index 0000000000..751dc5d6eb --- /dev/null +++ b/persistence-modules/java-mongodb-queries/src/main/java/com.baeldung.mongo/crud/model/Event.java @@ -0,0 +1,28 @@ +package com.baeldung.mongo.crud.model; + +import java.time.LocalDateTime; + +public class Event { + public String title; + public String location; + public LocalDateTime dateTime; + public String timeZoneOffset; + + public Event() {} + public Event(String title, String location, LocalDateTime dateTime) { + this.title = title; + this.location = location; + this.dateTime = dateTime; + } + + public Event(String title, String location, LocalDateTime dateTime, String timeZoneOffset) { + this.title = title; + this.location = location; + this.dateTime = dateTime; + this.timeZoneOffset = timeZoneOffset; + } + + @Override + public String toString() { return "\nEvent: " + title + "\nWhere: " + location + "\nWhen: " + dateTime; } +} + diff --git a/persistence-modules/java-mongodb-queries/src/test/java/com.baeldung.mongo.crud/CrudClientLiveTest.java b/persistence-modules/java-mongodb-queries/src/test/java/com.baeldung.mongo.crud/CrudClientLiveTest.java new file mode 100644 index 0000000000..db2f35f634 --- /dev/null +++ b/persistence-modules/java-mongodb-queries/src/test/java/com.baeldung.mongo.crud/CrudClientLiveTest.java @@ -0,0 +1,87 @@ +package com.baeldung.mongo.crud; + +import com.baeldung.mongo.crud.model.Event; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Order; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; + +import java.io.IOException; +import java.util.List; + +@TestMethodOrder(MethodOrderer.OrderAnnotation.class) +public class CrudClientLiveTest { + + @BeforeAll + public static void setup() { + CrudClient.setup(); + } + + @Test + @Order(1) + public void whenInsertingEventsWithDate_thenCheckForDocument() { + Assertions.assertNotNull(CrudClient.insertEventsWithDate(CrudClient.pianoLessons)); + Assertions.assertNotNull(CrudClient.insertEventsWithDate(CrudClient.soccerGame)); + } + + @Test + @Order(2) + public void whenReadingEventsByDate_thenCheckForReturnedDocument() { + Assertions.assertNotNull(CrudClient.readEventsByDate(CrudClient.dateQuery)); + } + + @Test + @Order(3) + public void whenReadingEventsByDateRange_thenCheckForReturnedDocument() { + List events = CrudClient.readEventsByDateRange(CrudClient.from, CrudClient.to); + Assertions.assertNotNull(events); + Assertions.assertEquals(1, events.size()); + } + + @Test + @Order(5) + public void whenUpdatingEventsDateField_thenCheckUpdatedCount() { + Assertions.assertEquals(1, CrudClient.updateDateField()); + } + + @Test + @Order(6) + public void whenUpdatingManyEvents_thenCheckUpdatedCount() { + long updates = CrudClient.updateManyEventsWithDateCriteria(CrudClient.updateManyFrom, CrudClient.updateManyTo); + Assertions.assertTrue(1 < updates); + } + + @Test + @Order(7) + public void whenDeletingEventsWithDate_thenCheckDeletedCount() { + Assertions.assertEquals(2, CrudClient.deleteEventsByDate(CrudClient.deleteFrom, CrudClient.deleteTo)); + } + + @Test + @Order(8) + public void whenInsertingEventWithDateAndTimeZone_thenCheckForDocument() { + Assertions.assertNotNull(CrudClient.insertEventsWithDate(CrudClient.pianoLessonsTZ)); + } + + @Test + @Order(9) + public void whenReadingEventsWithDateAndTimeZone_thenCheckInsertedCount() { + Assertions.assertNotEquals(CrudClient.pianoLessonsTZ.dateTime, CrudClient.readEventsByDateWithTZ(CrudClient.dateQueryEventWithTZ)); + } + + @Test + @Order(10) + public void whenDeletingEventsWithDateAndTimeZone_thenCheckDeletedCount() { + Assertions.assertEquals(1, CrudClient.deleteEventsByDate(CrudClient.deleteFrom, CrudClient.deleteTo)); + } + + @AfterAll + public static void close() throws IOException { + CrudClient.dropDb(); + CrudClient.close(); + } + +} diff --git a/pom.xml b/pom.xml index 0801fbab46..046f59de53 100644 --- a/pom.xml +++ b/pom.xml @@ -7,7 +7,10 @@ com.baeldung parent-modules 1.0.0-SNAPSHOT - parent-modules + + persistence-modules/java-mongodb-queries + + parent-modules pom