Declare 'cassandra.version' JVM System property on integration test JVM command-line.

This property is used to get the desired Cassandra Testcotnainer at our supported Apache Cassandra version when running SD Cassandrta integration tests using Testcontainers (profile).

Refactor CassandraDelegate to resolve the Cassandra version property used in the Testcontainers Docker Image name.

Refactor EmbeddedCassandraServerHelper to guard against NPEs when resolving the RPC address (InetAddress) hostname.

Add logging to distinguish which method (Embedded or Testcontainers) to start the Cassandra server.

See #1170.
This commit is contained in:
John Blum
2021-09-21 18:22:49 -07:00
committed by Mark Paluch
parent cd0e66935e
commit f332ea3e3f
5 changed files with 92 additions and 18 deletions

17
pom.xml
View File

@@ -85,8 +85,7 @@
<properties>
<build.cassandra.host>localhost</build.cassandra.host>
<build.cassandra.mode>embedded</build.cassandra.mode>
<build.cassandra.native_transport_port>19042
</build.cassandra.native_transport_port>
<build.cassandra.native_transport_port>19042</build.cassandra.native_transport_port>
<build.cassandra.rpc_port>19160</build.cassandra.rpc_port>
<build.cassandra.ssl_storage_port>17001</build.cassandra.ssl_storage_port>
<build.cassandra.storage_port>17000</build.cassandra.storage_port>
@@ -240,8 +239,8 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<configuration>
<argLine>-Xms1g -Xmx1500m -Xss256k -Dcassandra.version=${cassandra.version}</argLine>
<forkCount>1</forkCount>
<argLine>-Xms1g -Xmx1500m -Xss256k</argLine>
<reuseForks>true</reuseForks>
<useFile>false</useFile>
<includes>
@@ -345,26 +344,22 @@
</profile>
<profile>
<id>external-cassandra</id>
<properties>
<build.cassandra.mode>external</build.cassandra.mode>
<build.cassandra.native_transport_port>9042
</build.cassandra.native_transport_port>
<build.cassandra.native_transport_port>9042 </build.cassandra.native_transport_port>
<build.cassandra.rpc_port>9160</build.cassandra.rpc_port>
<build.cassandra.storage_port>7000</build.cassandra.storage_port>
<build.cassandra.ssl_storage_port>7001</build.cassandra.ssl_storage_port>
<build.cassandra.storage_port>7000</build.cassandra.storage_port>
</properties>
</profile>
<profile>
<id>testcontainers-cassandra</id>
<properties>
<build.cassandra.mode>testcontainers</build.cassandra.mode>
<build.cassandra.native_transport_port>0
</build.cassandra.native_transport_port>
<build.cassandra.native_transport_port>0 </build.cassandra.native_transport_port>
<build.cassandra.rpc_port>0</build.cassandra.rpc_port>
<build.cassandra.storage_port>0</build.cassandra.storage_port>
<build.cassandra.ssl_storage_port>0</build.cassandra.ssl_storage_port>
<build.cassandra.storage_port>0</build.cassandra.storage_port>
</properties>
</profile>
</profiles>

View File

