This is an automated email from the ASF dual-hosted git repository.

smiklosovic pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/cassandra.git

commit ea5291c2ca2566c6d8ccbb37dab3280bf5f5c5bc
Merge: cf5d5fec6e a57f0396fa
Author: Stefan Miklosovic <[email protected]>
AuthorDate: Wed Jun 28 16:34:56 2023 +0200

    Merge branch 'cassandra-4.1' into trunk

 .build/cassandra-build-deps-template.xml           |   4 +
 .build/parent-pom-template.xml                     |   6 +
 CHANGES.txt                                        |   1 +
 NEWS.txt                                           |   5 +
 conf/cassandra-rackdc.properties                   |   6 +
 .../AbstractCloudMetadataServiceConnector.java     |  99 ++++++++++
 .../locator/Ec2MetadataServiceConnector.java       | 215 +++++++++++++++++++++
 .../cassandra/locator/Ec2MultiRegionSnitch.java    |  26 ++-
 .../org/apache/cassandra/locator/Ec2Snitch.java    |  66 +++----
 .../apache/cassandra/locator/SnitchProperties.java |   8 +
 .../apache/cassandra/locator/Ec2ConnectorTest.java | 106 ++++++++++
 .../{EC2SnitchTest.java => Ec2SnitchTest.java}     | 155 +++++++++------
 .../locator/Ec2V2ConnectorMockingTest.java         | 169 ++++++++++++++++
 13 files changed, 761 insertions(+), 105 deletions(-)

diff --cc .build/cassandra-build-deps-template.xml
index cbf2f8c59d,0000000000..b5db6846da
mode 100644,000000..100644
--- a/.build/cassandra-build-deps-template.xml
+++ b/.build/cassandra-build-deps-template.xml
@@@ -1,127 -1,0 +1,131 @@@
 +<?xml version="1.0" encoding="UTF-8"?>
 +<!--
 +  Licensed to the Apache Software Foundation (ASF) under one or more
 +  contributor license agreements.  See the NOTICE file distributed with
 +  this work for additional information regarding copyright ownership.
 +  The ASF licenses this file to You 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 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/xsd/maven-4.0.0.xsd"; 
xmlns="http://maven.apache.org/POM/4.0.0";
 +    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";>
 +  <modelVersion>4.0.0</modelVersion>
 +  <parent>
 +    <artifactId>cassandra-parent</artifactId>
 +    <groupId>org.apache.cassandra</groupId>
 +    <version>@version@</version>
 +    <relativePath>@[email protected]</relativePath>
 +  </parent>
 +  <groupId>org.apache.cassandra</groupId>
 +  <artifactId>cassandra-build-deps</artifactId>
 +  <version>@version@</version>
 +  <dependencies>
 +    <dependency>
 +      <groupId>junit</groupId>
 +      <artifactId>junit</artifactId>
 +    </dependency>
 +    <dependency>
 +      <groupId>commons-io</groupId>
 +      <artifactId>commons-io</artifactId>
 +    </dependency>
 +    <dependency>
 +      <groupId>org.mockito</groupId>
 +      <artifactId>mockito-core</artifactId>
 +    </dependency>
 +    <dependency>
 +      <groupId>org.mockito</groupId>
 +      <artifactId>mockito-inline</artifactId>
 +    </dependency>
 +    <dependency>
 +      <groupId>org.ow2.asm</groupId>
 +      <artifactId>asm</artifactId>
 +    </dependency>
 +    <dependency>
 +      <groupId>org.ow2.asm</groupId>
 +      <artifactId>asm-tree</artifactId>
 +    </dependency>
 +    <dependency>
 +      <groupId>org.ow2.asm</groupId>
 +      <artifactId>asm-commons</artifactId>
 +    </dependency>
 +    <dependency>
 +      <groupId>org.ow2.asm</groupId>
 +      <artifactId>asm-util</artifactId>
 +    </dependency>
 +    <dependency>
 +      <groupId>com.google.jimfs</groupId>
 +      <artifactId>jimfs</artifactId>
 +    </dependency>
 +    <dependency>
 +      <groupId>org.quicktheories</groupId>
 +      <artifactId>quicktheories</artifactId>
 +    </dependency>
 +    <dependency>
 +      <groupId>org.reflections</groupId>
 +      <artifactId>reflections</artifactId>
 +    </dependency>
 +    <dependency>
 +      <groupId>com.google.code.java-allocation-instrumenter</groupId>
 +      <artifactId>java-allocation-instrumenter</artifactId>
 +    </dependency>
 +    <dependency>
 +      <groupId>org.apache.cassandra</groupId>
 +      <artifactId>dtest-api</artifactId>
 +    </dependency>
 +    <dependency>
 +      <groupId>org.openjdk.jmh</groupId>
 +      <artifactId>jmh-core</artifactId>
 +    </dependency>
 +    <dependency>
 +      <groupId>org.openjdk.jmh</groupId>
 +      <artifactId>jmh-generator-annprocess</artifactId>
 +    </dependency>
 +    <dependency>
 +      <groupId>net.ju-n.compile-command-annotations</groupId>
 +      <artifactId>compile-command-annotations</artifactId>
 +    </dependency>
 +    <dependency>
 +      <groupId>org.apache.ant</groupId>
 +      <artifactId>ant-junit</artifactId>
 +    </dependency>
 +    <dependency>
 +      <groupId>org.apache.cassandra</groupId>
 +      <artifactId>harry-core</artifactId>
 +    </dependency>
 +    <dependency>
 +      <groupId>org.junit</groupId>
 +      <artifactId>junit-bom</artifactId>
 +      <type>pom</type>
 +    </dependency>
 +    <dependency>
 +      <groupId>org.awaitility</groupId>
 +      <artifactId>awaitility</artifactId>
 +    </dependency>
 +    <dependency>
 +      <groupId>org.hamcrest</groupId>
 +      <artifactId>hamcrest</artifactId>
 +    </dependency>
 +    <dependency>
 +      <groupId>org.jacoco</groupId>
 +      <artifactId>org.jacoco.agent</artifactId>
 +    </dependency>
 +    <dependency>
 +      <groupId>org.jacoco</groupId>
 +      <artifactId>org.jacoco.ant</artifactId>
 +    </dependency>
 +    <dependency>
 +      <groupId>com.fasterxml.jackson.dataformat</groupId>
 +      <artifactId>jackson-dataformat-yaml</artifactId>
 +    </dependency>
++    <dependency>
++      <groupId>com.github.tomakehurst</groupId>
++      <artifactId>wiremock-jre8</artifactId>
++    </dependency>
 +  </dependencies>
 +</project>
diff --cc .build/parent-pom-template.xml
index 9203d4ad89,0000000000..a88764ee75
mode 100644,000000..100644
--- a/.build/parent-pom-template.xml
+++ b/.build/parent-pom-template.xml
@@@ -1,1052 -1,0 +1,1058 @@@
 +<?xml version="1.0" encoding="UTF-8"?>
 +<!--
 +  Licensed to the Apache Software Foundation (ASF) under one or more
 +  contributor license agreements.  See the NOTICE file distributed with
 +  this work for additional information regarding copyright ownership.
 +  The ASF licenses this file to You 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 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/xsd/maven-4.0.0.xsd"; 
