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]
