diff --git a/pom.xml b/pom.xml
index a1c317b..8e46a66 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,7 +4,7 @@
4.0.0
com.instaclustr
- ic-sstable-tools-4.1.3
+ ic-sstable-tools-5.0.0
1.0.0
Instaclustr SSTable Tools
@@ -21,7 +21,7 @@
3.1.1
3.1.1
3.8.1
- 2.2.4
+ 4.9.10
Various <support@instaclustr.com>
1.8
@@ -34,9 +34,9 @@
${project.build.directory}
UTF-8
- 1.8
- 1.8
- 8
+ 11
+ 11
+ 11
2018
@@ -83,12 +83,12 @@
info.picocli
picocli
- 4.5.2
+ 4.7.1
org.apache.cassandra
cassandra-all
- 4.1.3
+ 5.0-beta1
provided
@@ -109,7 +109,7 @@
-
+
@@ -147,13 +147,21 @@
${maven.git.command.plugin.version}
+ get-the-git-infos
revision
+ initialize
- ${project.basedir}/.git
+ true
+ ${project.build.outputDirectory}/git.properties
+
+ ^git.build.(time|version)$
+ ^git.commit.id.(abbrev|full)$
+
+ full
diff --git a/src/main/java/com/instaclustr/sstabletools/ColumnFamilyProxy.java b/src/main/java/com/instaclustr/sstabletools/ColumnFamilyProxy.java
index cfc976b..370e9c2 100644
--- a/src/main/java/com/instaclustr/sstabletools/ColumnFamilyProxy.java
+++ b/src/main/java/com/instaclustr/sstabletools/ColumnFamilyProxy.java
@@ -1,6 +1,5 @@
package com.instaclustr.sstabletools;
-import com.google.common.util.concurrent.RateLimiter;
import org.apache.cassandra.db.DecoratedKey;
import java.util.Collection;
@@ -39,13 +38,6 @@ public interface ColumnFamilyProxy extends AutoCloseable {
*/
String formatKey(DecoratedKey key);
- /**
- * Is the column family using Date Tiered compaction strategy.
- *
- * @return True if column family is using Date Tiered compaction strategy.
- */
- boolean isDTCS();
-
/**
* Is the column family using Time Window compaction strategy.
*
diff --git a/src/main/java/com/instaclustr/sstabletools/PurgeStatisticsCollector.java b/src/main/java/com/instaclustr/sstabletools/PurgeStatisticsCollector.java
index 6f37069..f4c556d 100644
--- a/src/main/java/com/instaclustr/sstabletools/PurgeStatisticsCollector.java
+++ b/src/main/java/com/instaclustr/sstabletools/PurgeStatisticsCollector.java
@@ -29,7 +29,7 @@ public class PurgeStatisticsCollector implements Runnable {
@Option(names = {"-t"}, description = "Snapshot name", arity = "1")
public String snapshotName;
- @Option(names = {"-f"}, description = "Filter to sstables (comma separated", defaultValue = "")
+ @Option(names = {"-f"}, description = "Filter to sstables (comma separated)", defaultValue = "")
public String filters;
@Option(names = {"-b"}, description = "Batch mode", arity = "0")
diff --git a/src/main/java/com/instaclustr/sstabletools/SSTableMetadata.java b/src/main/java/com/instaclustr/sstabletools/SSTableMetadata.java
index 0b25444..9abdb75 100644
--- a/src/main/java/com/instaclustr/sstabletools/SSTableMetadata.java
+++ b/src/main/java/com/instaclustr/sstabletools/SSTableMetadata.java
@@ -55,9 +55,9 @@ public int compare(SSTableMetadata o1, SSTableMetadata o2) {
public long maxTimestamp;
- public int minLocalDeletionTime;
+ public long minLocalDeletionTime;
- public int maxLocalDeletionTime;
+ public long maxLocalDeletionTime;
public long fileTimestamp;
diff --git a/src/main/java/com/instaclustr/sstabletools/cassandra/CassandraBackend.java b/src/main/java/com/instaclustr/sstabletools/cassandra/CassandraBackend.java
index a3da7e1..fe1daea 100644
--- a/src/main/java/com/instaclustr/sstabletools/cassandra/CassandraBackend.java
+++ b/src/main/java/com/instaclustr/sstabletools/cassandra/CassandraBackend.java
@@ -3,11 +3,11 @@
import com.instaclustr.sstabletools.CassandraProxy;
import com.instaclustr.sstabletools.ColumnFamilyProxy;
import com.instaclustr.sstabletools.SSTableMetadata;
+import org.apache.cassandra.io.sstable.format.SSTableFormat;
import org.apache.cassandra.schema.TableMetadata;
import org.apache.cassandra.schema.Schema;
import org.apache.cassandra.db.ColumnFamilyStore;
import org.apache.cassandra.db.Keyspace;
-import org.apache.cassandra.db.compaction.DateTieredCompactionStrategy;
import org.apache.cassandra.db.compaction.TimeWindowCompactionStrategy;
import org.apache.cassandra.io.sstable.Component;
import org.apache.cassandra.io.sstable.format.SSTableReader;
@@ -41,7 +41,7 @@ public static CassandraProxy getInstance() {
private CassandraBackend() {}
public List getKeyspaces() {
- return Schema.instance.getNonLocalStrategyKeyspaces()
+ return Schema.instance.distributedKeyspaces()
.stream()
.map(ksmd -> ksmd.name).sorted().collect(Collectors.toList());
}
@@ -92,7 +92,7 @@ public List getSSTableMetadata(String ksName, String cfName) {
List metaData = new ArrayList<>(tables.size());
for (SSTableReader table : tables) {
SSTableMetadata tableMetadata = new SSTableMetadata();
- File dataFile = new File(table.descriptor.filenameFor(Component.DATA));
+ File dataFile = table.descriptor.fileFor(SSTableFormat.Components.DATA).toJavaIOFile();
tableMetadata.filename = dataFile.getName();
tableMetadata.ssTableId = table.descriptor.id;
try {
@@ -129,7 +129,6 @@ public ColumnFamilyProxy getColumnFamily(String ksName, String cfName, String sn
Class> compactionClass = metaData.params.compaction.klass();
return new ColumnFamilyBackend(
metaData.partitionKeyType,
- compactionClass.equals(DateTieredCompactionStrategy.class),
compactionClass.equals(TimeWindowCompactionStrategy.class),
cfStore,
snapshotName,
diff --git a/src/main/java/com/instaclustr/sstabletools/cassandra/ColumnFamilyBackend.java b/src/main/java/com/instaclustr/sstabletools/cassandra/ColumnFamilyBackend.java
index 5c0729a..9d6c169 100644
--- a/src/main/java/com/instaclustr/sstabletools/cassandra/ColumnFamilyBackend.java
+++ b/src/main/java/com/instaclustr/sstabletools/cassandra/ColumnFamilyBackend.java
@@ -3,8 +3,16 @@
import com.instaclustr.sstabletools.*;
import org.apache.cassandra.db.ColumnFamilyStore;
import org.apache.cassandra.db.DecoratedKey;
+import org.apache.cassandra.db.SerializationHeader;
import org.apache.cassandra.db.marshal.AbstractType;
import org.apache.cassandra.io.sstable.Component;
+import org.apache.cassandra.io.sstable.format.SSTableFormat;
+import org.apache.cassandra.io.sstable.format.big.BigFormat;
+import org.apache.cassandra.io.sstable.format.big.BigTableReader;
+import org.apache.cassandra.io.util.FileHandle;
+import org.apache.cassandra.utils.FilterFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.IOException;
@@ -12,21 +20,21 @@
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
+import java.util.Optional;
+import java.util.Set;
/**
* ColumnFamilyProxy using Cassandra 3.5 backend.
*/
public class ColumnFamilyBackend implements ColumnFamilyProxy {
+
+ private static final Logger logger = LoggerFactory.getLogger(ColumnFamilyBackend.class);
+
/**
* Key validator for column family.
*/
private AbstractType> keyValidator;
- /**
- * Is column family using Date Tiered Compaction Strategy.
- */
- private boolean isDTCS;
-
/**
* Is column family using Time Window Compaction Strategy.
*/
@@ -53,13 +61,11 @@ public class ColumnFamilyBackend implements ColumnFamilyProxy {
private Collection sstables;
public ColumnFamilyBackend(AbstractType> keyValidator,
- boolean isDTCS,
boolean isTWCS,
ColumnFamilyStore cfStore,
String snapshotName,
Collection filter) throws IOException {
this.keyValidator = keyValidator;
- this.isDTCS = isDTCS;
this.isTWCS = isTWCS;
this.cfStore = cfStore;
if (snapshotName != null) {
@@ -74,7 +80,7 @@ public ColumnFamilyBackend(AbstractType> keyValidator,
if (filter != null) {
List filteredSSTables = new ArrayList<>(sstables.size());
for (org.apache.cassandra.io.sstable.format.SSTableReader sstable : sstables) {
- File dataFile = new File(sstable.descriptor.filenameFor(Component.DATA));
+ File dataFile = sstable.descriptor.fileFor(SSTableFormat.Components.DATA).toJavaIOFile();;
if (filter.contains(dataFile.getName())) {
filteredSSTables.add(sstable);
}
@@ -88,7 +94,24 @@ public Collection getIndexReaders() {
Collection readers = new ArrayList<>(sstables.size());
for (org.apache.cassandra.io.sstable.format.SSTableReader sstable : sstables) {
try {
- File dataFile = new File(sstable.descriptor.filenameFor(Component.DATA));
+ Set components = sstable.descriptor.discoverComponents();
+
+ Optional maybeIndexComponent = components.stream().filter(c -> c.name.contains("Index")).findFirst();
+ if (!maybeIndexComponent.isPresent()) {
+ continue;
+ }
+
+ org.apache.cassandra.io.util.File indexFile = sstable.descriptor.fileFor(maybeIndexComponent.get());
+ FileHandle indexHandle = new FileHandle.Builder(indexFile).complete();
+
+ BigTableReader reader = new BigTableReader.Builder(sstable.descriptor)
+ .setComponents(components)
+ .setFilter(FilterFactory.AlwaysPresent)
+ .setSerializationHeader(SerializationHeader.makeWithoutStats(cfStore.metadata()))
+ .setIndexFile(indexHandle)
+ .build(this.cfStore, false, false);
+
+ File dataFile = sstable.descriptor.fileFor(SSTableFormat.Components.DATA).toJavaIOFile();
readers.add(new IndexReader(
new SSTableStatistics(
sstable.descriptor.id,
@@ -97,12 +120,12 @@ public Collection getIndexReaders() {
sstable.getMinTimestamp(),
sstable.getMaxTimestamp(),
sstable.getSSTableLevel()),
- sstable.openIndexReader(),
+ reader.getIndexFile().createReader(),
sstable.descriptor.version,
sstable.getPartitioner()
));
} catch (Throwable t) {
-
+ logger.error("Error opening index readers", t);
}
}
return readers;
@@ -113,7 +136,7 @@ public Collection getDataReaders() {
Collection readers = new ArrayList<>(sstables.size());
for (org.apache.cassandra.io.sstable.format.SSTableReader sstable : sstables) {
try {
- File dataFile = new File(sstable.descriptor.filenameFor(Component.DATA));
+ File dataFile = sstable.descriptor.fileFor(SSTableFormat.Components.DATA).toJavaIOFile();
readers.add(new DataReader(
new SSTableStatistics(
sstable.descriptor.id,
@@ -125,7 +148,9 @@ public Collection getDataReaders() {
sstable.getScanner(),
Util.NOW_SECONDS - sstable.metadata().params.gcGraceSeconds
));
- } catch (Throwable t) {}
+ } catch (Throwable t) {
+ logger.error("Error while getting data readers", t);
+ }
}
return readers;
}
@@ -140,11 +165,6 @@ public String formatKey(DecoratedKey key) {
return keyValidator.getString(key.getKey());
}
- @Override
- public boolean isDTCS() {
- return isDTCS;
- }
-
@Override
public boolean isTWCS() {
return isTWCS;
diff --git a/src/main/java/com/instaclustr/sstabletools/cassandra/IndexReader.java b/src/main/java/com/instaclustr/sstabletools/cassandra/IndexReader.java
index b88c502..3ebfd0d 100644
--- a/src/main/java/com/instaclustr/sstabletools/cassandra/IndexReader.java
+++ b/src/main/java/com/instaclustr/sstabletools/cassandra/IndexReader.java
@@ -67,7 +67,7 @@ public IndexReader(SSTableStatistics tableStats, RandomAccessReader reader, Vers
* @throws IOException
*/
private void skipData() throws IOException {
- int size = version.getVersion().compareTo("ma") >= 0 ? (int) reader.readUnsignedVInt() : reader.readInt();
+ int size = version.version.compareTo("ma") >= 0 ? (int) reader.readUnsignedVInt() : reader.readInt();
if (size > 0) {
reader.skipBytesFully(size);
}
@@ -81,14 +81,14 @@ public boolean next() {
try {
if (nextKey == null) {
nextKey = ByteBufferUtil.readWithShortLength(reader);
- nextPosition = version.getVersion().compareTo("ma") > 0 ? reader.readUnsignedVInt() : reader.readLong();
+ nextPosition = version.version.compareTo("ma") > 0 ? reader.readUnsignedVInt() : reader.readLong();
skipData();
}
partitionStats = new PartitionStatistics(partitioner.decorateKey(nextKey));
long position = nextPosition;
if (!reader.isEOF()) {
nextKey = ByteBufferUtil.readWithShortLength(reader);
- nextPosition = version.getVersion().compareTo("ma") > 0 ? reader.readUnsignedVInt() : reader.readLong();
+ nextPosition = version.version.compareTo("ma") > 0 ? reader.readUnsignedVInt() : reader.readLong();
skipData();
partitionStats.size = nextPosition - position;
} else {
diff --git a/src/main/java/com/instaclustr/sstabletools/cli/CLI.java b/src/main/java/com/instaclustr/sstabletools/cli/CLI.java
index ac65d53..a89f593 100644
--- a/src/main/java/com/instaclustr/sstabletools/cli/CLI.java
+++ b/src/main/java/com/instaclustr/sstabletools/cli/CLI.java
@@ -1,7 +1,5 @@
package com.instaclustr.sstabletools.cli;
-import java.io.PrintWriter;
-
import com.instaclustr.sstabletools.PurgeStatisticsCollector;
import picocli.CommandLine;
import picocli.CommandLine.Command;
@@ -9,18 +7,18 @@
import picocli.CommandLine.Spec;
@Command(
- mixinStandardHelpOptions = true,
- subcommands = {
- ColumnFamilyStatisticsCollector.class,
- PartitionSizeStatisticsCollector.class,
- PurgeStatisticsCollector.class,
- SSTableMetadataCollector.class,
- SummaryCollector.class,
- },
- versionProvider = CLI.class,
- usageHelpWidth = 128
+ mixinStandardHelpOptions = true,
+ subcommands = {
+ ColumnFamilyStatisticsCollector.class,
+ PartitionSizeStatisticsCollector.class,
+ PurgeStatisticsCollector.class,
+ SSTableMetadataCollector.class,
+ SummaryCollector.class,
+ },
+ versionProvider = CLI.class,
+ usageHelpWidth = 128
)
-public class CLI extends JarManifestVersionProvider implements Runnable {
+public class CLI extends CLIApplication implements Runnable {
@Spec
private CommandSpec spec;
@@ -29,16 +27,12 @@ public static void main(String[] args) {
main(args, true);
}
+ public static void mainWithoutExit(String[] args) {
+ main(args, false);
+ }
+
public static void main(String[] args, boolean exit) {
- int exitCode = new CommandLine(new CLI())
- .setErr(new PrintWriter(System.err))
- .setOut(new PrintWriter(System.err))
- .setColorScheme(new CommandLine.Help.ColorScheme.Builder().ansi(CommandLine.Help.Ansi.ON).build())
- .setExecutionExceptionHandler((ex, cmdLine, parseResult) -> {
- ex.printStackTrace();
- return 1;
- })
- .execute(args);
+ int exitCode = execute(new CommandLine(new CLI()), args);
if (exit) {
System.exit(exitCode);
@@ -46,13 +40,13 @@ public static void main(String[] args, boolean exit) {
}
@Override
- public String getImplementationTitle() {
- return "ic-sstable-tools";
+ public void run() {
+ throw new CommandLine.ParameterException(spec.commandLine(), "Missing required sub-command.");
}
@Override
- public void run() {
- throw new CommandLine.ParameterException(spec.commandLine(), "Missing required sub-command.");
+ public String title() {
+ return "ic-sstable-tools";
}
}
diff --git a/src/main/java/com/instaclustr/sstabletools/cli/CLIApplication.java b/src/main/java/com/instaclustr/sstabletools/cli/CLIApplication.java
new file mode 100644
index 0000000..3265246
--- /dev/null
+++ b/src/main/java/com/instaclustr/sstabletools/cli/CLIApplication.java
@@ -0,0 +1,36 @@
+package com.instaclustr.sstabletools.cli;
+
+import picocli.CommandLine;
+
+import java.io.PrintWriter;
+import java.util.concurrent.Callable;
+
+public abstract class CLIApplication implements CommandLine.IVersionProvider {
+
+ public static int execute(final Runnable runnable, String... args) {
+ return execute(new CommandLine(runnable), args);
+ }
+
+ public static int execute(final Callable callable, String... args) {
+ return execute(new CommandLine(callable), args);
+ }
+
+ public static int execute(CommandLine commandLine, String... args) {
+ return commandLine
+ .setErr(new PrintWriter(System.err, true))
+ .setOut(new PrintWriter(System.out, true))
+ .setColorScheme(new CommandLine.Help.ColorScheme.Builder().ansi(CommandLine.Help.Ansi.ON).build())
+ .setExecutionExceptionHandler((ex, cmdLine, parseResult) -> {
+ ex.printStackTrace();
+ return 1;
+ })
+ .execute(args);
+ }
+
+ public abstract String title();
+
+ @Override
+ public String[] getVersion() throws Exception {
+ return VersionParser.parse(title());
+ }
+}
diff --git a/src/main/java/com/instaclustr/sstabletools/cli/ColumnFamilyStatisticsCollector.java b/src/main/java/com/instaclustr/sstabletools/cli/ColumnFamilyStatisticsCollector.java
index 6c09f59..1a70dfe 100644
--- a/src/main/java/com/instaclustr/sstabletools/cli/ColumnFamilyStatisticsCollector.java
+++ b/src/main/java/com/instaclustr/sstabletools/cli/ColumnFamilyStatisticsCollector.java
@@ -41,7 +41,7 @@ public class ColumnFamilyStatisticsCollector implements Runnable {
@Option(names = {"-t"}, description = "Snapshot name", arity = "1")
public String snapshotName;
- @Option(names = {"-f"}, description = "Filter to sstables (comma separated", defaultValue = "")
+ @Option(names = {"-f"}, description = "Filter to sstables (comma separated)", defaultValue = "")
public String filters;
@Option(names = {"-b"}, description = "Batch mode", arity = "0")
@@ -323,9 +323,6 @@ public void run() {
List sstableStats = partitionReader.getSSTableStatistics();
Comparator comparator = SSTableStatistics.LIVENESS_COMPARATOR;
- if (cfProxy.isDTCS()) {
- comparator = SSTableStatistics.DTCS_COMPARATOR;
- }
if (cfProxy.isTWCS()) {
comparator = SSTableStatistics.TWCS_COMPARATOR;
}
diff --git a/src/main/java/com/instaclustr/sstabletools/cli/JarManifestVersionProvider.java b/src/main/java/com/instaclustr/sstabletools/cli/JarManifestVersionProvider.java
deleted file mode 100644
index a67ce7c..0000000
--- a/src/main/java/com/instaclustr/sstabletools/cli/JarManifestVersionProvider.java
+++ /dev/null
@@ -1,59 +0,0 @@
-package com.instaclustr.sstabletools.cli;
-
-import java.io.IOException;
-import java.net.URL;
-import java.util.Enumeration;
-import java.util.Optional;
-import java.util.jar.Attributes;
-import java.util.jar.Manifest;
-
-import com.google.common.base.Joiner;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import picocli.CommandLine;
-import picocli.CommandLine.IVersionProvider;
-
-public abstract class JarManifestVersionProvider implements IVersionProvider {
-
- @Override
- public String[] getVersion() throws IOException {
- final Enumeration resources = CommandLine.class.getClassLoader().getResources("META-INF/MANIFEST.MF");
-
- Optional implementationVersion = Optional.empty();
- Optional buildTime = Optional.empty();
- Optional gitCommit = Optional.empty();
-
- while (resources.hasMoreElements()) {
- final URL url = resources.nextElement();
-
- final Manifest manifest = new Manifest(url.openStream());
- final Attributes attributes = manifest.getMainAttributes();
-
- if (isApplicableManifest(attributes)) {
- implementationVersion = Optional.ofNullable(attributes.getValue(Attributes.Name.IMPLEMENTATION_VERSION));
- buildTime = Optional.ofNullable(attributes.getValue("Build-Time"));
- gitCommit = Optional.ofNullable(attributes.getValue("Git-Commit"));
-
- break;
- }
- }
-
- return new String[]{
- String.format("%s %s", getImplementationTitle(), implementationVersion.orElse("development build")),
- String.format("Build time: %s", buildTime.orElse("unknown")),
- String.format("Git commit: %s", gitCommit.orElse("unknown")),
- };
- }
-
- private boolean isApplicableManifest(Attributes attributes) {
- return getImplementationTitle().equals(attributes.getValue(Attributes.Name.IMPLEMENTATION_TITLE));
- }
-
- public abstract String getImplementationTitle();
-
- public static void logCommandVersionInformation(final CommandLine.Model.CommandSpec commandSpec) {
- final Logger logger = LoggerFactory.getLogger(commandSpec.userObject().getClass());
- logger.info("{} version: {}", commandSpec.name(), Joiner.on(", ").join(commandSpec.version()));
- }
-}
-
diff --git a/src/main/java/com/instaclustr/sstabletools/cli/PartitionSizeStatisticsCollector.java b/src/main/java/com/instaclustr/sstabletools/cli/PartitionSizeStatisticsCollector.java
index db6d4d0..8b9bb8b 100644
--- a/src/main/java/com/instaclustr/sstabletools/cli/PartitionSizeStatisticsCollector.java
+++ b/src/main/java/com/instaclustr/sstabletools/cli/PartitionSizeStatisticsCollector.java
@@ -38,7 +38,7 @@ public class PartitionSizeStatisticsCollector implements Runnable {
@Option(names = {"-t"}, description = "Snapshot name", arity = "1")
public String snapshotName;
- @Option(names = {"-f"}, description = "Filter to sstables (comma separated", defaultValue = "")
+ @Option(names = {"-f"}, description = "Filter to sstables (comma separated)", defaultValue = "")
public String filters;
@Option(names = {"-b"}, description = "Batch mode", arity = "0")
@@ -166,9 +166,6 @@ public void run() {
);
List sstableStats = partitionReader.getSSTableStatistics();
Comparator comparator = SSTableStatistics.LIVENESS_COMPARATOR;
- if (cfProxy.isDTCS()) {
- comparator = SSTableStatistics.DTCS_COMPARATOR;
- }
if (cfProxy.isTWCS()) {
comparator = SSTableStatistics.TWCS_COMPARATOR;
}
diff --git a/src/main/java/com/instaclustr/sstabletools/cli/SSTableMetadataCollector.java b/src/main/java/com/instaclustr/sstabletools/cli/SSTableMetadataCollector.java
index 4b900f0..96e9820 100644
--- a/src/main/java/com/instaclustr/sstabletools/cli/SSTableMetadataCollector.java
+++ b/src/main/java/com/instaclustr/sstabletools/cli/SSTableMetadataCollector.java
@@ -10,7 +10,6 @@
import com.instaclustr.sstabletools.TableBuilder;
import com.instaclustr.sstabletools.Util;
import com.instaclustr.sstabletools.cassandra.CassandraBackend;
-import org.apache.cassandra.db.compaction.DateTieredCompactionStrategy;
import org.apache.cassandra.db.compaction.LeveledCompactionStrategy;
import org.apache.cassandra.db.compaction.TimeWindowCompactionStrategy;
import picocli.CommandLine.Command;
@@ -60,9 +59,6 @@ public void run() {
List metadataCollection = proxy.getSSTableMetadata(ksName, cfName);
Class> compactionClass = proxy.getCompactionClass(ksName, cfName);
Comparator comparator = SSTableMetadata.GENERATION_COMPARATOR;
- if (compactionClass.equals(DateTieredCompactionStrategy.class)) {
- comparator = SSTableMetadata.DTCS_COMPARATOR;
- }
if (compactionClass.equals(TimeWindowCompactionStrategy.class)) {
comparator = SSTableMetadata.TWCS_COMPARATOR;
}
diff --git a/src/main/java/com/instaclustr/sstabletools/cli/VersionParser.java b/src/main/java/com/instaclustr/sstabletools/cli/VersionParser.java
new file mode 100644
index 0000000..d517107
--- /dev/null
+++ b/src/main/java/com/instaclustr/sstabletools/cli/VersionParser.java
@@ -0,0 +1,40 @@
+package com.instaclustr.sstabletools.cli;
+
+import picocli.CommandLine;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.Enumeration;
+import java.util.Optional;
+import java.util.Properties;
+
+public class VersionParser {
+ public static String[] parse(String title) throws IOException
+ {
+ Enumeration resources = CommandLine.class.getClassLoader().getResources("git.properties");
+
+ Optional implementationVersion = Optional.empty();
+ Optional buildTime = Optional.empty();
+ Optional gitCommit = Optional.empty();
+
+ while (resources.hasMoreElements()) {
+ final URL url = resources.nextElement();
+
+ Properties properties = new Properties();
+ properties.load(url.openStream());
+
+ if (properties.getProperty("git.build.time") != null) {
+ implementationVersion = Optional.ofNullable(properties.getProperty("git.build.version"));
+ buildTime = Optional.ofNullable(properties.getProperty("git.build.time"));
+ gitCommit = Optional.ofNullable(properties.getProperty("git.commit.id.full"));
+ }
+ }
+
+ return new String[]{
+ String.format("%s %s", title, implementationVersion.orElse("development build")),
+ String.format("Build time: %s", buildTime.orElse("unknown")),
+ String.format("Git commit: %s", gitCommit.orElse("unknown")),
+ };
+ }
+
+}