xmlns="http://maven.apache.org/POM/4.0.0";
 +    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";>
 +  <modelVersion>4.0.0</modelVersion>
 +  <parent>
 +    <artifactId>apache</artifactId>
 +    <groupId>org.apache</groupId>
 +    <version>22</version>
 +  </parent>
 +  <groupId>org.apache.cassandra</groupId>
 +  <artifactId>cassandra-parent</artifactId>
 +  <version>@version@</version>
 +  <packaging>pom</packaging>
 +  <name>Apache Cassandra</name>
 +  <description>The Apache Cassandra Project develops a highly scalable 
second-generation distributed database, bringing together Dynamo's fully 
distributed design and Bigtable's ColumnFamily-based data model.</description>
 +  <url>https://cassandra.apache.org</url>
 +  <inceptionYear>2009</inceptionYear>
 +  <licenses>
 +    <license>
 +      <name>The Apache Software License, Version 2.0</name>
 +      <url>https://www.apache.org/licenses/LICENSE-2.0.txt</url>
 +    </license>
 +  </licenses>
 +  <properties>
 +    <bytebuddy.version>1.12.13</bytebuddy.version>
 +    <byteman.version>4.0.20</byteman.version>
 +    <ohc.version>0.5.1</ohc.version>
 +
 +    <!-- These are referenced in build.xml, so need to be propagated from 
there -->
 +    <asm.version>@asm.version@</asm.version>
 +    <jamm.version>@jamm.version@</jamm.version>
 +    
<allocation-instrumenter.version>@allocation-instrumenter.version@</allocation-instrumenter.version>
 +    <ecj.version>@ecj.version@</ecj.version>
 +    <jacoco.version>@jacoco.version@</jacoco.version>
 +    <jflex.version>@jflex.version@</jflex.version>
 +  </properties>
 +  <developers>
 +    <developer>
 +      <id>adelapena</id>
 +      <name>Andres de la Peña</name>
 +    </developer>
 +    <developer>
 +      <id>alakshman</id>
 +      <name>Avinash Lakshman</name>
 +    </developer>
 +    <developer>
 +      <id>aleksey</id>
 +      <name>Aleksey Yeschenko</name>
 +    </developer>
 +    <developer>
 +      <id>amorton</id>
 +      <name>Aaron Morton</name>
 +    </developer>
 +    <developer>
 +      <id>aweisberg</id>
 +      <name>Ariel Weisberg</name>
 +    </developer>
 +    <developer>
 +      <id>bdeggleston</id>
 +      <name>Blake Eggleston</name>
 +    </developer>
 +    <developer>
 +      <id>benedict</id>
 +      <name>Benedict Elliott Smith</name>
 +    </developer>
 +    <developer>
 +      <id>benjamin</id>
 +      <name>Benjamin Lerer</name>
 +    </developer>
 +    <developer>
 +      <id>blambov</id>
 +      <name>Branimir Lambov</name>
 +    </developer>
 +    <developer>
 +      <id>brandonwilliams</id>
 +      <name>Brandon Williams</name>
 +    </developer>
 +    <developer>
 +      <id>carl</id>
 +      <name>Carl Yeksigian</name>
 +    </developer>
 +    <developer>
 +      <id>dbrosius</id>
 +      <name>David Brosiusd</name>
 +    </developer>
 +    <developer>
 +      <id>dikang</id>
 +      <name>Dikang Gu</name>
 +    </developer>
 +    <developer>
 +      <id>eevans</id>
 +      <name>Eric Evans</name>
 +    </developer>
 +    <developer>
 +      <id>edimitrova</id>
 +      <name>Ekaterina Dimitrova</name>
 +    </developer>
 +    <developer>
 +      <id>gdusbabek</id>
 +      <name>Gary Dusbabek</name>
 +    </developer>
 +    <developer>
 +      <id>goffinet</id>
 +      <name>Chris Goffinet</name>
 +    </developer>
 +    <developer>
 +      <id>ifesdjeen</id>
 +      <name>Alex Petrov</name>
 +    </developer>
 +    <developer>
 +      <id>jaakko</id>
 +      <name>Laine Jaakko Olavi</name>
 +    </developer>
 +    <developer>
 +      <id>jake</id>
 +      <name>T Jake Luciani</name>
 +    </developer>
 +    <developer>
 +      <id>jasonbrown</id>
 +      <name>Jason Brown</name>
 +    </developer>
 +    <developer>
 +      <id>jbellis</id>
 +      <name>Jonathan Ellis</name>
 +    </developer>
 +    <developer>
 +      <id>jfarrell</id>
 +      <name>Jake Farrell</name>
 +    </developer>
 +    <developer>
 +      <id>jjirsa</id>
 +      <name>Jeff Jirsa</name>
 +    </developer>
 +    <developer>
 +      <id>jkni</id>
 +      <name>Joel Knighton</name>
 +    </developer>
 +    <developer>
 +      <id>jmckenzie</id>
 +      <name>Josh McKenzie</name>
 +    </developer>
 +    <developer>
 +      <id>johan</id>
 +      <name>Johan Oskarsson</name>
 +    </developer>
 +    <developer>
 +      <id>junrao</id>
 +      <name>Jun Rao</name>
 +    </developer>
 +    <developer>
 +      <id>jzhuang</id>
 +      <name>Jay Zhuang</name>
 +    </developer>
 +    <developer>
 +      <id>kohlisankalp</id>
 +      <name>Sankalp Kohli</name>
 +    </developer>
 +    <developer>
 +      <id>marcuse</id>
 +      <name>Marcus Eriksson</name>
 +    </developer>
 +    <developer>
 +      <id>mck</id>
 +      <name>Michael Semb Wever</name>
 +    </developer>
 +    <developer>
 +      <id>mishail</id>
 +      <name>Mikhail Stepura</name>
 +    </developer>
 +    <developer>
 +      <id>mshuler</id>
 +      <name>Michael Shuler</name>
 +    </developer>
 +    <developer>
 +      <id>paulo</id>
 +      <name>Paulo Motta</name>
 +    </developer>
 +    <developer>
 +      <id>pmalik</id>
 +      <name>Prashant Malik</name>
 +    </developer>
 +    <developer>
 +      <id>rstupp</id>
 +      <name>Robert Stupp</name>
 +    </developer>
 +    <developer>
 +      <id>scode</id>
 +      <name>Peter Schuller</name>
 +    </developer>
 +    <developer>
 +      <id>beobal</id>
 +      <name>Sam Tunnicliffe</name>
 +    </developer>
 +    <developer>
 +      <id>slebresne</id>
 +      <name>Sylvain Lebresne</name>
 +    </developer>
 +    <developer>
 +      <id>stefania</id>
 +      <name>Stefania Alborghetti</name>
 +    </developer>
 +    <developer>
 +      <id>tylerhobbs</id>
 +      <name>Tyler Hobbs</name>
 +    </developer>
 +    <developer>
 +      <id>vijay</id>
 +      <name>Vijay Parthasarathy</name>
 +    </developer>
 +    <developer>
 +      <id>xedin</id>
 +      <name>Pavel Yaskevich</name>
 +    </developer>
 +    <developer>
 +      <id>yukim</id>
 +      <name>Yuki Morishita</name>
 +    </developer>
 +    <developer>
 +      <id>zznate</id>
 +      <name>Nate McCall</name>
 +    </developer>
 +  </developers>
 +  <scm>
 +    
