Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce cassandra-test-image and Update Docs #708

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

## Version 1.0.0 (Not yet Release)

* Investigate Introduction of testContainers Issue #682
* Update Architecture and Tests Documentations to Add the Agent Features and The cassandra-test-image - Issue #707
* Enhance Test Infrastructure by Adding Cassandra-Test-Image Module With Multi-Datacenter Cluster and Abstract Integration Test Class - Issue #706
* Investigate Introduction of testContainers - Issue #682
* Create EccNodesSync Object to Represent Table nodes_sync - Issue #672
* Expose AgentJMXConnectionProvider on Connection and Application Module - Issue #676
* Create JMXAgentConfig to add Hosts in JMX Session Through ecc.yml - Issue #675
Expand Down
99 changes: 99 additions & 0 deletions cassandra-test-image/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--

Copyright 2024 Telefonaktiebolaget LM Ericsson

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
http://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.

-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.ericsson.bss.cassandra.ecchronos</groupId>
<artifactId>agent</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>cassandra-test-image</artifactId>
<description>Test image for integration tests using Apache Cassandra</description>
<name>EcChronos Cassandra Test Image</name>

<dependencies>
<!-- Cassandra driver -->
<dependency>
<groupId>com.datastax.oss</groupId>
<artifactId>java-driver-core</artifactId>
</dependency>

<!-- Tests -->
<dependency>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.awaitility</groupId>
<artifactId>awaitility</artifactId>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>cassandra</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>

<plugin>
<artifactId>maven-install-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
</plugins>
</build>

<profiles>
<profile>
<id>build-cassandra-test-jar</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>test-jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>
11 changes: 11 additions & 0 deletions cassandra-test-image/src/main/docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
FROM cassandra:4.1.5

COPY ecc-entrypoint.sh /usr/local/bin/
RUN ln -s usr/local/bin/ecc-entrypoint.sh /ecc-entrypoint.sh

COPY create_keyspaces.cql /etc/cassandra/
COPY users.cql /etc/cassandra/
COPY setup_db.sh /etc/cassandra/

