diff --git a/src/main/java/org/springframework/data/r2dbc/connectionfactory/lookup/AbstractRoutingConnectionFactory.java b/src/main/java/org/springframework/data/r2dbc/connectionfactory/lookup/AbstractRoutingConnectionFactory.java index 6a128bb..136a7c6 100644 --- a/src/main/java/org/springframework/data/r2dbc/connectionfactory/lookup/AbstractRoutingConnectionFactory.java +++ b/src/main/java/org/springframework/data/r2dbc/connectionfactory/lookup/AbstractRoutingConnectionFactory.java @@ -38,6 +38,7 @@ import org.springframework.util.Assert; * ConnectionFactory} if configured. * * @author Mark Paluch + * @author Jens Schauder * @see #setTargetConnectionFactories * @see #setDefaultTargetConnectionFactory * @see #determineCurrentLookupKey() @@ -46,7 +47,7 @@ public abstract class AbstractRoutingConnectionFactory implements ConnectionFact private static final Object FALLBACK_MARKER = new Object(); - private @Nullable Map targetConnectionFactories; + private @Nullable Map targetConnectionFactories; private @Nullable Object defaultTargetConnectionFactory; @@ -67,9 +68,8 @@ public abstract class AbstractRoutingConnectionFactory implements ConnectionFact * representation will be handled by {@link #resolveSpecifiedLookupKey(Object)} and * {@link #determineCurrentLookupKey()}. */ - @SuppressWarnings("unchecked") public void setTargetConnectionFactories(Map targetConnectionFactories) { - this.targetConnectionFactories = (Map) targetConnectionFactories; + this.targetConnectionFactories = targetConnectionFactories; } /** @@ -79,7 +79,7 @@ public abstract class AbstractRoutingConnectionFactory implements ConnectionFact * {@link String} (to be resolved via a {@link #setConnectionFactoryLookup ConnectionFactoryLookup}). *