<connection>scm:https://gitbox.apache.org/repos/asf/cassandra.git</connection>
 +    
<developerConnection>scm:https://gitbox.apache.org/repos/asf/cassandra.git</developerConnection>
 +    <url>https://gitbox.apache.org/repos/asf?p=cassandra.git;a=tree</url>
 +  </scm>
 +  <dependencyManagement>
 +    <!--
 +    Dependency metadata is specified here (version, scope, exclusions, etc.), 
then referenced in child POMs by groupId and
 +    artifactId.
 +    -->
 +    <dependencies>
 +      <dependency>
 +        <groupId>org.xerial.snappy</groupId>
 +        <artifactId>snappy-java</artifactId>
 +        <version>1.1.10.1</version>
 +      </dependency>
 +      <dependency>
 +        <groupId>org.lz4</groupId>
 +        <artifactId>lz4-java</artifactId>
 +        <version>1.8.0</version>
 +      </dependency>
 +      <dependency>
 +        <groupId>com.ning</groupId>
 +        <artifactId>compress-lzf</artifactId>
 +        <version>0.8.4</version>
 +        <scope>provided</scope>
 +      </dependency>
 +      <dependency>
 +        <groupId>com.github.luben</groupId>
 +        <artifactId>zstd-jni</artifactId>
 +        <version>1.5.5-1</version>
 +      </dependency>
 +      <dependency>
 +        <groupId>com.google.guava</groupId>
 +        <artifactId>guava</artifactId>
 +        <version>27.0-jre</version>
 +        <exclusions>
 +          <exclusion>
 +            <artifactId>jsr305</artifactId>
 +            <groupId>com.google.code.findbugs</groupId>
 +          </exclusion>
 +          <exclusion>
 +            <artifactId>animal-sniffer-annotations</artifactId>
 +            <groupId>org.codehaus.mojo</groupId>
 +          </exclusion>
 +          <exclusion>
 +            <artifactId>listenablefuture</artifactId>
 +            <groupId>com.google.guava</groupId>
 +          </exclusion>
 +          <exclusion>
 +            <artifactId>failureaccess</artifactId>
 +            <groupId>com.google.guava</groupId>
 +          </exclusion>
 +          <exclusion>
 +            <artifactId>checker-qual</artifactId>
 +            <groupId>org.checkerframework</groupId>
 +          </exclusion>
 +          <exclusion>
 +            <artifactId>error_prone_annotations</artifactId>
 +            <groupId>com.google.errorprone</groupId>
 +          </exclusion>
 +        </exclusions>
 +      </dependency>
 +      <dependency>
 +        <groupId>com.google.jimfs</groupId>
 +        <artifactId>jimfs</artifactId>
 +        <version>1.1</version>
 +      </dependency>
 +      <dependency>
 +        <groupId>org.hdrhistogram</groupId>
 +        <artifactId>HdrHistogram</artifactId>
 +        <version>2.1.9</version>
 +      </dependency>
 +      <dependency>
 +        <groupId>commons-cli</groupId>
 +        <artifactId>commons-cli</artifactId>
 +        <version>1.1</version>
 +      </dependency>
 +      <dependency>
 +        <groupId>commons-codec</groupId>
 +        <artifactId>commons-codec</artifactId>
 +        <version>1.9</version>
 +      </dependency>
 +      <dependency>
 +        <groupId>commons-io</groupId>
 +        <artifactId>commons-io</artifactId>
 +        <version>2.11.0</version>
 +      </dependency>
 +      <dependency>
 +        <groupId>org.apache.commons</groupId>
 +        <artifactId>commons-lang3</artifactId>
 +        <version>3.11</version>
 +      </dependency>
 +      <dependency>
 +        <groupId>org.apache.commons</groupId>
 +        <artifactId>commons-math3</artifactId>
 +        <version>3.2</version>
 +      </dependency>
 +      <dependency>
 +        <groupId>org.antlr</groupId>
 +        <artifactId>antlr</artifactId>
 +        <version>3.5.2</version>
 +        <scope>provided</scope>
 +        <exclusions>
 +          <exclusion>
 +            <artifactId>stringtemplate</artifactId>
 +            <groupId>org.antlr</groupId>
 +          </exclusion>
 +        </exclusions>
 +      </dependency>
 +      <dependency>
 +        <groupId>org.antlr</groupId>
 +        <artifactId>ST4</artifactId>
 +        <version>4.0.8</version>
 +      </dependency>
 +      <dependency>
 +        <groupId>org.antlr</groupId>
 +        <artifactId>antlr-runtime</artifactId>
 +        <version>3.5.2</version>
 +        <exclusions>
 +          <exclusion>
 +            <artifactId>stringtemplate</artifactId>
 +            <groupId>org.antlr</groupId>
 +          </exclusion>
 +        </exclusions>
 +      </dependency>
 +      <dependency>
 +        <groupId>org.slf4j</groupId>
 +        <artifactId>slf4j-api</artifactId>
 +        <version>1.7.25</version>
 +      </dependency>
 +      <dependency>
 +        <groupId>org.slf4j</groupId>
 +        <artifactId>log4j-over-slf4j</artifactId>
 +        <version>1.7.25</version>
 +      </dependency>
 +      <dependency>
 +        <groupId>org.slf4j</groupId>
 +        <artifactId>jcl-over-slf4j</artifactId>
 +        <version>1.7.25</version>
 +      </dependency>
 +      <dependency>
 +        <groupId>ch.qos.logback</groupId>
 +        <artifactId>logback-core</artifactId>
 +        <version>1.2.9</version>
 +      </dependency>
 +      <dependency>
 +        <groupId>ch.qos.logback</groupId>
 +        <artifactId>logback-classic</artifactId>
 +        <version>1.2.9</version>
 +      </dependency>
 +      <dependency>
 +        <groupId>com.fasterxml.jackson.core</groupId>
 +        <artifactId>jackson-core</artifactId>
 +        <version>2.13.2</version>
 +      </dependency>
 +      <dependency>
 +        <groupId>com.fasterxml.jackson.core</groupId>
 +        <artifactId>jackson-databind</artifactId>
 +        <version>2.13.2.2</version>
 +      </dependency>
 +      <dependency>
 +        <groupId>com.fasterxml.jackson.core</groupId>
 +        <artifactId>jackson-annotations</artifactId>
 +        <version>2.13.2</version>
 +      </dependency>
 +      <dependency>
 +        <groupId>com.fasterxml.jackson.datatype</groupId>
 +        <artifactId>jackson-datatype-jsr310</artifactId>
 +        <version>2.13.2</version>
 +      </dependency>
 +      <dependency>
 +        <groupId>com.fasterxml.jackson.dataformat</groupId>
 +        <artifactId>jackson-dataformat-yaml</artifactId>
 +        <version>2.13.2</version>
 +        <scope>test</scope>
 +        <exclusions>
 +          <exclusion>
 +            <artifactId>snakeyaml</artifactId>
 +            <groupId>org.yaml</groupId>
 +          </exclusion>
 +        </exclusions>
 +      </dependency>
 +      <dependency>
 +        <groupId>com.boundary</groupId>
 +        <artifactId>high-scale-lib</artifactId>
 +        <version>1.0.6</version>
 +      </dependency>
 +      <dependency>
 +        <groupId>com.github.jbellis</groupId>
 +        <artifactId>jamm</artifactId>
 +        <version>${jamm.version}</version>
 +      </dependency>
 +      <dependency>
 +        <groupId>org.yaml</groupId>
 +        <artifactId>snakeyaml</artifactId>
 +        <version>1.26</version>
 +      </dependency>
 +      <dependency>
 +        <groupId>junit</groupId>
 +        <artifactId>junit</artifactId>
 +        <version>4.12</version>
 +        <scope>test</scope>
 +        <exclusions>
 +          <exclusion>
 +            <artifactId>hamcrest-core</artifactId>
 +            <groupId>org.hamcrest</groupId>
 +          </exclusion>
 +        </exclusions>
 +      </dependency>
 +      <dependency>
 +        <groupId>org.mockito</groupId>
 +        <artifactId>mockito-core</artifactId>
 +        <version>4.7.0</version>
 +        <scope>test</scope>
 +      </dependency>
 +      <dependency>
 +        <groupId>org.mockito</groupId>
 +        <artifactId>mockito-inline</artifactId>
 +        <version>4.7.0</version>
 +        <scope>test</scope>
 +      </dependency>
 +      <dependency>
 +        <groupId>org.quicktheories</groupId>
 +        <artifactId>quicktheories</artifactId>
 +        <version>0.26</version>
 +        <scope>test</scope>
 +      </dependency>
 +      <dependency>
 +        <groupId>com.google.code.java-allocation-instrumenter</groupId>
 +        <artifactId>java-allocation-instrumenter</artifactId>
 +        <version>${allocation-instrumenter.version}</version>
 +        <scope>test</scope>
 +        <exclusions>
 +          <exclusion>
 +            <artifactId>guava</artifactId>
 +            <groupId>com.google.guava</groupId>
 +          </exclusion>
 +        </exclusions>
 +      </dependency>
 +      <dependency>
 +        <groupId>org.apache.cassandra</groupId>
 +        <artifactId>harry-core</artifactId>
 +        <version>0.0.1</version>
 +        <scope>test</scope>
 +      </dependency>
 +      <dependency>
 +        <groupId>org.reflections</groupId>
 +        <artifactId>reflections</artifactId>
 +        <version>0.10.2</version>
 +        <scope>test</scope>
 +      </dependency>
 +      <dependency>
 +        <groupId>org.apache.cassandra</groupId>
 +        <artifactId>dtest-api</artifactId>
 +        <version>0.0.15</version>
 +        <scope>test</scope>
 +      </dependency>