ENTRYPOINT ["ecc-entrypoint.sh"]
EXPOSE 7000 7001 7199 9042
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
dc= datacenter1
rack= rack1
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
dc= datacenter2
rack= rack1
17 changes: 17 additions & 0 deletions cassandra-test-image/src/main/docker/create_keyspaces.cql
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
CREATE KEYSPACE IF NOT EXISTS ecchronos WITH replication = {'class': 'NetworkTopologyStrategy', 'datacenter1': 1, 'datacenter2': 1};
CREATE TYPE IF NOT EXISTS ecchronos.token_range (start text, end text);
CREATE TYPE IF NOT EXISTS ecchronos.table_reference (id uuid, keyspace_name text, table_name text);
CREATE TABLE IF NOT EXISTS ecchronos.nodes_sync(ecchronos_id TEXT, datacenter_name TEXT, node_id UUID, node_endpoint TEXT, node_status TEXT, last_connection TIMESTAMP, next_connection TIMESTAMP, PRIMARY KEY(ecchronos_id, datacenter_name, node_id)) WITH CLUSTERING ORDER BY(datacenter_name DESC, node_id DESC);
CREATE TABLE IF NOT EXISTS ecchronos.on_demand_repair_status (host_id uuid, job_id uuid, table_reference frozen<table_reference>, token_map_hash int, repaired_tokens frozen<set<frozen<token_range>>>, status text, completed_time timestamp, repair_type text, PRIMARY KEY(host_id, job_id)) WITH default_time_to_live = 2592000 AND gc_grace_seconds = 0;
CREATE TABLE IF NOT EXISTS ecchronos.lock (resource text, node uuid, metadata map<text,text>, PRIMARY KEY(resource)) WITH default_time_to_live = 600 AND gc_grace_seconds = 0;
CREATE TABLE IF NOT EXISTS ecchronos.lock_priority (resource text, node uuid, priority int, PRIMARY KEY(resource, node)) WITH default_time_to_live = 600 AND gc_grace_seconds = 0;
CREATE TABLE IF NOT EXISTS ecchronos.reject_configuration (keyspace_name text, table_name text, start_hour int, start_minute int, end_hour int, end_minute int, PRIMARY KEY(keyspace_name, table_name, start_hour, start_minute));
CREATE TABLE IF NOT EXISTS ecchronos.repair_history(table_id uuid, node_id uuid, repair_id timeuuid, job_id uuid, coordinator_id uuid, range_begin text, range_end text, participants set<uuid>, status text, started_at timestamp, finished_at timestamp, PRIMARY KEY((table_id,node_id), repair_id)) WITH compaction = {'class': 'TimeWindowCompactionStrategy'} AND default_time_to_live = 1728000 AND CLUSTERING ORDER BY (repair_id DESC);
CREATE KEYSPACE IF NOT EXISTS test WITH replication = {'class': 'NetworkTopologyStrategy', 'datacenter1': 2, 'datacenter2': 1};
CREATE TABLE IF NOT EXISTS test.table1 (key1 text, key2 int, value int, PRIMARY KEY(key1, key2));
CREATE TABLE IF NOT EXISTS test.table2 (key1 text, key2 int, value int, PRIMARY KEY(key1, key2));
CREATE KEYSPACE IF NOT EXISTS test2 WITH replication = {'class': 'NetworkTopologyStrategy', 'datacenter1': 2, 'datacenter2': 1};
CREATE TABLE IF NOT EXISTS test2.table1 (key1 text, key2 int, value int, PRIMARY KEY(key1, key2));
CREATE TABLE IF NOT EXISTS test2.table2 (key1 text, key2 int, value int, PRIMARY KEY(key1, key2));
CREATE KEYSPACE IF NOT EXISTS "keyspaceWithCamelCase" WITH replication = {'class': 'NetworkTopologyStrategy', 'datacenter1': 2, 'datacenter2': 1};
CREATE TABLE IF NOT EXISTS "keyspaceWithCamelCase"."tableWithCamelCase" (key1 text, key2 int, value int, PRIMARY KEY(key1, key2));
93 changes: 93 additions & 0 deletions cassandra-test-image/src/main/docker/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
version: '3.1'
services:
cassandra-seed-dc1-rack1-node1:
build:
context: .
ports:
- "9042:9042"
- "7100:7199"
environment:
- CASSANDRA_CLUSTER_NAME=cassandra-cluster
- CASSANDRA_DC=datacenter1
- CASSANDRA_RACK=rack1
- CASSANDRA_ENDPOINT_SNITCH=GossipingPropertyFileSnitch
- CASSANDRA_SEEDS=cassandra-seed-dc1-rack1-node1,cassandra-seed-dc2-rack1-node1,cassandra-node-dc1-rack1-node2,cassandra-node-dc2-rack1-node2
- CASSANDRA_PASSWORD_SEEDER=yes
- CASSANDRA_PASSWORD=cassandra
- MAX_HEAP_SIZE=2G
- HEAP_NEWSIZE=200M
- LOCAL_JMX=no
- JVM_EXTRA_OPTS=-Dcom.sun.management.jmxremote.authenticate=false -Dcassandra.superuser_setup_delay_ms=0 -Dcassandra.skip_wait_for_gossip_to_settle=0 -Dcassandra.ring_delay_ms=0
volumes:
- cassandra-seed-dc1-rack1-node1-data:/var/lib/cassandra
- ./cassandra-rackdc-dc1-rack1.properties:/etc/cassandra/cassandra-rackdc.properties

cassandra-seed-dc2-rack1-node1:
build:
context: .
ports:
- "9043:9042"
- "7200:7199"
environment:
- CASSANDRA_CLUSTER_NAME=cassandra-cluster
- CASSANDRA_DC=datacenter2
- CASSANDRA_RACK=rack1
- CASSANDRA_ENDPOINT_SNITCH=GossipingPropertyFileSnitch
- CASSANDRA_SEEDS=cassandra-seed-dc1-rack1-node1,cassandra-seed-dc2-rack1-node1,cassandra-node-dc1-rack1-node2,cassandra-node-dc2-rack1-node2
- CASSANDRA_PASSWORD_SEEDER=yes
- CASSANDRA_PASSWORD=cassandra
- MAX_HEAP_SIZE=2G
- HEAP_NEWSIZE=200M
- LOCAL_JMX=no
- JVM_EXTRA_OPTS=-Dcom.sun.management.jmxremote.authenticate=false -Dcassandra.superuser_setup_delay_ms=0 -Dcassandra.skip_wait_for_gossip_to_settle=0 -Dcassandra.ring_delay_ms=0
volumes:
- cassandra-seed-dc2-rack1-node1-data:/var/lib/cassandra
- ./cassandra-rackdc-dc2-rack1.properties:/etc/cassandra/cassandra-rackdc.properties

