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:
17
pom.xml
17
pom.xml
@@ -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>
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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) }
|
||||
|
||||
|
||||
}
|
||||
@@ -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 -->
|
||||
|
||||
Reference in New Issue
Block a user