++      <dependency>
++        <groupId>com.github.tomakehurst</groupId>
++        <artifactId>wiremock-jre8</artifactId>
++        <version>2.35.0</version>
++        <scope>test</scope>
++      </dependency>
 +      <dependency>
 +        <groupId>net.java.dev.jna</groupId>
 +        <artifactId>jna</artifactId>
 +        <version>5.13.0</version>
 +      </dependency>
 +
 +      <dependency>
 +        <!-- transitive to posix to chronicle-core, declared explicit to use 
newer version -->
 +        <groupId>net.java.dev.jna</groupId>
 +        <artifactId>jna-platform</artifactId>
 +        <version>5.13.0</version>
 +      </dependency>
 +      <dependency>
 +        <!-- transitive to posix to chronicle-core, declared explicit to use 
newer version -->
 +        <groupId>com.github.jnr</groupId>
 +        <artifactId>jnr-ffi</artifactId>
 +        <version>2.2.13</version>
 +        <exclusions>
 +            <exclusion>
 +                <groupId>org.ow2.asm</groupId>
 +                <artifactId>asm-analysis</artifactId>
 +            </exclusion>
 +            <exclusion>
 +                <groupId>org.ow2.asm</groupId>
 +                <artifactId>asm-commons</artifactId>
 +            </exclusion>
 +            <exclusion>
 +                <groupId>org.ow2.asm</groupId>
 +                <artifactId>asm-tree</artifactId>
 +            </exclusion>
 +            <exclusion>
 +                <groupId>org.ow2.asm</groupId>
 +                <artifactId>asm-util</artifactId>
 +            </exclusion>
 +        </exclusions>
 +      </dependency>
 +      <dependency>
 +        <!-- transitive to jnr-ffi to posix to chronicle-core, declared 
explicit to use newer version -->
 +        <groupId>com.github.jnr</groupId>
 +        <artifactId>jffi</artifactId>
 +        <version>1.3.11</version>
 +      </dependency>
 +      <dependency>
 +        <!-- transitive to jnr-ffi to posix to chronicle-core, declared 
explicit to use newer version -->
 +        <groupId>com.github.jnr</groupId>
 +        <artifactId>jffi</artifactId>
 +        <classifier>native</classifier>
 +        <version>1.3.11</version>
 +      </dependency>
 +      <dependency>
 +        <!-- transitive to posix to chronicle-core, declared explicit to use 
