diff --git a/.circleci/config.yml b/.circleci/config.yml
index 6f06b29..2f502ae 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -2,7 +2,7 @@ version: 2.1
jobs:
build:
machine:
- image: ubuntu-1604:202104-01
+ image: ubuntu-2004:202104-01
working_directory: ~/cassandra-everywhere-strategy
@@ -22,6 +22,7 @@ jobs:
- ~/.m2
key: m2-{{ checksum "pom.xml" }}
+ - run: echo "2" | sudo update-alternatives --config java
- run: ./conf/setup.sh && mvn clean install && (cd test && ./run-tests.sh)
- persist_to_workspace:
@@ -31,6 +32,7 @@ jobs:
- "cassandra-3.0/target/everywhere-strategy-cassandra*.jar"
- "cassandra-3.11/target/everywhere-strategy-cassandra*.jar"
- "cassandra-4.0/target/everywhere-strategy-cassandra*.jar"
+ - "cassandra-4.1/target/everywhere-strategy-cassandra*.jar"
build-2-2:
docker:
@@ -160,6 +162,38 @@ jobs:
- "everywhere-strategy-cassandra-4.0*.deb"
- "everywhere-strategy-cassandra-4.0*.rpm"
+ build-4-1:
+ docker:
+ - image: circleci/openjdk:8-jdk-stretch
+
+ working_directory: ~/cassandra-everywhere-strategy
+
+ environment:
+ MAVEN_OPTS: -Xmx3200m
+
+ steps:
+
+ - checkout
+
+ - restore_cache:
+ keys:
+ - m2-{{ checksum "pom.xml" }}
+ - m2-
+
+ - run: mvn clean install -DoutputDirectory=/tmp/artifacts
+
+ - save_cache:
+ paths:
+ - ~/.m2
+ key: m2-{{ checksum "pom.xml" }}
+
+ - persist_to_workspace:
+ root: /tmp/artifacts
+ paths:
+ - "everywhere-strategy-cassandra-4.1*.jar"
+ - "everywhere-strategy-cassandra-4.1*.deb"
+ - "everywhere-strategy-cassandra-4.1*.rpm"
+
publish-github-release-2-2:
docker:
- image: circleci/golang
@@ -213,6 +247,19 @@ jobs:
go get github.com/tcnksm/ghr
ghr -t ${GITHUB_TOKEN} -u ${CIRCLE_PROJECT_USERNAME} -r ${CIRCLE_PROJECT_REPONAME} -c ${CIRCLE_SHA1} -delete ${CIRCLE_TAG} ./artifacts/
+ publish-github-release-4-1:
+ docker:
+ - image: circleci/golang
+ steps:
+ - attach_workspace:
+ at: ./artifacts
+ - run:
+ name: "Publish 4.1 Release on GitHub"
+ command: |
+ set -xue
+ go get github.com/tcnksm/ghr
+ ghr -t ${GITHUB_TOKEN} -u ${CIRCLE_PROJECT_USERNAME} -r ${CIRCLE_PROJECT_REPONAME} -c ${CIRCLE_SHA1} -delete ${CIRCLE_TAG} ./artifacts/
+
workflows:
version: 2
main:
@@ -245,6 +292,12 @@ workflows:
ignore: /.*/
tags:
only: /^v4.0.\d+-\d+\.\d+\.\d+$/
+ - build-4-1:
+ filters:
+ branches:
+ ignore: /.*/
+ tags:
+ only: /^v4.1.\d+-\d+\.\d+\.\d+$/
- publish-github-release-2-2:
requires:
- build-2-2
@@ -277,3 +330,11 @@ workflows:
ignore: /.*/
tags:
only: /^v4.0.\d+-\d+\.\d+\.\d+$/
+ - publish-github-release-4-1:
+ requires:
+ - build-4-1
+ filters:
+ branches:
+ ignore: /.*/
+ tags:
+ only: /^v4.1.\d+-\d+\.\d+\.\d+$/
\ No newline at end of file
diff --git a/README.md b/README.md
index 2e0bebb..21f4b2e 100644
--- a/README.md
+++ b/README.md
@@ -149,11 +149,11 @@ So we resort to reflection to fix this. Yuck! But, it works…
| Cassandra Version | Status |
| --- | --- |
-| 3.11.x | Supported |
| 4.x | Supported |
-| 3.0.x | _Supported_ |
-| 2.2.x | _Supported_ |
-| 2.1.x | _Supported_ |
+| 3.11.x | Supported |
+| 3.0.x | Supported |
+| 2.2.x | Supported |
+| 2.1.x | Supported |
| 2.0.x | Supported |
For 2.1.x and 2.0.x versions, you can use version 2.2.x, it is compatible.
@@ -164,4 +164,4 @@ This project is licensed under the Apache License, version 2.0. See [LICENSE](LI
## Instaclustr Support
-Please see our [Open Source Project Status](https://www.instaclustr.com/support/documentation/announcements/instaclustr-open-source-project-status/) page for details on Instaclustr's support status of this project.
\ No newline at end of file
+Please see our [Open Source Project Status](https://www.instaclustr.com/support/documentation/announcements/instaclustr-open-source-project-status/) page for details on Instaclustr's support status of this project.
diff --git a/cassandra-2.2/pom.xml b/cassandra-2.2/pom.xml
index 12a0618..75ad535 100644
--- a/cassandra-2.2/pom.xml
+++ b/cassandra-2.2/pom.xml
@@ -20,7 +20,7 @@
org.apache.cassandra
cassandra-all
- 2.2.18
+ 2.2.19
provided
diff --git a/cassandra-3.0/pom.xml b/cassandra-3.0/pom.xml
index b63a885..397f287 100644
--- a/cassandra-3.0/pom.xml
+++ b/cassandra-3.0/pom.xml
@@ -20,7 +20,7 @@
org.apache.cassandra
cassandra-all
- 3.0.24
+ 3.0.26
provided
diff --git a/cassandra-3.11/pom.xml b/cassandra-3.11/pom.xml
index a33c7ed..e67a365 100644
--- a/cassandra-3.11/pom.xml
+++ b/cassandra-3.11/pom.xml
@@ -20,7 +20,7 @@
org.apache.cassandra
cassandra-all
- 3.11.8
+ 3.11.14
provided
diff --git a/cassandra-4.1/pom.xml b/cassandra-4.1/pom.xml
new file mode 100644
index 0000000..35f5eaf
--- /dev/null
+++ b/cassandra-4.1/pom.xml
@@ -0,0 +1,69 @@
+
+
+
+ 4.0.0
+
+
+ com.instaclustr
+ everywhere-strategy-parent
+ 1.0.0
+ ../pom.xml
+
+
+ everywhere-strategy-cassandra-4.1
+ 1.0.0
+
+ everywhere-strategy-cassandra-4.1
+ An EverywhereStrategy implementation for Apache Cassandra 4.1
+
+
+
+ org.apache.cassandra
+ cassandra-all
+ 4.1.0
+ provided
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-release-plugin
+
+
+ v4.1-@{project.version}
+
+
+
+
+ jdeb
+ org.vafer
+
+
+
+ de.dentrassi.maven
+ rpm
+
+
+ package
+
+ rpm
+
+
+
+
+ cassandra
+ 4.1
+
+
+
+
+
+
+
+
+
+
diff --git a/cassandra-4.1/src/deb/control/control b/cassandra-4.1/src/deb/control/control
new file mode 100644
index 0000000..b5cfd44
--- /dev/null
+++ b/cassandra-4.1/src/deb/control/control
@@ -0,0 +1,7 @@
+Package: [[name]]
+Version: [[version]]
+Section: misc
+Priority: optional
+Architecture: all
+Depends: cassandra (>= 4.1)
+Maintainer: [[maintainer]]
diff --git a/cassandra-4.1/src/main/java/org/apache/cassandra/locator/EverywhereStrategy.java b/cassandra-4.1/src/main/java/org/apache/cassandra/locator/EverywhereStrategy.java
new file mode 100644
index 0000000..7abb0ac
--- /dev/null
+++ b/cassandra-4.1/src/main/java/org/apache/cassandra/locator/EverywhereStrategy.java
@@ -0,0 +1,87 @@
+package org.apache.cassandra.locator;
+
+import java.lang.reflect.Field;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+import com.google.common.collect.ImmutableMap;
+import org.apache.cassandra.dht.Token;
+import org.apache.cassandra.exceptions.ConfigurationException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/*
+ The strategy should be DC-aware, but DC-awareness is hardcoded to NTS throughout Cassandra.
+ (see for example org.apache.cassandra.db.ConsistencyLevel)
+ Hence why this implementation subclasses NTS.
+ */
+public class EverywhereStrategy extends NetworkTopologyStrategy {
+
+ private static final Logger logger = LoggerFactory.getLogger(EverywhereStrategy.class);
+
+ protected final Map datacenters;
+
+ public EverywhereStrategy(final String keyspaceName,
+ final TokenMetadata tokenMetadata,
+ final IEndpointSnitch snitch,
+ final Map configOptions) throws NoSuchFieldException, IllegalAccessException {
+ super(keyspaceName, tokenMetadata, snitch, null);
+
+ if (configOptions != null && configOptions.size() != 0) {
+ throw new ConfigurationException("EverywhereStrategy doesn't accept any options.");
+ }
+
+ // yuck. but then again, why is this field private?
+ // also, sucks that its final *and* and an unmodifiable collection.
+ // lets fix that...
+ final Field field = NetworkTopologyStrategy.class.getDeclaredField("datacenters");
+ field.setAccessible(true);
+
+ this.datacenters = new HashMap<>();
+
+ field.set(this, this.datacenters);
+ }
+
+ // this gets called whenever the ring topology changes.
+ // redetermine the RF for each DC.
+ @Override
+ public EndpointsForRange calculateNaturalReplicas(Token searchToken, TokenMetadata tokenMetadata) {
+ final Set endpoints = tokenMetadata.getAllEndpoints();
+
+ final Map previousDataCenters = ImmutableMap.copyOf(this.datacenters);
+
+ this.datacenters.clear();
+
+ for (final InetAddressAndPort endpoint : endpoints) {
+ if (!tokenMetadata.isMember(endpoint))
+ continue;
+
+ final String datacenter = this.snitch.getDatacenter(endpoint);
+ this.datacenters.merge(datacenter, ReplicationFactor.fromString("1"), (rf1, rf2) -> ReplicationFactor.fullOnly(rf1.fullReplicas + rf2.fullReplicas));
+ }
+
+ if (!previousDataCenters.equals(this.datacenters)) {
+ logger.info("Data center replication factors for keyspace '{}' = {}", this.keyspaceName, this.datacenters);
+ }
+
+ return super.calculateNaturalReplicas(searchToken, tokenMetadata);
+ }
+
+ @Override
+ public Collection recognizedOptions() {
+ return Collections.emptyList();
+ }
+
+ @Override
+ public void validateOptions() throws ConfigurationException {
+ super.validateOptions();
+ }
+
+ @Override
+ protected void validateExpectedOptions() throws ConfigurationException {
+ // do nothing, we are not excepting any options and method in super would throw as we have not provided any
+ }
+}
diff --git a/cassandra-4/pom.xml b/cassandra-4/pom.xml
index 96f97f8..122c53f 100644
--- a/cassandra-4/pom.xml
+++ b/cassandra-4/pom.xml
@@ -22,7 +22,7 @@
org.apache.cassandra
cassandra-all
- 4.0.0
+ 4.0.7
provided
diff --git a/conf/setup.sh b/conf/setup.sh
index b8db39a..b0775dd 100755
--- a/conf/setup.sh
+++ b/conf/setup.sh
@@ -3,4 +3,4 @@
sudo apt-get update
sudo apt-get --allow-downgrades --allow-remove-essential --allow-change-held-packages install libev4 libev-dev
-pip3.9 install ccm && wget https://github.com/zegelin/ccm-extensions/archive/refs/heads/master.zip && unzip master.zip && cd ccm-extensions-master && python3.9 setup.py install
\ No newline at end of file
+pip3.9 install ccm && wget https://github.com/smiklosovic/ccm-extensions/archive/refs/heads/master.zip && unzip master.zip && cd ccm-extensions-master && python3.9 setup.py install
diff --git a/pom.xml b/pom.xml
index 78b8f1c..3e2ee37 100644
--- a/pom.xml
+++ b/pom.xml
@@ -13,6 +13,7 @@
cassandra-3.0
cassandra-3.11
cassandra-4
+ cassandra-4.1
everywhere-strategy-parent
diff --git a/test/compare_dumps.py b/test/compare_dumps.py
index 8ec4449..0140e20 100644
--- a/test/compare_dumps.py
+++ b/test/compare_dumps.py
@@ -87,8 +87,13 @@ def flush_dump_compare(nodes: Iterable[Node], dump_dir: Path):
dump_dir.mkdir(parents=True,exist_ok=True)
path = (dump_dir / f'{node.ip_addr}-{i}.json')
logger.info(f'Writing {node.ip_addr} dump to {path}')
- with path.open('wb') as f:
- f.write(result.stdout)
+ print(result.stdout)
+ try:
+ with path.open('w') as f:
+ f.write(result.stdout)
+ except:
+ with path.open('wb') as f:
+ f.write(result.stdout)
logger.info('Comparing dumps')
compare_sstable_dumps(dump_dir)
diff --git a/test/run-tests.sh b/test/run-tests.sh
index e278de5..290215c 100755
--- a/test/run-tests.sh
+++ b/test/run-tests.sh
@@ -2,6 +2,7 @@
# ssltabledump not available on 2.2.x
#python3 ccm-test.py -j ../cassandra-2.2/target/everywhere-strategy-cassandra-2.2-1.0.0.jar 2.2.18
-python3 ccm-test.py -j ../cassandra-3.0/target/everywhere-strategy-cassandra-3.0-1.0.0.jar 3.0.24
-python3 ccm-test.py -j ../cassandra-3.11/target/everywhere-strategy-cassandra-3.11-1.0.0.jar 3.11.10
-python3 ccm-test.py -j ../cassandra-4/target/everywhere-strategy-cassandra-4.0-1.0.0.jar 4.0.0
\ No newline at end of file
+python3 ccm-test.py -j ../cassandra-3.0/target/everywhere-strategy-cassandra-3.0-1.0.0.jar 3.0.26
+python3 ccm-test.py -j ../cassandra-3.11/target/everywhere-strategy-cassandra-3.11-1.0.0.jar 3.11.14
+python3 ccm-test.py -j ../cassandra-4/target/everywhere-strategy-cassandra-4.0-1.0.0.jar 4.0.7
+python3 ccm-test.py -j ../cassandra-4.1/target/everywhere-strategy-cassandra-4.1-1.0.0.jar 4.1.0
\ No newline at end of file