Skip to content

Commit

Permalink
Add KiwiMongoConverters utility class (#435)
Browse files Browse the repository at this point in the history
* Add KiwiMongoConverters and test
* Add Spring Data MongoDB to the POM. Since our service code is
  currently all using the 2.x series, we are only updating to the
  latest 2.x version, which is 2.2.11.RELEASE as of 2020-11-12
* Add mongo-java-server as test scope dependency

Fixes #410
  • Loading branch information
sleberknight authored Nov 12, 2020
1 parent a4745ab commit 7f09f1e
Show file tree
Hide file tree
Showing 3 changed files with 174 additions and 0 deletions.
38 changes: 38 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
<metrics-jetty9.version>4.1.14</metrics-jetty9.version>
<postgresql.version>42.2.12</postgresql.version>
<spring.version>5.3.0</spring.version>
<spring-data-mongodb.version>2.2.11.RELEASE</spring-data-mongodb.version>
<stax2-api.version>4.2.1</stax2-api.version>
<stax-ex.version>1.8.3</stax-ex.version>
<!--
Expand All @@ -83,6 +84,7 @@
<jdbi3.version>3.17.0</jdbi3.version>
<jersey-test-framework-core.version>2.32</jersey-test-framework-core.version>
<liquibase.version>3.8.9</liquibase.version>
<mongo-java-server.version>1.36.0</mongo-java-server.version>
</properties>

<dependencies>
Expand Down Expand Up @@ -514,6 +516,35 @@
<scope>provided</scope>
</dependency>

<!-- TODO Need exclusions until we can bring Spring Data Mongo fully up-to-date -->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb</artifactId>
<version>${spring-data-mongodb.version}</version>
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
</exclusion>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</exclusion>
</exclusions>
</dependency>

<dependency>
<groupId>org.codehaus.woodstox</groupId>
<artifactId>stax2-api</artifactId>
Expand Down Expand Up @@ -635,6 +666,13 @@
</exclusions>
</dependency>

<dependency>
<groupId>de.bwaldvogel</groupId>
<artifactId>mongo-java-server</artifactId>
<version>${mongo-java-server.version}</version>
<scope>test</scope>
</dependency>

</dependencies>

</project>
62 changes: 62 additions & 0 deletions src/main/java/org/kiwiproject/spring/data/KiwiMongoConverters.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package org.kiwiproject.spring.data;

import static com.google.common.base.Preconditions.checkArgument;

import com.google.common.collect.Lists;
import lombok.experimental.UtilityClass;
import org.bson.BsonUndefined;
import org.springframework.core.convert.converter.Converter;
import org.springframework.data.convert.CustomConversions;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
import org.springframework.data.mongodb.core.convert.MongoCustomConversions;

/**
* A few utilities related to Spring Data Mongo and custom {@link Converter}s.
*/
@UtilityClass
public class KiwiMongoConverters {

/**
* Create a new {@link BsonUndefinedToNullStringConverter}.
*
* @return new BsonUndefinedToNullStringConverter instance
*/
public static Converter<BsonUndefined, String> newBsonUndefinedToNullObjectConverter() {
return new BsonUndefinedToNullStringConverter();
}

/**
* Adds one or more custom converters to a {@link MongoTemplate} instance.
* <p>
* The MongoTemplate is assumed to have a {@link Converter} of type {@link MappingMongoConverter}.
*
* @param template the MongoTemplate
* @param converters the converters to add to MongoTemplate's existing converter
* @throws IllegalArgumentException if the given MongoTemplate's {@link Converter} is <em>not</em>
* a {@link MappingMongoConverter}
* @see org.springframework.data.mongodb.core.convert.AbstractMongoConverter#setCustomConversions(CustomConversions)
*/
public static MongoTemplate addCustomConverters(MongoTemplate template, Converter<?, ?>... converters) {
checkArgument(template.getConverter() instanceof MappingMongoConverter,
"Currently a MappingMongoConverter is required as the MongoTemplate's converter");

var converter = (MappingMongoConverter) template.getConverter();
converter.setCustomConversions(new MongoCustomConversions(Lists.newArrayList(converters)));
converter.afterPropertiesSet();

return template;
}

/**
* A {@link Converter} that maps from the JS 'undefined' type to a 'null' value.
*/
public static class BsonUndefinedToNullStringConverter implements Converter<BsonUndefined, String> {

@SuppressWarnings("NullableProblems")
@Override
public String convert(BsonUndefined bsonUndefined) {
return null;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package org.kiwiproject.spring.data;

import static org.assertj.core.api.Assertions.assertThat;
import static org.kiwiproject.base.KiwiStrings.f;

import de.bwaldvogel.mongo.MongoServer;
import de.bwaldvogel.mongo.backend.memory.MemoryBackend;
import org.bson.BsonUndefined;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.SimpleMongoClientDbFactory;

@DisplayName("KiwiMongoConverters")
class KiwiMongoConvertersTest {

private static MongoServer mongoServer;

private MongoTemplate mongoTemplate;

@BeforeAll
static void beforeAll() {
mongoServer = startInMemoryMongoServer();
}

@AfterAll
static void afterAll() {
mongoServer.shutdownNow();
}

@BeforeEach
void setUp() {
var addr = mongoServer.getLocalAddress();
var connectionString = f("mongodb://{}:{}/kiwi_mongo_converters_test", addr.getHostName(), addr.getPort());
var factory = new SimpleMongoClientDbFactory(connectionString);
mongoTemplate = new MongoTemplate(factory);
}

@Nested
class AddCustomConverters {

@Test
void shouldAddConverters() {
var converter = KiwiMongoConverters.newBsonUndefinedToNullObjectConverter();
KiwiMongoConverters.addCustomConverters(mongoTemplate, converter);

var bsonUndefined = new BsonUndefined();
var result = mongoTemplate.getConverter().getConversionService().convert(bsonUndefined, String.class);
assertThat(result).isNull();
}
}

@Nested
class BsonUndefinedToNullStringConverter {

@Test
void shouldConvertToNull() {
var converter = KiwiMongoConverters.newBsonUndefinedToNullObjectConverter();
assertThat(converter.convert(new BsonUndefined())).isNull();
}
}


private static MongoServer startInMemoryMongoServer() {
var mongoServer = new MongoServer(new MemoryBackend());
mongoServer.bind();
return mongoServer;
}

}

0 comments on commit 7f09f1e

Please sign in to comment.