Improve error checking

The container now gives error messages if you use programmatic cache creation with invalid InfinispanServer versions or invalid Hotrod protocol versions
This commit is contained in:
Reinhard Prechtl 2017-12-22 15:47:36 +01:00
parent d08688124e
commit 587e7d1d0d
3 changed files with 61 additions and 14 deletions

View file

@ -4,12 +4,16 @@ import com.github.dockerjava.api.command.InspectContainerResponse;
import org.infinispan.client.hotrod.ProtocolVersion; import org.infinispan.client.hotrod.ProtocolVersion;
import org.infinispan.client.hotrod.RemoteCacheManager; import org.infinispan.client.hotrod.RemoteCacheManager;
import org.infinispan.client.hotrod.configuration.ConfigurationBuilder; import org.infinispan.client.hotrod.configuration.ConfigurationBuilder;
import org.infinispan.client.hotrod.exceptions.HotRodClientException;
import org.junit.runner.Description; import org.junit.runner.Description;
import org.rnorth.ducttape.Preconditions;
import org.testcontainers.containers.BindMode;
import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.GenericContainer;
import org.testcontainers.containers.wait.LogMessageWaitStrategy; import org.testcontainers.containers.wait.LogMessageWaitStrategy;
import java.time.Duration; import java.time.Duration;
import java.util.*; import java.util.*;
import java.util.stream.IntStream;
import static java.time.temporal.ChronoUnit.SECONDS; import static java.time.temporal.ChronoUnit.SECONDS;
@ -24,6 +28,7 @@ public class InfinispanContainer extends GenericContainer<InfinispanContainer> {
private static final String IMAGE_NAME = "jboss/infinispan-server"; private static final String IMAGE_NAME = "jboss/infinispan-server";
public static final String STANDALONE_MODE_CMD = "standalone"; public static final String STANDALONE_MODE_CMD = "standalone";
private final String infinispanServerVersion;
/* /*
* An enumeration of the endpoints provided by Infinispan, that this container provides access to. * An enumeration of the endpoints provided by Infinispan, that this container provides access to.
@ -67,6 +72,8 @@ public class InfinispanContainer extends GenericContainer<InfinispanContainer> {
public InfinispanContainer(final String imageName) { public InfinispanContainer(final String imageName) {
super(imageName); super(imageName);
this.infinispanServerVersion = imageName.split(":")[1];
this.withCommand(STANDALONE_MODE_CMD); this.withCommand(STANDALONE_MODE_CMD);
withExposedPorts(Arrays.stream(InfinispanEndpoints.values()).map(endpoint -> endpoint.protocolPort).toArray(Integer[]::new)); withExposedPorts(Arrays.stream(InfinispanEndpoints.values()).map(endpoint -> endpoint.protocolPort).toArray(Integer[]::new));
@ -137,23 +144,51 @@ public class InfinispanContainer extends GenericContainer<InfinispanContainer> {
* @return The container itself * @return The container itself
*/ */
public InfinispanContainer withCaches(final Collection<String> cacheNames) { public InfinispanContainer withCaches(final Collection<String> cacheNames) {
if (incompatibleProtocolVersions.contains(protocolVersion)) {
throw new IllegalArgumentException( if (isProtocolConflict()) {
"You have to use a Hotrod protocol version of 2.0 at least. 1.x can't create caches through the API. " + throw new IllegalArgumentException("Programmatic cache creation only works with Hotrod protocol version >= 2.0!");
"You can still map a configuration file into the container using '.withClasspathResourceMapping()'");
} }
if (isMajorVersionConflict() || isMinorVersionConflict()) {
throw new IllegalStateException("Programmatic cache creation only works with InfinispanServer version >= 9.1.0!");
}
this.cacheNames = cacheNames; this.cacheNames = cacheNames;
return this; return this;
} }
/**
* Links a configuration file for a standalone Infinispan server into the container. The configuration file format needs to match the server version.
*
* @param filenameFromClasspath The filename containing the standalone configuration.
* @return The container itself
*/
public InfinispanContainer withStandaloneConfiguration(final String filenameFromClasspath) {
return withClasspathResourceMapping(
filenameFromClasspath,
"/opt/jboss/infinispan-server/standalone/configuration/standalone.xml",
BindMode.READ_ONLY);
}
@Override @Override
protected void containerIsStarted(final InspectContainerResponse containerInfo) { protected void containerIsStarted(final InspectContainerResponse containerInfo) {
cacheManager = new RemoteCacheManager(new ConfigurationBuilder() cacheManager = new RemoteCacheManager(new ConfigurationBuilder()
.addServers(getHotrodEndpointConnectionString()) .addServers(getHotrodEndpointConnectionString())
.version(getProtocolVersion()) .version(getProtocolVersion())
.build()); .build());
if (cacheManager == null) {
throw new IllegalStateException("Couldn't instantiate cacheManager");
}
this.cacheNames.forEach(this::createCache);
}
this.cacheNames.forEach(cacheName -> cacheManager.administration().createCache(cacheName, null)); private void createCache(final String cacheName) {
try {
cacheManager.administration().createCache(cacheName, null);
} catch (HotRodClientException e) {
logger().error("Couldn't create cache '{}'", cacheName, e);
}
} }
@Override @Override
@ -185,4 +220,21 @@ public class InfinispanContainer extends GenericContainer<InfinispanContainer> {
public RemoteCacheManager getCacheManager() { public RemoteCacheManager getCacheManager() {
return cacheManager; return cacheManager;
} }
private boolean isProtocolConflict() {
return incompatibleProtocolVersions.contains(protocolVersion);
}
private boolean isMajorVersionConflict() {
return IntStream.range(1, 8)
.anyMatch(majorVersion -> infinispanServerVersion.startsWith(Integer.toString(majorVersion)));
}
private boolean isMinorVersionConflict() {
boolean minorVersionConflict = false;
if (infinispanServerVersion.startsWith("9.0")) {
minorVersionConflict = true;
}
return minorVersionConflict;
}
} }