newer version -->
 +        <groupId>com.github.jnr</groupId>
 +        <artifactId>jnr-constants</artifactId>
 +        <version>0.10.4</version>
 +      </dependency>
 +
 +      <dependency>
 +        <groupId>org.jacoco</groupId>
 +        <artifactId>org.jacoco.agent</artifactId>
 +        <version>${jacoco.version}</version>
 +        <scope>test</scope>
 +      </dependency>
 +      <dependency>
 +        <groupId>org.jacoco</groupId>
 +        <artifactId>org.jacoco.ant</artifactId>
 +        <version>${jacoco.version}</version>
 +        <scope>test</scope>
 +        <exclusions>
 +          <exclusion>
 +            <artifactId>asm</artifactId>
 +            <groupId>org.ow2.asm</groupId>
 +          </exclusion>
 +        </exclusions>
 +      </dependency>
 +      <dependency>
 +        <groupId>org.jboss.byteman</groupId>
 +        <artifactId>byteman-install</artifactId>
 +        <version>${byteman.version}</version>
 +        <scope>provided</scope>
 +      </dependency>
 +      <dependency>
 +        <groupId>org.jboss.byteman</groupId>
 +        <artifactId>byteman</artifactId>
 +        <version>${byteman.version}</version>
 +        <scope>provided</scope>
 +      </dependency>
 +      <dependency>
 +        <groupId>org.jboss.byteman</groupId>
 +        <artifactId>byteman-submit</artifactId>
 +        <version>${byteman.version}</version>
 +        <scope>provided</scope>
 +      </dependency>
 +      <dependency>
 +        <groupId>org.jboss.byteman</groupId>
 +        <artifactId>byteman-bmunit</artifactId>
 +        <version>${byteman.version}</version>
 +        <scope>provided</scope>
 +      </dependency>
 +      <dependency>
 +        <groupId>net.bytebuddy</groupId>
 +        <artifactId>byte-buddy</artifactId>
 +        <version>${bytebuddy.version}</version>
 +      </dependency>
 +      <dependency>
 +        <groupId>net.bytebuddy</groupId>
 +        <artifactId>byte-buddy-agent</artifactId>
 +        <version>${bytebuddy.version}</version>
 +      </dependency>
 +      <dependency>
 +        <groupId>org.openjdk.jmh</groupId>
 +        <artifactId>jmh-core</artifactId>
 +        <version>1.21</version>
 +        <scope>test</scope>
 +      </dependency>
 +      <dependency>
 +        <groupId>org.openjdk.jmh</groupId>
 +        <artifactId>jmh-generator-annprocess</artifactId>
 +        <version>1.21</version>
 +        <scope>test</scope>
 +      </dependency>
 +      <dependency>
 +        <groupId>org.apache.ant</groupId>
 +        <artifactId>ant-junit</artifactId>
 +        <version>1.10.12</version>
 +        <scope>test</scope>
 +      </dependency>
 +      <dependency>
 +        <groupId>org.apache.cassandra</groupId>
 +        <artifactId>cassandra-all</artifactId>
 +        <version>4.1-alpha2-SNAPSHOT</version>
 +      </dependency>
 +      <dependency>
 +        <groupId>io.dropwizard.metrics</groupId>
 +        <artifactId>metrics-core</artifactId>
 +        <version>3.1.5</version>
 +      </dependency>
 +      <dependency>
 +        <groupId>io.dropwizard.metrics</groupId>
 +        <artifactId>metrics-jvm</artifactId>
 +        <version>3.1.5</version>
 +      </dependency>
 +      <dependency>
 +        <groupId>io.dropwizard.metrics</groupId>
 +        <artifactId>metrics-logback</artifactId>
 +        <version>3.1.5</version>
 +      </dependency>
 +      <dependency>
 +        <groupId>com.addthis.metrics</groupId>
 +        <artifactId>reporter-config3</artifactId>
 +        <version>3.0.3</version>
 +        <exclusions>
 +          <exclusion>
 +            <artifactId>hibernate-validator</artifactId>
 +            <groupId>org.hibernate</groupId>
 +          </exclusion>
 +        </exclusions>
 +      </dependency>
 +      <dependency>
 +        <groupId>org.mindrot</groupId>
 +        <artifactId>jbcrypt</artifactId>
 +        <version>0.4</version>
 +      </dependency>
 +      <dependency>
 +        <groupId>io.airlift</groupId>
 +        <artifactId>airline</artifactId>
 +        <version>0.8</version>
 +        <exclusions>
 +          <exclusion>
 +            <artifactId>jsr305</artifactId>
 +            <groupId>com.google.code.findbugs</groupId>
 +          </exclusion>
 +        </exclusions>
 +      </dependency>
 +      <dependency>
 +        <groupId>io.netty</groupId>
 +        <artifactId>netty-bom</artifactId>
 +        <version>4.1.58.Final</version>
 +        <type>pom</type>
 +        <scope>provided</scope>
 +      </dependency>
 +      <dependency>
 +        <groupId>io.netty</groupId>
 +        <artifactId>netty-all</artifactId>
 +        <version>4.1.58.Final</version>
 +      </dependency>
 +      <dependency>
 +        <groupId>io.netty</groupId>
 +        <artifactId>netty-tcnative-boringssl-static</artifactId>
 +        <version>2.0.36.Final</version>
 +      </dependency>
 +
 +      <!-- chronicle-queue deps -->
 +      <dependency>
 +        <groupId>net.openhft</groupId>
 +        <artifactId>chronicle-queue</artifactId>
 +        <version>5.23.37</version>
 +        <exclusions>
 +          <exclusion>
 +            <artifactId>tools</artifactId>
 +            <groupId>com.sun</groupId>
 +          </exclusion>
 +          <exclusion>
 +              <!-- pulls in affinity-3.23ea1 which pulls in 
third-party-bom-3.22.4-SNAPSHOT -->
 +            <groupId>net.openhft</groupId>
 +            <artifactId>affinity</artifactId>
 +          </exclusion>
 +        </exclusions>
 +      </dependency>
 +      <dependency>
 +        <groupId>net.openhft</groupId>
 +        <artifactId>chronicle-core</artifactId>
 +        <version>2.23.36</version>
 +        <exclusions>
 +          <exclusion>
 +            <artifactId>chronicle-analytics</artifactId>
 +            <groupId>net.openhft</groupId>
 +          </exclusion>
 +          <exclusion>
 +            <artifactId>annotations</artifactId>
 +            <groupId>org.jetbrains</groupId>
 +          </exclusion>
 +        </exclusions>
 +      </dependency>
 +      <dependency>
 +        <groupId>net.openhft</groupId>
 +        <artifactId>chronicle-bytes</artifactId>
 +        <version>2.23.33</version>
 +        <exclusions>
 +          <exclusion>
 +            <artifactId>annotations</artifactId>
 +            <groupId>org.jetbrains</groupId>
 +          </exclusion>
 +        </exclusions>
 +      </dependency>
 +      <dependency>
 +        <groupId>net.openhft</groupId>
 +        <artifactId>chronicle-wire</artifactId>
 +        <version>2.23.39</version>
 +        <exclusions>
 +          <exclusion>
 +            <artifactId>compiler</artifactId>
 +            <groupId>net.openhft</groupId>
 +          </exclusion>
 +          <exclusion>
 +              <!-- pulls in affinity-3.23ea1 which pulls in 
third-party-bom-3.22.4-SNAPSHOT -->
 +            <groupId>net.openhft</groupId>
 +            <artifactId>affinity</artifactId>
 +          </exclusion>
 +        </exclusions>
 +      </dependency>
 +      <dependency>
 +        <groupId>net.openhft</groupId>
 +        <artifactId>chronicle-threads</artifactId>
 +        <version>2.23.25</version>
 +        <exclusions>
 +          <exclusion>
 +              <!-- pulls in affinity-3.23ea1 which pulls in 
third-party-bom-3.22.4-SNAPSHOT -->
 +            <groupId>net.openhft</groupId>
 +            <artifactId>affinity</artifactId>
 +          </exclusion>
 +        </exclusions>
 +      </dependency>
 +      <dependency>
 +        <!-- transitive to chronicle-queue, declared explicit to use newer 
version -->
 +        <groupId>net.openhft</groupId>
 +        <artifactId>affinity</artifactId>
 +        <version>3.23.3</version>
 +      </dependency>
 +      <dependency>
 +        <!-- transitive to chronicle-queue, declared explicit to use newer 