* This {@link ConnectionFactory} will be used as target if none of the keyed {@link #setTargetConnectionFactories - * targetConnectionFactories} match the {@link #determineCurrentLookupKey()} current lookup key. + * targetConnectionFactories} match the {@link #determineCurrentLookupKey() current lookup key}. */ public void setDefaultTargetConnectionFactory(Object defaultTargetConnectionFactory) { this.defaultTargetConnectionFactory = defaultTargetConnectionFactory; @@ -92,7 +92,7 @@ public abstract class AbstractRoutingConnectionFactory implements ConnectionFact * Default is {@literal true}, accepting lookup keys without a corresponding entry in the target * {@link ConnectionFactory} map - simply falling back to the default {@link ConnectionFactory} in that case. *

- * Switch this flag to {@literal false} if you would prefer the fallback to only apply no lookup key was emitted. + * Switch this flag to {@literal false} if you would prefer the fallback to only apply when no lookup key was emitted. * Lookup keys without a {@link ConnectionFactory} entry will then lead to an {@link IllegalStateException}. * * @see #setTargetConnectionFactories @@ -168,6 +168,7 @@ public abstract class AbstractRoutingConnectionFactory implements ConnectionFact } else if (connectionFactory instanceof String) { return this.connectionFactoryLookup.getConnectionFactory((String) connectionFactory); } else { + throw new IllegalArgumentException( "Illegal connection factory value - only 'io.r2dbc.spi.ConnectionFactory' and 'String' supported: " + connectionFactory); diff --git a/src/main/java/org/springframework/data/r2dbc/connectionfactory/lookup/MapConnectionFactoryLookup.java b/src/main/java/org/springframework/data/r2dbc/connectionfactory/lookup/MapConnectionFactoryLookup.java index 10a17ef..0a5a1f1 100644 --- a/src/main/java/org/springframework/data/r2dbc/connectionfactory/lookup/MapConnectionFactoryLookup.java +++ b/src/main/java/org/springframework/data/r2dbc/connectionfactory/lookup/MapConnectionFactoryLookup.java @@ -30,6 +30,7 @@ import org.springframework.util.Assert; * {@link ConnectionFactory} objects. * * @author Mark Paluch + * @author Jens Schauder */ public class MapConnectionFactoryLookup implements ConnectionFactoryLookup { @@ -111,13 +112,10 @@ public class MapConnectionFactoryLookup implements ConnectionFactoryLookup { Assert.notNull(connectionFactoryName, "ConnectionFactory name must not be null!"); - ConnectionFactory connectionFactory = this.connectionFactories.get(connectionFactoryName); + return this.connectionFactories.computeIfAbsent(connectionFactoryName, key -> { - if (connectionFactory == null) { throw new ConnectionFactoryLookupFailureException( "No ConnectionFactory with name '" + connectionFactoryName + "' registered"); - } - - return connectionFactory; + }); } } diff --git a/src/test/java/org/springframework/data/r2dbc/connectionfactory/lookup/AbstractRoutingConnectionFactoryUnitTests.java b/src/test/java/org/springframework/data/r2dbc/connectionfactory/lookup/AbstractRoutingConnectionFactoryUnitTests.java index 2feda2c..89c0fa7 100644 --- a/src/test/java/org/springframework/data/r2dbc/connectionfactory/lookup/AbstractRoutingConnectionFactoryUnitTests.java +++ b/src/test/java/org/springframework/data/r2dbc/connectionfactory/lookup/AbstractRoutingConnectionFactoryUnitTests.java @@ -15,6 +15,7 @@ */ package org.springframework.data.r2dbc.connectionfactory.lookup; +import static java.util.Collections.*; import static org.assertj.core.api.Assertions.*; import io.r2dbc.spi.ConnectionFactory; @@ -22,9 +23,6 @@ import reactor.core.publisher.Mono; import reactor.test.StepVerifier; import reactor.util.context.Context; -import java.util.Collections; -import java.util.Map; - import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -35,6 +33,7 @@ import org.mockito.junit.MockitoJUnitRunner; * Unit tests for {@link AbstractRoutingConnectionFactory}. * * @author Mark Paluch + * @author Jens Schauder */ @RunWith(MockitoJUnitRunner.class) public class AbstractRoutingConnectionFactoryUnitTests { @@ -44,23 +43,23 @@ public class AbstractRoutingConnectionFactoryUnitTests { @Mock ConnectionFactory defaultConnectionFactory; @Mock ConnectionFactory routedConnectionFactory; - DummyRoutingConnectionFactory sut; + DummyRoutingConnectionFactory connectionFactory; @Before public void before() { - sut = new DummyRoutingConnectionFactory(); - sut.setDefaultTargetConnectionFactory(defaultConnectionFactory); + connectionFactory = new DummyRoutingConnectionFactory(); + connectionFactory.setDefaultTargetConnectionFactory(defaultConnectionFactory); } @Test // gh-98 public void shouldDetermineRoutedFactory() { - sut.setTargetConnectionFactories(Collections.singletonMap("key", routedConnectionFactory)); - sut.setConnectionFactoryLookup(new MapConnectionFactoryLookup()); - sut.afterPropertiesSet(); + connectionFactory.setTargetConnectionFactories(singletonMap("key", routedConnectionFactory)); + connectionFactory.setConnectionFactoryLookup(new MapConnectionFactoryLookup()); + connectionFactory.afterPropertiesSet(); - sut.determineTargetConnectionFactory() // + connectionFactory.determineTargetConnectionFactory() // .subscriberContext(Context.of(ROUTING_KEY, "key")) // .as(StepVerifier::create) // .expectNext(routedConnectionFactory) // @@ -70,10 +69,10 @@ public class AbstractRoutingConnectionFactoryUnitTests { @Test // gh-98 public void shouldFallbackToDefaultConnectionFactory() { - sut.setTargetConnectionFactories(Collections.singletonMap("key", routedConnectionFactory)); - sut.afterPropertiesSet(); + connectionFactory.setTargetConnectionFactories(singletonMap("key", routedConnectionFactory)); + connectionFactory.afterPropertiesSet(); - sut.determineTargetConnectionFactory() // + connectionFactory.determineTargetConnectionFactory() // .as(StepVerifier::create) // .expectNext(defaultConnectionFactory) // .verifyComplete(); @@ -82,30 +81,31 @@ public class AbstractRoutingConnectionFactoryUnitTests { @Test // gh-98 public void initializationShouldFailUnsupportedLookupKey() { - sut.setTargetConnectionFactories(Collections.singletonMap("key", new Object())); + connectionFactory.setTargetConnectionFactories(singletonMap("key", new Object())); - assertThatThrownBy(() -> sut.afterPropertiesSet()).isInstanceOf(IllegalArgumentException.class); + assertThatThrownBy(() -> connectionFactory.afterPropertiesSet()).isInstanceOf(IllegalArgumentException.class); } @Test // gh-98 public void initializationShouldFailUnresolvableKey() { - sut.setTargetConnectionFactories(Collections.singletonMap("key", "value")); - sut.setConnectionFactoryLookup(new MapConnectionFactoryLookup()); + connectionFactory.setTargetConnectionFactories(singletonMap("key", "value")); + connectionFactory.setConnectionFactoryLookup(new MapConnectionFactoryLookup()); - assertThatThrownBy(() -> sut.afterPropertiesSet()).isInstanceOf(ConnectionFactoryLookupFailureException.class) + assertThatThrownBy(() -> connectionFactory.afterPropertiesSet()) // + .isInstanceOf(ConnectionFactoryLookupFailureException.class) // .hasMessageContaining("No ConnectionFactory with name 'value' registered"); } @Test // gh-98 public void unresolvableConnectionFactoryRetrievalShouldFail() { - sut.setLenientFallback(false); - sut.setConnectionFactoryLookup(new MapConnectionFactoryLookup()); - sut.setTargetConnectionFactories(Collections.singletonMap("key", routedConnectionFactory)); - sut.afterPropertiesSet(); + connectionFactory.setLenientFallback(false); + connectionFactory.setConnectionFactoryLookup(new MapConnectionFactoryLookup()); + connectionFactory.setTargetConnectionFactories(singletonMap("key", routedConnectionFactory)); + connectionFactory.afterPropertiesSet(); - sut.determineTargetConnectionFactory() // + connectionFactory.determineTargetConnectionFactory() // .subscriberContext(Context.of(ROUTING_KEY, "unknown")) // .as(StepVerifier::create) // .verifyError(IllegalStateException.class); @@ -114,11 +114,11 @@ public class AbstractRoutingConnectionFactoryUnitTests { @Test // gh-98 public void connectionFactoryRetrievalWithUnknownLookupKeyShouldReturnDefaultConnectionFactory() { - sut.setTargetConnectionFactories(Collections.singletonMap("key", routedConnectionFactory)); - sut.setDefaultTargetConnectionFactory(defaultConnectionFactory); - sut.afterPropertiesSet(); + connectionFactory.setTargetConnectionFactories(singletonMap("key", routedConnectionFactory)); + connectionFactory.setDefaultTargetConnectionFactory(defaultConnectionFactory); + connectionFactory.afterPropertiesSet(); - sut.determineTargetConnectionFactory() // + connectionFactory.determineTargetConnectionFactory() // .subscriberContext(Context.of(ROUTING_KEY, "unknown")) // .as(StepVerifier::create) // .expectNext(defaultConnectionFactory) // @@ -128,12 +128,12 @@ public class AbstractRoutingConnectionFactoryUnitTests { @Test // gh-98 public void connectionFactoryRetrievalWithoutLookupKeyShouldReturnDefaultConnectionFactory() { - sut.setTargetConnectionFactories(Collections.singletonMap("key", routedConnectionFactory)); - sut.setDefaultTargetConnectionFactory(defaultConnectionFactory); - sut.setLenientFallback(false); - sut.afterPropertiesSet(); + connectionFactory.setTargetConnectionFactories(singletonMap("key", routedConnectionFactory)); + connectionFactory.setDefaultTargetConnectionFactory(defaultConnectionFactory); + connectionFactory.setLenientFallback(false); + connectionFactory.afterPropertiesSet(); - sut.determineTargetConnectionFactory() // + connectionFactory.determineTargetConnectionFactory() // .as(StepVerifier::create) // .expectNext(defaultConnectionFactory) // .verifyComplete(); @@ -144,11 +144,11 @@ public class AbstractRoutingConnectionFactoryUnitTests { MapConnectionFactoryLookup lookup = new MapConnectionFactoryLookup("lookup-key", routedConnectionFactory); - sut.setConnectionFactoryLookup(lookup); - sut.setTargetConnectionFactories(Collections.singletonMap("my-key", "lookup-key")); - sut.afterPropertiesSet(); + connectionFactory.setConnectionFactoryLookup(lookup); + connectionFactory.setTargetConnectionFactories(singletonMap("my-key", "lookup-key")); + connectionFactory.afterPropertiesSet(); - sut.determineTargetConnectionFactory() // + connectionFactory.determineTargetConnectionFactory() // .subscriberContext(Context.of(ROUTING_KEY, "my-key")) // .as(StepVerifier::create) // .expectNext(routedConnectionFactory) // @@ -156,25 +156,24 @@ public class AbstractRoutingConnectionFactoryUnitTests { } @Test // gh-98 - @SuppressWarnings("unchecked") public void shouldAllowModificationsAfterInitialization() { MapConnectionFactoryLookup lookup = new MapConnectionFactoryLookup(); - sut.setConnectionFactoryLookup(lookup); - sut.setTargetConnectionFactories((Map) lookup.getConnectionFactories()); - sut.afterPropertiesSet(); + connectionFactory.setConnectionFactoryLookup(lookup); + connectionFactory.setTargetConnectionFactories(lookup.getConnectionFactories()); + connectionFactory.afterPropertiesSet(); - sut.determineTargetConnectionFactory() // + connectionFactory.determineTargetConnectionFactory() // .subscriberContext(Context.of(ROUTING_KEY, "lookup-key")) // .as(StepVerifier::create) // .expectNext(defaultConnectionFactory) // .verifyComplete(); lookup.addConnectionFactory("lookup-key", routedConnectionFactory); - sut.afterPropertiesSet(); + connectionFactory.afterPropertiesSet(); - sut.determineTargetConnectionFactory() // + connectionFactory.determineTargetConnectionFactory() // .subscriberContext(Context.of(ROUTING_KEY, "lookup-key")) // .as(StepVerifier::create) // .expectNext(routedConnectionFactory) // diff --git a/src/test/java/org/springframework/data/r2dbc/connectionfactory/lookup/BeanFactoryConnectionFactoryLookupUnitTests.java b/src/test/java/org/springframework/data/r2dbc/connectionfactory/lookup/BeanFactoryConnectionFactoryLookupUnitTests.java index 10b212f..795e866 100644 --- a/src/test/java/org/springframework/data/r2dbc/connectionfactory/lookup/BeanFactoryConnectionFactoryLookupUnitTests.java +++ b/src/test/java/org/springframework/data/r2dbc/connectionfactory/lookup/BeanFactoryConnectionFactoryLookupUnitTests.java @@ -49,6 +49,7 @@ public class BeanFactoryConnectionFactoryLookupUnitTests { BeanFactoryConnectionFactoryLookup lookup = new BeanFactoryConnectionFactoryLookup(); lookup.setBeanFactory(beanFactory); + ConnectionFactory connectionFactory = lookup.getConnectionFactory(CONNECTION_FACTORY_BEAN_NAME); assertThat(connectionFactory).isNotNull();