diff --git a/CHANGES.txt b/CHANGES.txt index 43126ed254..ec056e243a 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,4 +1,5 @@ 4.0-alpha3 + * Remove joda time dependency (CASSANDRA-15257) * Exclude purgeable tombstones from repaired data tracking (CASSANDRA-15462) * Exclude legacy counter shards from repaired data tracking (CASSANDRA-15461) * Make it easier to add trace headers to messages (CASSANDRA-15499) diff --git a/build.xml b/build.xml index 4de9285de7..0c9568740a 100644 --- a/build.xml +++ b/build.xml @@ -576,7 +576,6 @@ - @@ -709,7 +708,6 @@ - @@ -775,7 +773,6 @@ - diff --git a/ide/nbproject/project.xml b/ide/nbproject/project.xml index ece0d01a83..6b8a31ea71 100644 --- a/ide/nbproject/project.xml +++ b/ide/nbproject/project.xml @@ -7,7 +7,7 @@ .. - ${project.dir}/lib/HdrHistogram-2.1.9.jar:${project.dir}/lib/ST4-4.0.8.jar:${project.dir}/lib/airline-0.8.jar:${project.dir}/lib/antlr-runtime-3.5.2.jar:${project.dir}/lib/asm-7.1.jar:${project.dir}/lib/caffeine-2.3.5.jar:${project.dir}/lib/cassandra-driver-core-3.6.0-shaded.jar:${project.dir}/lib/chronicle-bytes-1.16.3.jar:${project.dir}/lib/chronicle-core-1.16.4.jar:${project.dir}/lib/chronicle-queue-4.16.3.jar:${project.dir}/lib/chronicle-threads-1.16.0.jar:${project.dir}/lib/chronicle-wire-1.16.1.jar:${project.dir}/lib/commons-cli-1.1.jar:${project.dir}/lib/commons-codec-1.9.jar:${project.dir}/lib/commons-lang3-3.1.jar:${project.dir}/lib/commons-math3-3.2.jar:${project.dir}/lib/concurrent-trees-2.4.0.jar:${project.dir}/lib/ecj-4.6.1.jar:${project.dir}/lib/guava-27.0-jre.jar:${project.dir}/lib/high-scale-lib-1.0.6.jar:${project.dir}/lib/hppc-0.5.4.jar:${project.dir}/lib/j2objc-annotations-1.3.jar:${project.dir}/lib/jackson-annotations-2.9.5.jar:${project.dir}/lib/jackson-core-2.9.5.jar:${project.dir}/lib/jackson-databind-2.9.5.jar:${project.dir}/lib/jamm-0.3.2.jar:${project.dir}/lib/javax.inject.jar:${project.dir}/lib/jbcrypt-0.3m.jar:${project.dir}/lib/jcl-over-slf4j-1.7.25.jar:${project.dir}/lib/jctools-core-1.2.1.jar:${project.dir}/lib/jflex-1.6.0.jar:${project.dir}/lib/jna-4.2.2.jar:${project.dir}/lib/joda-time-2.4.jar:${project.dir}/lib/json-simple-1.1.jar:${project.dir}/lib/jstackjunit-0.0.1.jar:${project.dir}/lib/log4j-over-slf4j-1.7.25.jar:${project.dir}/lib/logback-classic-1.2.3.jar:${project.dir}/lib/logback-core-1.2.3.jar:${project.dir}/lib/lz4-java-1.4.0.jar:${project.dir}/lib/metrics-core-3.1.5.jar:${project.dir}/lib/metrics-jvm-3.1.5.jar:${project.dir}/lib/metrics-logback-3.1.5.jar:${project.dir}/lib/netty-all-4.1.37.Final.jar:${project.dir}/lib/netty-tcnative-boringssl-static-2.0.25.Final.jar:${project.dir}/lib/ohc-core-0.5.1.jar:${project.dir}/lib/ohc-core-j8-0.5.1.jar:${project.dir}/lib/psjava-0.1.19.jar:${project.dir}/lib/reporter-config-base-3.0.3.jar:${project.dir}/lib/reporter-config3-3.0.3.jar:${project.dir}/lib/sigar-1.6.4.jar:${project.dir}/lib/slf4j-api-1.7.25.jar:${project.dir}/lib/snakeyaml-1.11.jar:${project.dir}/lib/snappy-java-1.1.2.6.jar:${project.dir}/lib/snowball-stemmer-1.3.0.581.1.jar:${project.dir}/lib/stream-2.5.2.jar:${project.dir}/lib/zstd-jni-1.3.8-5.jar:${project.dir}/build/lib/jars/ST4-4.0.8.jar:${project.dir}/build/lib/jars/ant-1.9.7.jar:${project.dir}/build/lib/jars/ant-junit-1.9.7.jar:${project.dir}/build/lib/jars/ant-launcher-1.9.7.jar:${project.dir}/build/lib/jars/antlr-3.5.2.jar:${project.dir}/build/lib/jars/antlr-runtime-3.5.2.jar:${project.dir}/build/lib/jars/apache-rat-0.10.jar:${project.dir}/build/lib/jars/apache-rat-core-0.10.jar:${project.dir}/build/lib/jars/apache-rat-tasks-0.10.jar:${project.dir}/build/lib/jars/byteman-4.0.6.jar:${project.dir}/build/lib/jars/byteman-bmunit-4.0.6.jar:${project.dir}/build/lib/jars/byteman-install-4.0.6.jar:${project.dir}/build/lib/jars/byteman-submit-4.0.6.jar:${project.dir}/build/lib/jars/cassandra-driver-core-3.6.0-shaded.jar:${project.dir}/build/lib/jars/commons-beanutils-1.7.0.jar:${project.dir}/build/lib/jars/commons-beanutils-core-1.8.0.jar:${project.dir}/build/lib/jars/commons-cli-1.2.jar:${project.dir}/build/lib/jars/commons-codec-1.4.jar:${project.dir}/build/lib/jars/commons-collections-3.2.1.jar:${project.dir}/build/lib/jars/commons-compress-1.5.jar:${project.dir}/build/lib/jars/commons-configuration-1.6.jar:${project.dir}/build/lib/jars/commons-digester-1.8.jar:${project.dir}/build/lib/jars/commons-el-1.0.jar:${project.dir}/build/lib/jars/commons-httpclient-3.0.1.jar:${project.dir}/build/lib/jars/commons-io-2.2.jar:${project.dir}/build/lib/jars/commons-lang-2.4.jar:${project.dir}/build/lib/jars/commons-math-2.1.jar:${project.dir}/build/lib/jars/commons-math3-3.2.jar:${project.dir}/build/lib/jars/commons-net-1.4.1.jar:${project.dir}/build/lib/jars/compile-command-annotations-1.2.0.jar:${project.dir}/build/lib/jars/ecj-4.6.1.jar:${project.dir}/build/lib/jars/ftplet-api-1.0.0.jar:${project.dir}/build/lib/jars/ftpserver-core-1.0.0.jar:${project.dir}/build/lib/jars/ftpserver-deprecated-1.0.0-M2.jar:${project.dir}/build/lib/jars/guava-19.0.jar:${project.dir}/build/lib/jars/hadoop-core-1.0.3.jar:${project.dir}/build/lib/jars/hadoop-minicluster-1.0.3.jar:${project.dir}/build/lib/jars/hadoop-test-1.0.3.jar:${project.dir}/build/lib/jars/hamcrest-core-1.3.jar:${project.dir}/build/lib/jars/hsqldb-1.8.0.10.jar:${project.dir}/build/lib/jars/jackson-core-asl-1.0.1.jar:${project.dir}/build/lib/jars/jackson-mapper-asl-1.0.1.jar:${project.dir}/build/lib/jars/jacocoagent.jar:${project.dir}/build/lib/jars/jasper-compiler-5.5.12.jar:${project.dir}/build/lib/jars/jasper-runtime-5.5.12.jar:${project.dir}/build/lib/jars/jersey-core-1.0.jar:${project.dir}/build/lib/jars/jersey-server-1.0.jar:${project.dir}/build/lib/jars/jets3t-0.7.1.jar:${project.dir}/build/lib/jars/jetty-6.1.26.jar:${project.dir}/build/lib/jars/jetty-util-6.1.26.jar:${project.dir}/build/lib/jars/jffi-1.2.16-native.jar:${project.dir}/build/lib/jars/jffi-1.2.16.jar:${project.dir}/build/lib/jars/jmh-core-1.21.jar:${project.dir}/build/lib/jars/jmh-generator-annprocess-1.21.jar:${project.dir}/build/lib/jars/jna-4.1.0.jar:${project.dir}/build/lib/jars/jnr-constants-0.9.9.jar:${project.dir}/build/lib/jars/jnr-ffi-2.1.7.jar:${project.dir}/build/lib/jars/jnr-posix-3.0.44.jar:${project.dir}/build/lib/jars/jnr-x86asm-1.0.2.jar:${project.dir}/build/lib/jars/jopt-simple-4.6.jar:${project.dir}/build/lib/jars/jsp-2.1-6.1.14.jar:${project.dir}/build/lib/jars/jsp-api-2.1-6.1.14.jar:${project.dir}/build/lib/jars/jsr305-2.0.2.jar:${project.dir}/build/lib/jars/jsr311-api-1.0.jar:${project.dir}/build/lib/jars/junit-4.12.jar:${project.dir}/build/lib/jars/kfs-0.3.jar:${project.dir}/build/lib/jars/metrics-core-3.2.2.jar:${project.dir}/build/lib/jars/mina-core-2.0.0-M5.jar:${project.dir}/build/lib/jars/ohc-core-0.5.1.jar:${project.dir}/build/lib/jars/ohc-core-j8-0.5.1.jar:${project.dir}/build/lib/jars/org.jacoco.agent-0.7.5.201505241946.jar:${project.dir}/build/lib/jars/org.jacoco.ant-0.7.5.201505241946.jar:${project.dir}/build/lib/jars/org.jacoco.core-0.7.5.201505241946.jar:${project.dir}/build/lib/jars/org.jacoco.report-0.7.5.201505241946.jar:${project.dir}/build/lib/jars/oro-2.0.8.jar:${project.dir}/build/lib/jars/psjava-0.1.19.jar:${project.dir}/build/lib/jars/quicktheories-0.25.jar:${project.dir}/build/lib/jars/servlet-api-2.5-6.1.14.jar:${project.dir}/build/lib/jars/xmlenc-0.52.jar: + ${project.dir}/lib/HdrHistogram-2.1.9.jar:${project.dir}/lib/ST4-4.0.8.jar:${project.dir}/lib/airline-0.8.jar:${project.dir}/lib/antlr-runtime-3.5.2.jar:${project.dir}/lib/asm-7.1.jar:${project.dir}/lib/caffeine-2.3.5.jar:${project.dir}/lib/cassandra-driver-core-3.6.0-shaded.jar:${project.dir}/lib/chronicle-bytes-1.16.3.jar:${project.dir}/lib/chronicle-core-1.16.4.jar:${project.dir}/lib/chronicle-queue-4.16.3.jar:${project.dir}/lib/chronicle-threads-1.16.0.jar:${project.dir}/lib/chronicle-wire-1.16.1.jar:${project.dir}/lib/commons-cli-1.1.jar:${project.dir}/lib/commons-codec-1.9.jar:${project.dir}/lib/commons-lang3-3.1.jar:${project.dir}/lib/commons-math3-3.2.jar:${project.dir}/lib/concurrent-trees-2.4.0.jar:${project.dir}/lib/ecj-4.6.1.jar:${project.dir}/lib/guava-27.0-jre.jar:${project.dir}/lib/high-scale-lib-1.0.6.jar:${project.dir}/lib/hppc-0.5.4.jar:${project.dir}/lib/j2objc-annotations-1.3.jar:${project.dir}/lib/jackson-annotations-2.9.5.jar:${project.dir}/lib/jackson-core-2.9.5.jar:${project.dir}/lib/jackson-databind-2.9.5.jar:${project.dir}/lib/jamm-0.3.2.jar:${project.dir}/lib/javax.inject.jar:${project.dir}/lib/jbcrypt-0.3m.jar:${project.dir}/lib/jcl-over-slf4j-1.7.25.jar:${project.dir}/lib/jctools-core-1.2.1.jar:${project.dir}/lib/jflex-1.6.0.jar:${project.dir}/lib/jna-4.2.2.jar:${project.dir}/lib/json-simple-1.1.jar:${project.dir}/lib/jstackjunit-0.0.1.jar:${project.dir}/lib/log4j-over-slf4j-1.7.25.jar:${project.dir}/lib/logback-classic-1.2.3.jar:${project.dir}/lib/logback-core-1.2.3.jar:${project.dir}/lib/lz4-java-1.4.0.jar:${project.dir}/lib/metrics-core-3.1.5.jar:${project.dir}/lib/metrics-jvm-3.1.5.jar:${project.dir}/lib/metrics-logback-3.1.5.jar:${project.dir}/lib/netty-all-4.1.37.Final.jar:${project.dir}/lib/netty-tcnative-boringssl-static-2.0.25.Final.jar:${project.dir}/lib/ohc-core-0.5.1.jar:${project.dir}/lib/ohc-core-j8-0.5.1.jar:${project.dir}/lib/psjava-0.1.19.jar:${project.dir}/lib/reporter-config-base-3.0.3.jar:${project.dir}/lib/reporter-config3-3.0.3.jar:${project.dir}/lib/sigar-1.6.4.jar:${project.dir}/lib/slf4j-api-1.7.25.jar:${project.dir}/lib/snakeyaml-1.11.jar:${project.dir}/lib/snappy-java-1.1.2.6.jar:${project.dir}/lib/snowball-stemmer-1.3.0.581.1.jar:${project.dir}/lib/stream-2.5.2.jar:${project.dir}/lib/zstd-jni-1.3.8-5.jar:${project.dir}/build/lib/jars/ST4-4.0.8.jar:${project.dir}/build/lib/jars/ant-1.9.7.jar:${project.dir}/build/lib/jars/ant-junit-1.9.7.jar:${project.dir}/build/lib/jars/ant-launcher-1.9.7.jar:${project.dir}/build/lib/jars/antlr-3.5.2.jar:${project.dir}/build/lib/jars/antlr-runtime-3.5.2.jar:${project.dir}/build/lib/jars/apache-rat-0.10.jar:${project.dir}/build/lib/jars/apache-rat-core-0.10.jar:${project.dir}/build/lib/jars/apache-rat-tasks-0.10.jar:${project.dir}/build/lib/jars/byteman-4.0.6.jar:${project.dir}/build/lib/jars/byteman-bmunit-4.0.6.jar:${project.dir}/build/lib/jars/byteman-install-4.0.6.jar:${project.dir}/build/lib/jars/byteman-submit-4.0.6.jar:${project.dir}/build/lib/jars/cassandra-driver-core-3.6.0-shaded.jar:${project.dir}/build/lib/jars/commons-beanutils-1.7.0.jar:${project.dir}/build/lib/jars/commons-beanutils-core-1.8.0.jar:${project.dir}/build/lib/jars/commons-cli-1.2.jar:${project.dir}/build/lib/jars/commons-codec-1.4.jar:${project.dir}/build/lib/jars/commons-collections-3.2.1.jar:${project.dir}/build/lib/jars/commons-compress-1.5.jar:${project.dir}/build/lib/jars/commons-configuration-1.6.jar:${project.dir}/build/lib/jars/commons-digester-1.8.jar:${project.dir}/build/lib/jars/commons-el-1.0.jar:${project.dir}/build/lib/jars/commons-httpclient-3.0.1.jar:${project.dir}/build/lib/jars/commons-io-2.2.jar:${project.dir}/build/lib/jars/commons-lang-2.4.jar:${project.dir}/build/lib/jars/commons-math-2.1.jar:${project.dir}/build/lib/jars/commons-math3-3.2.jar:${project.dir}/build/lib/jars/commons-net-1.4.1.jar:${project.dir}/build/lib/jars/compile-command-annotations-1.2.0.jar:${project.dir}/build/lib/jars/ecj-4.6.1.jar:${project.dir}/build/lib/jars/ftplet-api-1.0.0.jar:${project.dir}/build/lib/jars/ftpserver-core-1.0.0.jar:${project.dir}/build/lib/jars/ftpserver-deprecated-1.0.0-M2.jar:${project.dir}/build/lib/jars/guava-19.0.jar:${project.dir}/build/lib/jars/hadoop-core-1.0.3.jar:${project.dir}/build/lib/jars/hadoop-minicluster-1.0.3.jar:${project.dir}/build/lib/jars/hadoop-test-1.0.3.jar:${project.dir}/build/lib/jars/hamcrest-core-1.3.jar:${project.dir}/build/lib/jars/hsqldb-1.8.0.10.jar:${project.dir}/build/lib/jars/jackson-core-asl-1.0.1.jar:${project.dir}/build/lib/jars/jackson-mapper-asl-1.0.1.jar:${project.dir}/build/lib/jars/jacocoagent.jar:${project.dir}/build/lib/jars/jasper-compiler-5.5.12.jar:${project.dir}/build/lib/jars/jasper-runtime-5.5.12.jar:${project.dir}/build/lib/jars/jersey-core-1.0.jar:${project.dir}/build/lib/jars/jersey-server-1.0.jar:${project.dir}/build/lib/jars/jets3t-0.7.1.jar:${project.dir}/build/lib/jars/jetty-6.1.26.jar:${project.dir}/build/lib/jars/jetty-util-6.1.26.jar:${project.dir}/build/lib/jars/jffi-1.2.16-native.jar:${project.dir}/build/lib/jars/jffi-1.2.16.jar:${project.dir}/build/lib/jars/jmh-core-1.21.jar:${project.dir}/build/lib/jars/jmh-generator-annprocess-1.21.jar:${project.dir}/build/lib/jars/jna-4.1.0.jar:${project.dir}/build/lib/jars/jnr-constants-0.9.9.jar:${project.dir}/build/lib/jars/jnr-ffi-2.1.7.jar:${project.dir}/build/lib/jars/jnr-posix-3.0.44.jar:${project.dir}/build/lib/jars/jnr-x86asm-1.0.2.jar:${project.dir}/build/lib/jars/jopt-simple-4.6.jar:${project.dir}/build/lib/jars/jsp-2.1-6.1.14.jar:${project.dir}/build/lib/jars/jsp-api-2.1-6.1.14.jar:${project.dir}/build/lib/jars/jsr305-2.0.2.jar:${project.dir}/build/lib/jars/jsr311-api-1.0.jar:${project.dir}/build/lib/jars/junit-4.12.jar:${project.dir}/build/lib/jars/kfs-0.3.jar:${project.dir}/build/lib/jars/metrics-core-3.2.2.jar:${project.dir}/build/lib/jars/mina-core-2.0.0-M5.jar:${project.dir}/build/lib/jars/ohc-core-0.5.1.jar:${project.dir}/build/lib/jars/ohc-core-j8-0.5.1.jar:${project.dir}/build/lib/jars/org.jacoco.agent-0.7.5.201505241946.jar:${project.dir}/build/lib/jars/org.jacoco.ant-0.7.5.201505241946.jar:${project.dir}/build/lib/jars/org.jacoco.core-0.7.5.201505241946.jar:${project.dir}/build/lib/jars/org.jacoco.report-0.7.5.201505241946.jar:${project.dir}/build/lib/jars/oro-2.0.8.jar:${project.dir}/build/lib/jars/psjava-0.1.19.jar:${project.dir}/build/lib/jars/quicktheories-0.25.jar:${project.dir}/build/lib/jars/servlet-api-2.5-6.1.14.jar:${project.dir}/build/lib/jars/xmlenc-0.52.jar: diff --git a/lib/joda-time-2.4.jar b/lib/joda-time-2.4.jar deleted file mode 100644 index ace67d7a25..0000000000 Binary files a/lib/joda-time-2.4.jar and /dev/null differ diff --git a/src/java/org/apache/cassandra/serializers/SimpleDateSerializer.java b/src/java/org/apache/cassandra/serializers/SimpleDateSerializer.java index 075094c293..fbb5087cf0 100644 --- a/src/java/org/apache/cassandra/serializers/SimpleDateSerializer.java +++ b/src/java/org/apache/cassandra/serializers/SimpleDateSerializer.java @@ -18,22 +18,26 @@ package org.apache.cassandra.serializers; import java.nio.ByteBuffer; +import java.time.Duration; +import java.time.Instant; +import java.time.LocalDate; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeParseException; import java.util.concurrent.TimeUnit; import java.util.regex.Pattern; -import org.joda.time.DateTime; -import org.joda.time.DateTimeZone; -import org.joda.time.LocalDate; -import org.joda.time.format.DateTimeFormat; -import org.joda.time.format.DateTimeFormatter; - import org.apache.cassandra.utils.ByteBufferUtil; +import static java.time.ZoneOffset.UTC; +import static java.time.format.ResolverStyle.STRICT; + // For byte-order comparability, we shift by Integer.MIN_VALUE and treat the data as an unsigned integer ranging from // min date to max date w/epoch sitting in the center @ 2^31 public class SimpleDateSerializer implements TypeSerializer { - private static final DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd").withZone(DateTimeZone.UTC); + private static final DateTimeFormatter formatter = + DateTimeFormatter.ISO_LOCAL_DATE.withZone(UTC).withResolverStyle(STRICT); private static final long minSupportedDateMillis = TimeUnit.DAYS.toMillis(Integer.MIN_VALUE); private static final long maxSupportedDateMillis = TimeUnit.DAYS.toMillis(Integer.MAX_VALUE); private static final long maxSupportedDays = (long)Math.pow(2,32) - 1; @@ -57,53 +61,57 @@ public class SimpleDateSerializer implements TypeSerializer // Raw day value in unsigned int form, epoch @ 2^31 if (rawPattern.matcher(source).matches()) { - try - { - long result = Long.parseLong(source); - - if (result < 0 || result > maxSupportedDays) - throw new NumberFormatException("Input out of bounds: " + source); - - // Shift > epoch days into negative portion of Integer result for byte order comparability - if (result >= Integer.MAX_VALUE) - result -= byteOrderShift; - - return (int) result; - } - catch (NumberFormatException e) - { - throw new MarshalException(String.format("Unable to make unsigned int (for date) from: '%s'", source), e); - } + return parseRaw(source); } // Attempt to parse as date string try { - DateTime parsed = formatter.parseDateTime(source); - long millis = parsed.getMillis(); + LocalDate parsed = formatter.parse(source, LocalDate::from); + long millis = parsed.atStartOfDay(UTC).toInstant().toEpochMilli(); if (millis < minSupportedDateMillis) - throw new MarshalException(String.format("Input date %s is less than min supported date %s", source, new LocalDate(minSupportedDateMillis).toString())); + throw new MarshalException(String.format("Input date %s is less than min supported date %s", source, + ZonedDateTime.ofInstant(Instant.ofEpochMilli(minSupportedDateMillis), UTC).toString())); if (millis > maxSupportedDateMillis) - throw new MarshalException(String.format("Input date %s is greater than max supported date %s", source, new LocalDate(maxSupportedDateMillis).toString())); + throw new MarshalException(String.format("Input date %s is greater than max supported date %s", source, + ZonedDateTime.ofInstant(Instant.ofEpochMilli(maxSupportedDateMillis), UTC).toString())); return timeInMillisToDay(millis); } - catch (IllegalArgumentException e1) + catch (DateTimeParseException| ArithmeticException e1) { throw new MarshalException(String.format("Unable to coerce '%s' to a formatted date (long)", source), e1); } } + private static int parseRaw(String source) { + try + { + long result = Long.parseLong(source); + + if (result < 0 || result > maxSupportedDays) + throw new NumberFormatException("Input out of bounds: " + source); + + // Shift > epoch days into negative portion of Integer result for byte order comparability + if (result >= Integer.MAX_VALUE) + result -= byteOrderShift; + + return (int) result; + } + catch (NumberFormatException | DateTimeParseException e) + { + throw new MarshalException(String.format("Unable to make unsigned int (for date) from: '%s'", source), e); + } + } + public static int timeInMillisToDay(long millis) { - Integer result = (int) TimeUnit.MILLISECONDS.toDays(millis); - result -= Integer.MIN_VALUE; - return result; + return (int) (Duration.ofMillis(millis).toDays() - Integer.MIN_VALUE); } public static long dayToTimeInMillis(int days) { - return TimeUnit.DAYS.toMillis(days - Integer.MIN_VALUE); + return Duration.ofDays(days + Integer.MIN_VALUE).toMillis(); } public void validate(ByteBuffer bytes) throws MarshalException @@ -117,7 +125,7 @@ public class SimpleDateSerializer implements TypeSerializer if (value == null) return ""; - return formatter.print(new LocalDate(dayToTimeInMillis(value), DateTimeZone.UTC)); + return Instant.ofEpochMilli(dayToTimeInMillis(value)).atZone(UTC).format(formatter); } public Class getType() diff --git a/src/java/org/apache/cassandra/tools/SSTableMetadataViewer.java b/src/java/org/apache/cassandra/tools/SSTableMetadataViewer.java index 8f7e8a5dbd..eb8670cee2 100755 --- a/src/java/org/apache/cassandra/tools/SSTableMetadataViewer.java +++ b/src/java/org/apache/cassandra/tools/SSTableMetadataViewer.java @@ -21,6 +21,7 @@ import static org.apache.cassandra.tools.Util.BLUE; import static org.apache.cassandra.tools.Util.CYAN; import static org.apache.cassandra.tools.Util.RESET; import static org.apache.cassandra.tools.Util.WHITE; +import static org.apache.commons.lang3.time.DurationFormatUtils.formatDurationWords; import java.io.DataInputStream; import java.io.File; @@ -70,10 +71,9 @@ import org.apache.commons.cli.Option; import org.apache.commons.cli.Options; import org.apache.commons.cli.ParseException; import org.apache.commons.cli.PosixParser; -import org.joda.time.Duration; -import org.joda.time.format.PeriodFormat; import com.google.common.collect.MinMaxPriorityQueue; +import org.apache.commons.lang3.time.DurationFormatUtils; /** * Shows the contents of sstable metadata @@ -143,7 +143,7 @@ public class SSTableMetadataViewer { return "never"; } - return PeriodFormat.getDefault().print(new Duration(unit.toMillis(duration)).toPeriod()); + return formatDurationWords(unit.toMillis(duration), true, true); } public static String toByteString(long bytes) diff --git a/test/unit/org/apache/cassandra/cql3/functions/CastFctsTest.java b/test/unit/org/apache/cassandra/cql3/functions/CastFctsTest.java index 2ffd8b41f3..ee6c69f8d8 100644 --- a/test/unit/org/apache/cassandra/cql3/functions/CastFctsTest.java +++ b/test/unit/org/apache/cassandra/cql3/functions/CastFctsTest.java @@ -19,14 +19,17 @@ package org.apache.cassandra.cql3.functions; import java.math.BigDecimal; import java.math.BigInteger; +import java.time.LocalDate; +import java.time.LocalTime; +import java.time.ZoneOffset; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; import java.util.Date; import org.apache.cassandra.cql3.CQLTester; import org.apache.cassandra.serializers.SimpleDateSerializer; import org.apache.cassandra.utils.UUIDGen; -import org.joda.time.DateTime; -import org.joda.time.DateTimeZone; -import org.joda.time.format.DateTimeFormat; + import org.junit.Test; public class CastFctsTest extends CQLTester @@ -217,25 +220,23 @@ public class CastFctsTest extends CQLTester { createTable("CREATE TABLE %s (a timeuuid primary key, b timestamp, c date, d time)"); - DateTime dateTime = DateTimeFormat.forPattern("yyyy-MM-dd hh:mm:ss") - .withZone(DateTimeZone.UTC) - .parseDateTime("2015-05-21 11:03:02"); + final String yearMonthDay = "2015-05-21"; + final LocalDate localDate = LocalDate.of(2015, 5, 21); + ZonedDateTime date = localDate.atStartOfDay(ZoneOffset.UTC); - DateTime date = DateTimeFormat.forPattern("yyyy-MM-dd") - .withZone(DateTimeZone.UTC) - .parseDateTime("2015-05-21"); + ZonedDateTime dateTime = ZonedDateTime.of(localDate, LocalTime.of(11,3,2), ZoneOffset.UTC); - long timeInMillis = dateTime.getMillis(); + long timeInMillis = dateTime.toInstant().toEpochMilli(); - execute("INSERT INTO %s (a, b, c, d) VALUES (?, '2015-05-21 11:03:02+00', '2015-05-21', '11:03:02')", + execute("INSERT INTO %s (a, b, c, d) VALUES (?, '" + yearMonthDay + " 11:03:02+00', '2015-05-21', '11:03:02')", UUIDGen.getTimeUUID(timeInMillis)); assertRows(execute("SELECT CAST(a AS timestamp), " + "CAST(b AS timestamp), " + "CAST(c AS timestamp) FROM %s"), - row(new Date(dateTime.getMillis()), new Date(dateTime.getMillis()), new Date(date.getMillis()))); + row(Date.from(dateTime.toInstant()), Date.from(dateTime.toInstant()), Date.from(date.toInstant()))); - int timeInMillisToDay = SimpleDateSerializer.timeInMillisToDay(date.getMillis()); + int timeInMillisToDay = SimpleDateSerializer.timeInMillisToDay(date.toInstant().toEpochMilli()); assertRows(execute("SELECT CAST(a AS date), " + "CAST(b AS date), " + "CAST(c AS date) FROM %s"), @@ -244,7 +245,7 @@ public class CastFctsTest extends CQLTester assertRows(execute("SELECT CAST(b AS text), " + "CAST(c AS text), " + "CAST(d AS text) FROM %s"), - row("2015-05-21T11:03:02.000Z", "2015-05-21", "11:03:02.000000000")); + row(yearMonthDay + "T11:03:02.000Z", yearMonthDay, "11:03:02.000000000")); } @Test diff --git a/test/unit/org/apache/cassandra/cql3/functions/TimeFctsTest.java b/test/unit/org/apache/cassandra/cql3/functions/TimeFctsTest.java index b7b99b4169..b0a4bb98ea 100644 --- a/test/unit/org/apache/cassandra/cql3/functions/TimeFctsTest.java +++ b/test/unit/org/apache/cassandra/cql3/functions/TimeFctsTest.java @@ -18,7 +18,10 @@ package org.apache.cassandra.cql3.functions; import java.nio.ByteBuffer; -import java.util.Arrays; +import java.time.*; +import java.time.format.DateTimeFormatter; +import java.util.Collections; +import java.util.Date; import java.util.List; import org.junit.Test; @@ -30,9 +33,6 @@ import org.apache.cassandra.db.marshal.TimestampType; import org.apache.cassandra.transport.ProtocolVersion; import org.apache.cassandra.utils.ByteBufferUtil; import org.apache.cassandra.utils.UUIDGen; -import org.joda.time.DateTime; -import org.joda.time.DateTimeZone; -import org.joda.time.format.DateTimeFormat; import static org.apache.cassandra.cql3.functions.TimeFcts.*; import static org.junit.Assert.assertEquals; @@ -40,15 +40,21 @@ import static org.junit.Assert.assertNull; public class TimeFctsTest { + private static final LocalDate LOCAL_DATE = LocalDate.of(2019, 8, 3); + + private static final ZonedDateTime DATE = LOCAL_DATE.atStartOfDay(ZoneOffset.UTC); + private static final LocalTime LOCAL_TIME = LocalTime.of(11, 3, 2); + private static final ZonedDateTime DATE_TIME = + ZonedDateTime.of(LOCAL_DATE, LOCAL_TIME, ZoneOffset.UTC); + private static final String DATE_STRING = DATE.format(DateTimeFormatter.ISO_LOCAL_DATE); + private static final String DATE_TIME_STRING = + DATE_STRING + " " + LOCAL_TIME.format(DateTimeFormatter.ISO_LOCAL_TIME); + @Test public void testMinTimeUuid() { - DateTime dateTime = DateTimeFormat.forPattern("yyyy-MM-dd hh:mm:ss") - .withZone(DateTimeZone.UTC) - .parseDateTime("2015-05-21 11:03:02"); - - long timeInMillis = dateTime.getMillis(); - ByteBuffer input = TimestampType.instance.fromString("2015-05-21 11:03:02+00"); + long timeInMillis = DATE_TIME.toInstant().toEpochMilli(); + ByteBuffer input = TimestampType.instance.fromString(DATE_TIME_STRING + "+00"); ByteBuffer output = executeFunction(TimeFcts.minTimeuuidFct, input); assertEquals(UUIDGen.minTimeUUID(timeInMillis), TimeUUIDType.instance.compose(output)); } @@ -56,12 +62,8 @@ public class TimeFctsTest @Test public void testMaxTimeUuid() { - DateTime dateTime = DateTimeFormat.forPattern("yyyy-MM-dd hh:mm:ss") - .withZone(DateTimeZone.UTC) - .parseDateTime("2015-05-21 11:03:02"); - - long timeInMillis = dateTime.getMillis(); - ByteBuffer input = TimestampType.instance.fromString("2015-05-21 11:03:02+00"); + long timeInMillis = DATE_TIME.toInstant().toEpochMilli(); + ByteBuffer input = TimestampType.instance.fromString(DATE_TIME_STRING + "+00"); ByteBuffer output = executeFunction(TimeFcts.maxTimeuuidFct, input); assertEquals(UUIDGen.maxTimeUUID(timeInMillis), TimeUUIDType.instance.compose(output)); } @@ -69,37 +71,26 @@ public class TimeFctsTest @Test public void testDateOf() { - DateTime dateTime = DateTimeFormat.forPattern("yyyy-MM-dd hh:mm:ss") - .withZone(DateTimeZone.UTC) - .parseDateTime("2015-05-21 11:03:02"); - long timeInMillis = dateTime.getMillis(); + long timeInMillis = DATE_TIME.toInstant().toEpochMilli(); ByteBuffer input = ByteBuffer.wrap(UUIDGen.getTimeUUIDBytes(timeInMillis, 0)); ByteBuffer output = executeFunction(TimeFcts.dateOfFct, input); - assertEquals(dateTime.toDate(), TimestampType.instance.compose(output)); + assertEquals(Date.from(DATE_TIME.toInstant()), TimestampType.instance.compose(output)); } @Test public void testTimeUuidToTimestamp() { - DateTime dateTime = DateTimeFormat.forPattern("yyyy-MM-dd hh:mm:ss") - .withZone(DateTimeZone.UTC) - .parseDateTime("2015-05-21 11:03:02"); - - long timeInMillis = dateTime.getMillis(); + long timeInMillis = DATE_TIME.toInstant().toEpochMilli(); ByteBuffer input = ByteBuffer.wrap(UUIDGen.getTimeUUIDBytes(timeInMillis, 0)); ByteBuffer output = executeFunction(toTimestamp(TimeUUIDType.instance), input); - assertEquals(dateTime.toDate(), TimestampType.instance.compose(output)); + assertEquals(Date.from(DATE_TIME.toInstant()), TimestampType.instance.compose(output)); } @Test public void testUnixTimestampOfFct() { - DateTime dateTime = DateTimeFormat.forPattern("yyyy-MM-dd hh:mm:ss") - .withZone(DateTimeZone.UTC) - .parseDateTime("2015-05-21 11:03:02"); - - long timeInMillis = dateTime.getMillis(); + long timeInMillis = DATE_TIME.toInstant().toEpochMilli(); ByteBuffer input = ByteBuffer.wrap(UUIDGen.getTimeUUIDBytes(timeInMillis, 0)); ByteBuffer output = executeFunction(TimeFcts.unixTimestampOfFct, input); assertEquals(timeInMillis, LongType.instance.compose(output).longValue()); @@ -108,11 +99,7 @@ public class TimeFctsTest @Test public void testTimeUuidToUnixTimestamp() { - DateTime dateTime = DateTimeFormat.forPattern("yyyy-MM-dd hh:mm:ss") - .withZone(DateTimeZone.UTC) - .parseDateTime("2015-05-21 11:03:02"); - - long timeInMillis = dateTime.getMillis(); + long timeInMillis = DATE_TIME.toInstant().toEpochMilli(); ByteBuffer input = ByteBuffer.wrap(UUIDGen.getTimeUUIDBytes(timeInMillis, 0)); ByteBuffer output = executeFunction(toUnixTimestamp(TimeUUIDType.instance), input); assertEquals(timeInMillis, LongType.instance.compose(output).longValue()); @@ -121,18 +108,11 @@ public class TimeFctsTest @Test public void testTimeUuidToDate() { - DateTime dateTime = DateTimeFormat.forPattern("yyyy-MM-dd hh:mm:ss") - .withZone(DateTimeZone.UTC) - .parseDateTime("2015-05-21 11:03:02"); - - long timeInMillis = dateTime.getMillis(); + long timeInMillis = DATE_TIME.toInstant().toEpochMilli(); ByteBuffer input = ByteBuffer.wrap(UUIDGen.getTimeUUIDBytes(timeInMillis, 0)); ByteBuffer output = executeFunction(toDate(TimeUUIDType.instance), input); - long expectedTime = DateTimeFormat.forPattern("yyyy-MM-dd") - .withZone(DateTimeZone.UTC) - .parseDateTime("2015-05-21") - .getMillis(); + long expectedTime = DATE.toInstant().toEpochMilli(); assertEquals(expectedTime, SimpleDateType.instance.toTimeInMillis(output)); } @@ -140,37 +120,25 @@ public class TimeFctsTest @Test public void testDateToTimestamp() { - DateTime dateTime = DateTimeFormat.forPattern("yyyy-MM-dd") - .withZone(DateTimeZone.UTC) - .parseDateTime("2015-05-21"); - - ByteBuffer input = SimpleDateType.instance.fromString("2015-05-21"); + ByteBuffer input = SimpleDateType.instance.fromString(DATE_STRING); ByteBuffer output = executeFunction(toTimestamp(SimpleDateType.instance), input); - assertEquals(dateTime.toDate(), TimestampType.instance.compose(output)); + assertEquals(Date.from(DATE.toInstant()), TimestampType.instance.compose(output)); } @Test public void testDateToUnixTimestamp() { - DateTime dateTime = DateTimeFormat.forPattern("yyyy-MM-dd") - .withZone(DateTimeZone.UTC) - .parseDateTime("2015-05-21"); - - ByteBuffer input = SimpleDateType.instance.fromString("2015-05-21"); + ByteBuffer input = SimpleDateType.instance.fromString(DATE_STRING); ByteBuffer output = executeFunction(toUnixTimestamp(SimpleDateType.instance), input); - assertEquals(dateTime.getMillis(), LongType.instance.compose(output).longValue()); + assertEquals(DATE.toInstant().toEpochMilli(), LongType.instance.compose(output).longValue()); } @Test public void testTimestampToDate() { - DateTime dateTime = DateTimeFormat.forPattern("yyyy-MM-dd") - .withZone(DateTimeZone.UTC) - .parseDateTime("2015-05-21"); - - ByteBuffer input = TimestampType.instance.fromString("2015-05-21 11:03:02+00"); + ByteBuffer input = TimestampType.instance.fromString(DATE_TIME_STRING + "+00"); ByteBuffer output = executeFunction(toDate(TimestampType.instance), input); - assertEquals(dateTime.getMillis(), SimpleDateType.instance.toTimeInMillis(output)); + assertEquals(DATE.toInstant().toEpochMilli(), SimpleDateType.instance.toTimeInMillis(output)); } @Test @@ -183,13 +151,9 @@ public class TimeFctsTest @Test public void testTimestampToUnixTimestamp() { - DateTime dateTime = DateTimeFormat.forPattern("yyyy-MM-dd hh:mm:ss") - .withZone(DateTimeZone.UTC) - .parseDateTime("2015-05-21 11:03:02"); - - ByteBuffer input = TimestampType.instance.decompose(dateTime.toDate()); + ByteBuffer input = TimestampType.instance.decompose(Date.from(DATE_TIME.toInstant())); ByteBuffer output = executeFunction(toUnixTimestamp(TimestampType.instance), input); - assertEquals(dateTime.getMillis(), LongType.instance.compose(output).longValue()); + assertEquals(DATE_TIME.toInstant().toEpochMilli(), LongType.instance.compose(output).longValue()); } @Test @@ -201,7 +165,7 @@ public class TimeFctsTest private static ByteBuffer executeFunction(Function function, ByteBuffer input) { - List params = Arrays.asList(input); + List params = Collections.singletonList(input); return ((ScalarFunction) function).execute(ProtocolVersion.CURRENT, params); } } diff --git a/test/unit/org/apache/cassandra/serializers/SimpleDateSerializerTest.java b/test/unit/org/apache/cassandra/serializers/SimpleDateSerializerTest.java index e051357621..9c1ef886f9 100644 --- a/test/unit/org/apache/cassandra/serializers/SimpleDateSerializerTest.java +++ b/test/unit/org/apache/cassandra/serializers/SimpleDateSerializerTest.java @@ -24,11 +24,12 @@ import org.junit.Test; import java.nio.ByteBuffer; import java.sql.Timestamp; import java.text.SimpleDateFormat; +import java.time.temporal.ChronoUnit; import java.util.*; public class SimpleDateSerializerTest { - private static final long millisPerDay = 1000 * 60 * 60 * 24; + private static final long millisPerDay = ChronoUnit.DAYS.getDuration().toMillis(); private String dates[] = new String[] { @@ -38,7 +39,7 @@ public class SimpleDateSerializerTest "-0001-01-02", "-5877521-01-02", "2014-01-01", - "5881580-01-10", + "+5881580-01-10", // See java.time.format.SignStyle.EXCEEDS_PAD "1920-12-01", "1582-10-19" };