version -->
 +        <groupId>net.openhft</groupId>
 +        <artifactId>posix</artifactId>
 +        <version>2.24ea4</version>
 +      </dependency>
 +      <!-- end of chronicle-queue -->
 +
 +      <dependency>
 +        <groupId>com.google.code.findbugs</groupId>
 +        <artifactId>jsr305</artifactId>
 +        <version>2.0.2</version>
 +      </dependency>
 +      <dependency>
 +        <groupId>com.clearspring.analytics</groupId>
 +        <artifactId>stream</artifactId>
 +        <version>2.5.2</version>
 +        <exclusions>
 +          <exclusion>
 +            <artifactId>fastutil</artifactId>
 +            <groupId>it.unimi.dsi</groupId>
 +          </exclusion>
 +        </exclusions>
 +      </dependency>
 +      <dependency>
 +        <groupId>com.datastax.cassandra</groupId>
 +        <artifactId>cassandra-driver-core</artifactId>
 +        <version>3.11.0</version>
 +        <classifier>shaded</classifier>
 +        <exclusions>
 +          <exclusion>
 +            <artifactId>netty-buffer</artifactId>
 +            <groupId>io.netty</groupId>
 +          </exclusion>
 +          <exclusion>
 +            <artifactId>netty-codec</artifactId>
 +            <groupId>io.netty</groupId>
 +          </exclusion>
 +          <exclusion>
 +            <artifactId>netty-handler</artifactId>
 +            <groupId>io.netty</groupId>
 +          </exclusion>
 +          <exclusion>
 +            <artifactId>netty-transport</artifactId>
 +            <groupId>io.netty</groupId>
 +          </exclusion>
 +          <exclusion>
 +            <artifactId>slf4j-api</artifactId>
 +            <groupId>org.slf4j</groupId>
 +          </exclusion>
 +          <exclusion>
 +            <artifactId>jnr-ffi</artifactId>
 +            <groupId>com.github.jnr</groupId>
 +          </exclusion>
 +          <exclusion>
 +            <artifactId>jnr-posix</artifactId>
 +            <groupId>com.github.jnr</groupId>
 +          </exclusion>
 +        </exclusions>
 +      </dependency>
 +      <dependency>
 +        <groupId>org.eclipse.jdt.core.compiler</groupId>
 +        <artifactId>ecj</artifactId>
 +        <version>${ecj.version}</version>
 +      </dependency>
 +      <dependency>
 +        <groupId>org.caffinitas.ohc</groupId>
 +        <artifactId>ohc-core</artifactId>
 +        <version>${ohc.version}</version>
 +        <exclusions>
 +          <exclusion>
 +            <artifactId>slf4j-api</artifactId>
 +            <groupId>org.slf4j</groupId>
 +          </exclusion>
 +        </exclusions>
 +      </dependency>
 +      <dependency>
 +        <groupId>org.caffinitas.ohc</groupId>
 +        <artifactId>ohc-core-j8</artifactId>
 +        <version>${ohc.version}</version>
 +      </dependency>
 +      <dependency>
 +        <groupId>net.ju-n.compile-command-annotations</groupId>
 +        <artifactId>compile-command-annotations</artifactId>
 +        <version>1.2.0</version>
 +        <scope>provided</scope>
 +      </dependency>
 +      <dependency>
 +        <groupId>org.fusesource</groupId>
 +        <artifactId>sigar</artifactId>
 +        <version>1.6.4</version>
 +        <exclusions>
 +          <exclusion>
 +            <artifactId>log4j</artifactId>
 +            <groupId>log4j</groupId>
 +          </exclusion>
 +        </exclusions>
 +      </dependency>
 +      <dependency>
 +        <groupId>com.carrotsearch</groupId>
 +        <artifactId>hppc</artifactId>
 +        <version>0.8.1</version>
 +      </dependency>
 +      <dependency>
 +        <groupId>de.jflex</groupId>
 +        <artifactId>jflex</artifactId>
 +        <version>${jflex.version}</version>
 +        <exclusions>
 +          <exclusion>
 +            <artifactId>ant</artifactId>
 +            <groupId>org.apache.ant</groupId>
 +          </exclusion>
 +        </exclusions>
 +      </dependency>
 +      <dependency>
 +        <groupId>com.github.rholder</groupId>
 +        <artifactId>snowball-stemmer</artifactId>
 +        <version>1.3.0.581.1</version>
 +      </dependency>
 +      <dependency>
 +        <groupId>com.googlecode.concurrent-trees</groupId>
 +        <artifactId>concurrent-trees</artifactId>
 +        <version>2.4.0</version>
 +      </dependency>
 +      <dependency>
 +        <groupId>com.github.ben-manes.caffeine</groupId>
 +        <artifactId>caffeine</artifactId>
 +        <version>2.9.2</version>
 +      </dependency>
 +      <dependency>
 +        <groupId>org.jctools</groupId>
 +        <artifactId>jctools-core</artifactId>
 +        <version>3.1.0</version>
 +      </dependency>
 +
 +      <dependency>
 +        <groupId>org.ow2.asm</groupId>
 +        <artifactId>asm</artifactId>
 +        <version>${asm.version}</version>
 +      </dependency>
 +      <dependency>
 +        <groupId>org.ow2.asm</groupId>
 +        <artifactId>asm-analysis</artifactId>
 +        <version>${asm.version}</version>
 +        <scope>test</scope>
 +      </dependency>
 +      <dependency>
 +        <groupId>org.ow2.asm</groupId>
 +        <artifactId>asm-tree</artifactId>
 +        <version>${asm.version}</version>
 +        <scope>test</scope>
 +      </dependency>
 +      <dependency>
 +        <groupId>org.ow2.asm</groupId>
 +        <artifactId>asm-commons</artifactId>
 +        <version>${asm.version}</version>
 +        <scope>test</scope>
 +      </dependency>
 +      <dependency>
 +        <groupId>org.ow2.asm</groupId>
 +        <artifactId>asm-util</artifactId>
 +        <version>${asm.version}</version>
 +        <scope>test</scope>
 +      </dependency>
 +
 +      <dependency>
 +        <groupId>org.gridkit.jvmtool</groupId>
 +        <artifactId>sjk-cli</artifactId>
 +        <version>0.14</version>
 +      </dependency>
 +      <dependency>
 +        <groupId>org.gridkit.jvmtool</groupId>
 +        <artifactId>sjk-core</artifactId>
 +        <version>0.14</version>
 +        <exclusions>
 +          <exclusion>
 +            <artifactId>sjk-hflame</artifactId>
 +            <groupId>org.gridkit.jvmtool</groupId>
 +          </exclusion>
 +          <exclusion>
 +            <artifactId>sjk-hflame</artifactId>
 +            <groupId>org.perfkit.sjk.parsers</groupId>
 +          </exclusion>
 +          <exclusion>
 +            <artifactId>sjk-jfr-standalone</artifactId>
 +            <groupId>org.perfkit.sjk.parsers</groupId>
 +          </exclusion>
 +          <exclusion>
 +            <artifactId>sjk-nps</artifactId>
 +            <groupId>org.perfkit.sjk.parsers</groupId>
 +          </exclusion>
 +          <exclusion>
 +            <artifactId>sjk-jfr5</artifactId>
 +            <groupId>org.perfkit.sjk.parsers</groupId>
 +          </exclusion>
 +          <exclusion>
 +            <artifactId>sjk-jfr6</artifactId>
 +            <groupId>org.perfkit.sjk.parsers</groupId>
 +          </exclusion>
 +        </exclusions>
 +      </dependency>
 +      <dependency>
 +        <groupId>org.gridkit.jvmtool</groupId>
 +        <artifactId>sjk-stacktrace</artifactId>
 +        <version>0.14</version>
 +      </dependency>
 +      <dependency>
 +        <groupId>org.gridkit.jvmtool</groupId>
 +        <artifactId>mxdump</artifactId>
 +        <version>0.14</version>
 +      </dependency>
 +      <dependency>
 +        <groupId>org.gridkit.lab</groupId>
 +        <artifactId>jvm-attach-api</artifactId>
 +        <version>1.5</version>
 +      </dependency>
 +      <dependency>
 +        <groupId>org.gridkit.jvmtool</groupId>
 +        <artifactId>sjk-json</artifactId>
 +        <version>0.14</version>
 +      </dependency>
 +      <dependency>
 +        <groupId>com.beust</groupId>
 +        <artifactId>jcommander</artifactId>
 +        <version>1.30</version>
 +      </dependency>
 +      <dependency>
 +        <groupId>org.psjava</groupId>
 +        <artifactId>psjava</artifactId>
 +        <version>0.1.19</version>
 +      </dependency>
 +      <dependency>
 +        <groupId>javax.inject</groupId>
 +        <artifactId>javax.inject</artifactId>
 +        <version>1</version>
 +      </dependency>
 +      <dependency>
 +        <groupId>com.google.j2objc</groupId>
 +        <artifactId>j2objc-annotations</artifactId>
 +        <version>1.3</version>
 +      </dependency>
 +      <dependency>
 +        <groupId>org.junit</groupId>
 +        <artifactId>junit-bom</artifactId>
 +        <version>5.6.0</version>
 +        <type>pom</type>
 +        <scope>test</scope>
 +      </dependency>
 +      <dependency>
 +        <groupId>org.assertj</groupId>
 +        <artifactId>assertj-core</artifactId>
 +        <version>3.15.0</version>
 +        <scope>provided</scope>
 +      </dependency>
 +      <dependency>
 +        <groupId>org.awaitility</groupId>
 +        <artifactId>awaitility</artifactId>
 +        <version>4.0.3</version>
 +        <scope>test</scope>
 +        <exclusions>
 +          <exclusion>
 +            <artifactId>hamcrest</artifactId>
 +            <groupId>org.hamcrest</groupId>
 +          </exclusion>
 +        </exclusions>
 +      </dependency>
 +      <dependency>
 +        <groupId>org.hamcrest</groupId>
 +        <artifactId>hamcrest</artifactId>
 +        <version>2.2</version>
 +        <scope>test</scope>
 +      </dependency>
 +      <dependency>
 +        <groupId>com.github.seancfoley</groupId>
 +        <artifactId>ipaddress</artifactId>
 +        <version>5.3.3</version>
 +      </dependency>
 +      <dependency>
 +        <groupId>org.agrona</groupId>
 +        <artifactId>agrona</artifactId>
 +        <version>1.17.1</version>
 +      </dependency>
 +      <dependency>
 +        <groupId>ch.obermuhlner</groupId>
 +        <artifactId>big-math</artifactId>
 +        <version>2.3.0</version>
 +      </dependency>
 +    </dependencies>
 +  </dependencyManagement>
 +</project>