@@ -22,6 +22,8 @@ import java.util.List;
import java.util.Map;
import java.util.Optional;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testcontainers.containers.CassandraContainer;
import org.springframework.data.cassandra.core.cql.SessionCallback;
@@ -58,6 +60,8 @@ class CassandraDelegate {
private static CassandraContainer<?> container;
private static final Logger log = LoggerFactory.getLogger(CassandraDelegate.class);
private static ResourceHolder resourceHolder;
private final long startupTimeout;
@@ -269,11 +273,14 @@ class CassandraDelegate {
if (container == null) {
container = getCassandraDockerImageName().map(CassandraContainer::new)
container = getCassandraDockerImageName()
.map(CassandraContainer::new)
.orElseGet(CassandraContainer::new);
container.start();
log.info("Running with Cassandra Docker Testcontainer Image Name [{}]", container.getDockerImageName());
this.properties.setCassandraHost(container.getContainerIpAddress());
this.properties.setCassandraPort(container.getFirstMappedPort());
this.properties.update();
@@ -282,11 +289,16 @@ class CassandraDelegate {
private Optional<String> getCassandraDockerImageName() {
return Optional.ofNullable(System.getenv("CASSANDRA_VERSION"))
.filter(StringUtils::hasText)
return resolveCassandraVersion()
.map(cassandraVersion -> String.format("cassandra:%s", cassandraVersion));
}
private Optional<String> resolveCassandraVersion() {
return Optional.ofNullable(System.getProperty("cassandra.version", System.getenv("CASSANDRA_VERSION")))
.filter(StringUtils::hasText);
}
private synchronized void initializeConnection() {
this.cassandraPort = resolvePort();

View File

@@ -15,14 +15,17 @@
*/
package org.springframework.data.cassandra.test.util;
import static java.util.concurrent.TimeUnit.*;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Arrays;
import java.util.Optional;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@@ -47,10 +50,12 @@ import org.springframework.util.FileSystemUtils;
@SuppressWarnings("unused")
class EmbeddedCassandraServerHelper {
public static final long DEFAULT_STARTUP_TIMEOUT_MS = TimeUnit.SECONDS.toMillis(20);
private static final Log LOG = LogFactory.getLog(EmbeddedCassandraServerHelper.class);
public static final long DEFAULT_STARTUP_TIMEOUT_MS = TimeUnit.SECONDS.toMillis(20);
private static final String DEFAULT_TMP_DIR = "target/embeddedCassandra";
private static final String LOCALHOST = "localhost";
private static final AtomicReference<Object> sync = new AtomicReference<>();
private static final AtomicReference<CassandraDaemon> cassandraRef = new AtomicReference<>();
@@ -72,7 +77,20 @@ class EmbeddedCassandraServerHelper {
* @return the cassandra host
*/
public static String getHost() {
return DatabaseDescriptor.getRpcAddress().getHostName();
return Optional.ofNullable(DatabaseDescriptor.getRpcAddress())
.map(InetAddress::getHostName)
.orElseGet(EmbeddedCassandraServerHelper::getLocalhost);
}
private static String getLocalhost() {
try {
return InetAddress.getLocalHost().getHostName();
}
catch (UnknownHostException ignore) {
return LOCALHOST;
}
}
/**
@@ -155,7 +173,7 @@ class EmbeddedCassandraServerHelper {
checkConfigNameForRestart(file.getAbsolutePath());
LOG.debug("Starting cassandra...");
LOG.info(String.format("Starting Embedded Cassandra [v%s]...", System.getProperty("cassandra.version")));
LOG.debug("Initialization needed");
System.setProperty("cassandra.config", "file:" + file.getAbsolutePath());

View File

@@ -0,0 +1,47 @@
/*
* Copyright 2021 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.cassandra.core
import org.springframework.data.cassandra.core.mapping.*
import java.time.LocalDate
import java.util.*
@Table("person")
data class Person(
@PrimaryKey("person_id")
val personId: UUID,
@field:Column("first_name")
val firstName: String,
@field:Column("last_name")
val lastName: String,
@field:Column("date_of_birth")
val dateOfBirth: LocalDate,
@field:Column("last_updated_at")
val lastUpdatedAt: LocalDate
)
fun main() {
val cctx = CassandraMappingContext()
val pe = cctx.getRequiredPersistentEntity(Person::class.java)
pe.doWithProperties { persistentProperty: CassandraPersistentProperty -> println(persistentProperty.columnName) }
}

View File

@@ -10,6 +10,8 @@
<logger name="org.springframework" level="ERROR" />
<logger name="org.springframework.data.cassandra" level="ERROR" />
<logger name="org.springframework.data.cassandra.test.util" level="INFO"/>
<logger name="com.datastax" level="ERROR" />
<!-- See https://issues.apache.org/jira/browse/CASSANDRA-8220 -->