View file

@ -2,8 +2,6 @@ import de.rpr.testcontainers.infinispan.InfinispanContainer;
import org.infinispan.client.hotrod.ProtocolVersion; import org.infinispan.client.hotrod.ProtocolVersion;
import org.junit.ClassRule; import org.junit.ClassRule;
import org.junit.Test; import org.junit.Test;
import org.testcontainers.containers.BindMode;
import org.testcontainers.containers.GenericContainer;
import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotNull;
@ -11,11 +9,8 @@ public class Infinispan90xContainerIntegrationTest {
@ClassRule @ClassRule
public static InfinispanContainer infinispan = new InfinispanContainer("jboss/infinispan-server:9.0.3.Final") public static InfinispanContainer infinispan = new InfinispanContainer("jboss/infinispan-server:9.0.3.Final")
.withProtocolVersion(ProtocolVersion.PROTOCOL_VERSION_26) .withProtocolVersion(ProtocolVersion.PROTOCOL_VERSION_26)
.withClasspathResourceMapping( .withStandaloneConfiguration("infinispan-90x-standalone.xml");
"infinispan-90x-standalone.xml",
"/opt/jboss/infinispan-server/standalone/configuration/standalone.xml",
BindMode.READ_ONLY) ;
@Test @Test
public void rule_should_have_mapped_hotrod_port() { public void rule_should_have_mapped_hotrod_port() {

View file

@ -8,8 +8,8 @@ import static org.junit.Assert.assertNotNull;
public class Infinispan91xContainerIntegrationTest { public class Infinispan91xContainerIntegrationTest {
@ClassRule @ClassRule
public static InfinispanContainer infinispan = new InfinispanContainer("jboss/infinispan-server:9.1.4.Final") public static InfinispanContainer infinispan = new InfinispanContainer("jboss/infinispan-server:9.1.3.Final")
.withProtocolVersion(ProtocolVersion.PROTOCOL_VERSION_26) .withProtocolVersion(ProtocolVersion.PROTOCOL_VERSION_20)
.withCaches("testCache"); .withCaches("testCache");
@Test @Test