diff --cc NEWS.txt
index 11eafa231b,5dc4c7993a..1ecd60ab29
--- a/NEWS.txt
+++ b/NEWS.txt
@@@ -182,17 -78,6 +182,22 @@@ Upgradin
       upgrades involving 3.x and 4.x nodes. The fix for that issue makes it 
can now appear during rolling upgrades from
       4.1.0 or 4.0.0-4.0.7. If that is your case, please use protocol v4 or 
higher in your driver. See CASSANDRA-17507
       for further details.
 +   - Added API for alternative sstable implementations. For details, see 
src/java/org/apache/cassandra/io/sstable/SSTable_API.md
 +   - DateTieredCompactionStrategy was removed. Please change the compaction 
strategy for the tables using this strategy
 +     to TimeWindowCompactionStrategy before upgrading to this version.
 +   - The deprecated functions `dateOf` and `unixTimestampOf` have been 
removed. They were deprecated and replaced by
 +     `toTimestamp` and `toUnixTimestamp` in Cassandra 2.2.
 +   - Hadoop integration is no longer available (CASSANDRA-18323). If you want 
to process Cassandra data by big data frameworks, 
 +     please upgrade your infrastructure to use Cassandra Spark connector.
 +   - Keystore/truststore password configurations are nullable now and the 
code defaults of those passwords to 'cassandra' are
 +     removed. Any deployments that depend upon the code default to this 
password value without explicitly specifying
 +     it in cassandra.yaml will fail on upgrade. Please specify your 
keystore_password and truststore_password elements in cassandra.yaml with 
appropriate
 +     values to prevent this failure.
++   - Please beware that if you use Ec2Snitch or Ec2MultiRegionSnitch, by 
default it will 
++     communicate with AWS IMDS of version 2. This change is transparent, 
there does not need 
++     to be done anything upon upgrade. Furthermore, IMDS of version 2 can be 
configured to be required in AWS EC2 console.
++     Consult cassandra-rackdc.properties for more details. (CASSANDRA-16555)
++
  
  Deprecation
  -----------
diff --cc test/unit/org/apache/cassandra/locator/Ec2SnitchTest.java
index 78c5d40dfc,a7f503d1bd..abd9bb0989
--- a/test/unit/org/apache/cassandra/locator/Ec2SnitchTest.java
+++ b/test/unit/org/apache/cassandra/locator/Ec2SnitchTest.java
@@@ -42,14 -40,18 +40,19 @@@ import org.mockito.stubbing.Answer
  
  import static org.apache.cassandra.ServerTestUtils.cleanup;
  import static org.apache.cassandra.ServerTestUtils.mkdirs;
 +import static 
org.apache.cassandra.config.CassandraRelevantProperties.GOSSIP_DISABLE_THREAD_VALIDATION;
+ import static 
org.apache.cassandra.locator.Ec2MultiRegionSnitch.PRIVATE_IP_QUERY;
+ import static 
org.apache.cassandra.locator.Ec2MultiRegionSnitch.PUBLIC_IP_QUERY;
  import static org.apache.cassandra.locator.Ec2Snitch.EC2_NAMING_LEGACY;
  import static org.junit.Assert.assertEquals;
+ import static org.junit.Assert.assertFalse;
+ import static org.junit.Assert.assertTrue;
+ import static org.mockito.ArgumentMatchers.anyString;
+ import static org.mockito.Mockito.mock;
+ import static org.mockito.Mockito.when;
  