cassandra-node-dc1-rack1-node2:
build:
context: .
ports:
- "7300:7199"
environment:
- CASSANDRA_CLUSTER_NAME=cassandra-cluster
- CASSANDRA_DC=datacenter1
- CASSANDRA_RACK=rack1
- CASSANDRA_ENDPOINT_SNITCH=GossipingPropertyFileSnitch
- CASSANDRA_SEEDS=cassandra-seed-dc1-rack1-node1,cassandra-seed-dc2-rack1-node1,cassandra-node-dc1-rack1-node2,cassandra-node-dc2-rack1-node2
- CASSANDRA_PASSWORD_SEEDER=yes
- CASSANDRA_PASSWORD=cassandra
- MAX_HEAP_SIZE=2G
- HEAP_NEWSIZE=200M
- LOCAL_JMX=no
- JVM_EXTRA_OPTS=-Dcom.sun.management.jmxremote.authenticate=false -Dcassandra.superuser_setup_delay_ms=0 -Dcassandra.skip_wait_for_gossip_to_settle=0 -Dcassandra.ring_delay_ms=0
volumes:
- cassandra-node-dc1-rack1-node2-data:/var/lib/cassandra
- ./cassandra-rackdc-dc1-rack1.properties:/etc/cassandra/cassandra-rackdc.properties

cassandra-node-dc2-rack1-node2:
build:
context: .
ports:
- "7400:7199"
environment:
- CASSANDRA_CLUSTER_NAME=cassandra-cluster
- CASSANDRA_DC=datacenter2
- CASSANDRA_RACK=rack1
- CASSANDRA_ENDPOINT_SNITCH=GossipingPropertyFileSnitch
- CASSANDRA_SEEDS=cassandra-seed-dc1-rack1-node1,cassandra-seed-dc2-rack1-node1,cassandra-node-dc1-rack1-node2,cassandra-node-dc2-rack1-node2
- CASSANDRA_PASSWORD_SEEDER=yes
- CASSANDRA_PASSWORD=cassandra
- MAX_HEAP_SIZE=2G
- HEAP_NEWSIZE=200M
- LOCAL_JMX=no
- JVM_EXTRA_OPTS=-Dcom.sun.management.jmxremote.authenticate=false -Dcassandra.superuser_setup_delay_ms=0 -Dcassandra.skip_wait_for_gossip_to_settle=0 -Dcassandra.ring_delay_ms=0
volumes:
- cassandra-node-dc2-rack1-node2-data:/var/lib/cassandra
- ./cassandra-rackdc-dc2-rack1.properties:/etc/cassandra/cassandra-rackdc.properties

volumes:
cassandra-seed-dc1-rack1-node1-data:
cassandra-seed-dc2-rack1-node1-data:
cassandra-node-dc1-rack1-node2-data:
cassandra-node-dc2-rack1-node2-data:
88 changes: 88 additions & 0 deletions cassandra-test-image/src/main/docker/ecc-entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
#!/bin/bash
#
# Copyright 2024 Telefonaktiebolaget LM Ericsson
#
# 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
# http://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.
#

set -e

sed -i "s/authenticator: .*/authenticator: PasswordAuthenticator/g" "$CASSANDRA_CONF"/cassandra.yaml
# Start of for 5.X
sed -i "/^authenticator:/{n;s/class_name : .*/class_name : PasswordAuthenticator/}" "$CASSANDRA_CONF"/cassandra.yaml
# End of for 5.X
sed -i "s/^authorizer: .*/authorizer: CassandraAuthorizer/g" "$CASSANDRA_CONF"/cassandra.yaml