- public class EC2SnitchTest
+ public class Ec2SnitchTest
  {
-     private static String az;
- 
      private final SnitchProperties legacySnitchProps = new SnitchProperties()
      {
          public String get(String propertyName, String defaultValue)
diff --cc test/unit/org/apache/cassandra/locator/Ec2V2ConnectorMockingTest.java
index 0000000000,0000000000..8fdbdfa093
new file mode 100644
--- /dev/null
+++ b/test/unit/org/apache/cassandra/locator/Ec2V2ConnectorMockingTest.java
@@@ -1,0 -1,0 +1,169 @@@
++/*
++ * Licensed to the Apache Software Foundation (ASF) under one
++ * or more contributor license agreements.  See the NOTICE file
++ * distributed with this work for additional information
++ * regarding copyright ownership.  The ASF licenses this file
++ * to you 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.
++ */
++
++package org.apache.cassandra.locator;
++
++import java.util.Properties;
++
++import org.junit.Rule;
++import org.junit.Test;
++
++import com.github.tomakehurst.wiremock.client.MappingBuilder;
++import com.github.tomakehurst.wiremock.junit.WireMockRule;
++import org.apache.cassandra.locator.Ec2MetadataServiceConnector.V2Connector;
++
++import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
++import static com.github.tomakehurst.wiremock.client.WireMock.equalTo;
++import static com.github.tomakehurst.wiremock.client.WireMock.get;
++import static com.github.tomakehurst.wiremock.client.WireMock.put;
++import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
++import static 
com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig;
++import static java.nio.charset.StandardCharsets.UTF_8;
++import static 
org.apache.cassandra.locator.Ec2MetadataServiceConnector.EC2MetadataType.v2;
++import static 
org.apache.cassandra.locator.Ec2MetadataServiceConnector.EC2_METADATA_TYPE_PROPERTY;
++import static 
org.apache.cassandra.locator.Ec2MetadataServiceConnector.V1Connector.EC2_METADATA_URL_PROPERTY;
++import static 
org.apache.cassandra.locator.Ec2MetadataServiceConnector.V2Connector.AWS_EC2_METADATA_TOKEN_HEADER;
++import static 
org.apache.cassandra.locator.Ec2MetadataServiceConnector.V2Connector.AWS_EC2_METADATA_TOKEN_TTL_SECONDS_HEADER;
++import static 
org.apache.cassandra.locator.Ec2MetadataServiceConnector.V2Connector.AWS_EC2_METADATA_TOKEN_TTL_SECONDS_HEADER_PROPERTY;
++import static 
org.apache.cassandra.locator.Ec2MetadataServiceConnector.V2Connector.TOKEN_QUERY;
++import static org.apache.cassandra.locator.Ec2Snitch.ZONE_NAME_QUERY;
++import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
++import static org.junit.Assert.assertEquals;
++import static org.mockito.Mockito.spy;
++import static org.mockito.Mockito.times;
++import static org.mockito.Mockito.verify;
++
++public class Ec2V2ConnectorMockingTest
++{
++    private static final String token = "thisismytoken";
++    private static final String az = "us-east-1a";
++
++    @Rule
++    public WireMockRule v2Service = new 
WireMockRule(wireMockConfig().bindAddress("127.0.0.1").port(8080));
++
++    @Test
++    public void testV2Connector() throws Throwable
++    {
++        v2Service.stubFor(tokenRequest(100, 200, token));
++        v2Service.stubFor(azRequest(az, 200, token));
++
++        assertEquals(az, getConnector(100).apiCall(ZONE_NAME_QUERY));
++    }
++
++    @Test
++    public void testV2ConnectorWhenUnauthorized()
++    {
++        String unauthorizedBody = "<?xml version=\"1.0\" 
encoding=\"iso-8859-1\"?>\n" +
++                                  "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 
1.0 Transitional//EN\"\n" +
++                                  
"\t\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\";>\n" +
++                                  "<html 
xmlns=\"http://www.w3.org/1999/xhtml\"; xml:lang=\"en\" lang=\"en\">\n" +
++                                  " <head>\n" +
++                                  "  <title>401 - Unauthorized</title>\n" +
++                                  " </head>\n" +
++                                  " <body>\n" +
++                                  "  <h1>401 - Unauthorized</h1>\n" +
++                                  " </body>\n" +
++                                  "</html>\n";
++
++        v2Service.stubFor(tokenRequest(100, 200, token));
++
++        
v2Service.stubFor(get(urlEqualTo(ZONE_NAME_QUERY)).withHeader(AWS_EC2_METADATA_TOKEN_HEADER,
 equalTo(token))
++                                                          
.willReturn(aResponse().withStatus(401)
++                                                                              
   .withStatusMessage("Unauthorized")
++                                                                              
   .withHeader("Content-Type", "text/html")
++                                                                              
   .withHeader("Content-Length", 
String.valueOf(unauthorizedBody.getBytes(UTF_8).length))));
++
++        V2Connector.HTTP_REQUEST_RETRIES = 0;
++        Ec2MetadataServiceConnector v2Connector = getConnector(100);
++
++        
assertThatExceptionOfType(AbstractCloudMetadataServiceConnector.HttpException.class)
++        .isThrownBy(() -> v2Connector.apiCall(ZONE_NAME_QUERY))
++        .matches(ex -> ex.responseCode == 401 && 
"Unauthorized".equals(ex.responseMessage),
++                 "exception should have response code 401 with response 
message 'Unauthorized'");
++    }
++
++    @Test
++    public void testCachedToken() throws Throwable
++    {
++        v2Service.stubFor(tokenRequest(30, 200, token));
++        v2Service.stubFor(azRequest(az, 200, token));
++
++        V2Connector spiedConnector = (V2Connector) spy(getConnector(30));
++
++        spiedConnector.apiCall(ZONE_NAME_QUERY);
++        verify(spiedConnector, times(1)).getToken();
++
++        // lets wait 10 seconds and make a call again
++        // which will use cached token and will not call token endpoint
++        // for the second time
++        Thread.sleep(10000);
++
++        // as token is not expired yet, another call to getToken will not be 
done
++        spiedConnector.apiCall(ZONE_NAME_QUERY);
++
++        // here we still have just 1 call to getToken method because we used 
a cached token
++        verify(spiedConnector, times(1)).getToken();
++    }
++
++    @Test
++    public void testExpiredTokenInteraction() throws Throwable
++    {
++        v2Service.stubFor(tokenRequest(30, 200, token));
++        v2Service.stubFor(azRequest(az, 200, token));
++
++        V2Connector spiedConnector = (V2Connector) spy(getConnector(30));
++
++        spiedConnector.apiCall(ZONE_NAME_QUERY);
++        verify(spiedConnector, times(1)).getToken();
++
++        // lets expire the token
++        Thread.sleep(35000);
++
++        // as token is expired, another call to getToken will be done
++        spiedConnector.apiCall(ZONE_NAME_QUERY);
++        verify(spiedConnector, times(2)).getToken();
++    }
++
++    private Ec2MetadataServiceConnector getConnector(int tokenTTL)
++    {
++        Properties p = new Properties();
++        p.setProperty(EC2_METADATA_TYPE_PROPERTY, v2.toString());
++        p.setProperty(EC2_METADATA_URL_PROPERTY, "http://127.0.0.1:8080";);
++        p.setProperty(AWS_EC2_METADATA_TOKEN_TTL_SECONDS_HEADER_PROPERTY, 
String.valueOf(tokenTTL));
++
++        return Ec2MetadataServiceConnector.create(new SnitchProperties(p));
++    }
++
++    private MappingBuilder tokenRequest(int ttl, int status, String 
tokenToReturn)
++    {
++        return 
put(urlEqualTo(TOKEN_QUERY)).withHeader(AWS_EC2_METADATA_TOKEN_TTL_SECONDS_HEADER,
 equalTo(String.valueOf(ttl)))
++                                           
.willReturn(aResponse().withBody(tokenToReturn)
++                                                                  
.withStatus(status)
++                                                                  
.withHeader("Content-Type", "text/plain")
++                                                                  
.withHeader("Content-Length", 
String.valueOf(tokenToReturn.getBytes(UTF_8).length)));
++    }
++
++    private MappingBuilder azRequest(String az, int status, String token)
++    {
++        return 
get(urlEqualTo(ZONE_NAME_QUERY)).withHeader(AWS_EC2_METADATA_TOKEN_HEADER, 
equalTo(token))
++                                               
.willReturn(aResponse().withBody(az)
++                                                                      
.withStatus(status)
++                                                                      
.withHeader("Content-Type", "text/plain")
++                                                                      
.withHeader("Content-Length", String.valueOf(az.getBytes(UTF_8).length)));
++    }
++}


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to