sed -i "s/num_tokens: .*/num_tokens: 16/g" "$CASSANDRA_CONF"/cassandra.yaml
sed -i "s/auto_snapshot: .*/auto_snapshot: false/g" "$CASSANDRA_CONF"/cassandra.yaml

mkdir -p ~/.cassandra

cat <<EOF > ~/.cassandra/cqlshrc
[authentication]
username = cassandra
password = cassandra

EOF

if [ -f /etc/certificates/.keystore ]; then
#
# Setup CQL certificates
#
sed -i "/client_encryption_options:/{n;s/enabled: false/enabled: true/}" "$CASSANDRA_CONF"/cassandra.yaml

sed -i "s;keystore: .*;keystore: /etc/certificates/.keystore;g" "$CASSANDRA_CONF"/cassandra.yaml
sed -i "s/keystore_password: .*/keystore_password: ecctest/g" "$CASSANDRA_CONF"/cassandra.yaml

sed -ri "s;(# )?truststore: .*;truststore: /etc/certificates/.truststore;g" "$CASSANDRA_CONF"/cassandra.yaml
sed -ri "s/(# )?truststore_password: .*/truststore_password: ecctest/g" "$CASSANDRA_CONF"/cassandra.yaml

sed -ri "s/(# )?require_client_auth: false/require_client_auth: true/g" "$CASSANDRA_CONF"/cassandra.yaml
sed -ri "s/(# )?protocol: TLS/protocol: TLSv1.2/g" "$CASSANDRA_CONF"/cassandra.yaml

cat <<EOF >> ~/.cassandra/cqlshrc
[connection]
hostname = localhost
port = 9042
ssl = true

[ssl]
certfile = /etc/certificates/ca.crt
validate = true
userkey = /etc/certificates/key.pem
usercert = /etc/certificates/cert.crt
version = TLSv1_2
EOF

#
# Setup JMX certificates
#

# Comment rmi port to choose randomly
sed -ri "s/(.*jmxremote.rmi.port.*)/#\1/g" "$CASSANDRA_CONF"/cassandra-env.sh

# Enable secure transport
sed -ri "s/#(.*jmxremote.ssl=true)/\1/g" "$CASSANDRA_CONF"/cassandra-env.sh
sed -ri "s/#(.*jmxremote.ssl.need_client_auth=true)/\1/g" "$CASSANDRA_CONF"/cassandra-env.sh

# Set protocol
sed -ri 's/#(.*jmxremote.ssl.enabled.protocols)=.*/\1=TLSv1.2"/g' "$CASSANDRA_CONF"/cassandra-env.sh

# Set keystore/truststore properties
sed -ri 's;#(.*keyStore)=.*;\1=/etc/certificates/.keystore";g' "$CASSANDRA_CONF"/cassandra-env.sh
sed -ri 's;#(.*trustStore)=.*;\1=/etc/certificates/.truststore";g' "$CASSANDRA_CONF"/cassandra-env.sh
sed -ri 's/#(.*keyStorePassword)=.*/\1=ecctest"/g' "$CASSANDRA_CONF"/cassandra-env.sh
sed -ri 's/#(.*trustStorePassword)=.*/\1=ecctest"/g' "$CASSANDRA_CONF"/cassandra-env.sh

fi

docker-entrypoint.sh
18 changes: 18 additions & 0 deletions cassandra-test-image/src/main/docker/setup_db.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#!/bin/bash
#
# Copyright 2024 Telefonaktiebolaget LM Ericsson
#
# 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
# http://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.
#

cqlsh -u cassandra -p cassandra -f /etc/cassandra/create_keyspaces.cql
cqlsh -u cassandra -p cassandra -f /etc/cassandra/users.cql
5 changes: 5 additions & 0 deletions cassandra-test-image/src/main/docker/users.cql
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
CREATE ROLE IF NOT EXISTS eccuser WITH PASSWORD = 'eccpassword' AND LOGIN = true;

GRANT SELECT ON KEYSPACE ecchronos TO eccuser;
GRANT MODIFY ON KEYSPACE ecchronos TO eccuser;
GRANT SELECT ON system_distributed.repair_history TO eccuser;
Loading