Convert app module to Java (#488)
* app.Program: convert to Java * app.Main: convert to Java * app: remove scala dependencies * parent: remove scala dependencies
This commit is contained in:
parent
783402f745
commit
ee5a831e81
8 changed files with 112 additions and 190 deletions
10
app/pom.xml
10
app/pom.xml
|
@ -45,20 +45,10 @@
|
|||
<groupId>net.kemitix.thorp</groupId>
|
||||
<artifactId>thorp-uishell</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- scala -->
|
||||
<dependency>
|
||||
<groupId>org.scala-lang</groupId>
|
||||
<artifactId>scala-library</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>net.alchim31.maven</groupId>
|
||||
<artifactId>scala-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
|
|
10
app/src/main/java/net/kemitix/thorp/Main.java
Normal file
10
app/src/main/java/net/kemitix/thorp/Main.java
Normal file
|
@ -0,0 +1,10 @@
|
|||
package net.kemitix.thorp;
|
||||
|
||||
public class Main {
|
||||
|
||||
public static void main(String[] args) {
|
||||
Program.run(args);
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
}
|
100
app/src/main/java/net/kemitix/thorp/Program.java
Normal file
100
app/src/main/java/net/kemitix/thorp/Program.java
Normal file
|
@ -0,0 +1,100 @@
|
|||
package net.kemitix.thorp;
|
||||
|
||||
import net.kemitix.thorp.cli.CliArgs;
|
||||
import net.kemitix.thorp.config.*;
|
||||
import net.kemitix.thorp.console.Console;
|
||||
import net.kemitix.thorp.domain.Counters;
|
||||
import net.kemitix.thorp.domain.RemoteObjects;
|
||||
import net.kemitix.thorp.domain.StorageEvent;
|
||||
import net.kemitix.thorp.domain.Terminal;
|
||||
import net.kemitix.thorp.domain.channel.Channel;
|
||||
import net.kemitix.thorp.domain.channel.Sink;
|
||||
import net.kemitix.thorp.lib.Archive;
|
||||
import net.kemitix.thorp.lib.LocalFileSystem;
|
||||
import net.kemitix.thorp.lib.UnversionedMirrorArchive;
|
||||
import net.kemitix.thorp.storage.Storage;
|
||||
import net.kemitix.thorp.uishell.UIEvent;
|
||||
import net.kemitix.thorp.uishell.UIShell;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
public interface Program {
|
||||
|
||||
String version = "1.1.0-SNAPSHOT";
|
||||
String versionLabel = String.format("%sThrop v%s%s",
|
||||
Terminal.white, version, Terminal.reset);
|
||||
|
||||
static void run(String[] args) {
|
||||
try {
|
||||
ConfigOptions configOptions = CliArgs.parse(args);
|
||||
Configuration configuration = ConfigurationBuilder.buildConfig(configOptions);
|
||||
Console.putStrLn(versionLabel);
|
||||
if (!ConfigQuery.showVersion(configOptions)) {
|
||||
executeWithUi(configuration);
|
||||
}
|
||||
} catch (ConfigValidationException e) {
|
||||
Console.putStrLn(String.format(
|
||||
"Configuration error: %s", e.getErrors()));
|
||||
} catch (IOException e) {
|
||||
Console.putStrLn(String.format(
|
||||
"Error loading configuration: %s", e.getMessage()));
|
||||
} catch (InterruptedException e) {
|
||||
Console.putStrLn(String.format(
|
||||
"Program interrupted: %s", e.getMessage()));
|
||||
}
|
||||
}
|
||||
|
||||
static void executeWithUi(Configuration configuration) throws InterruptedException {
|
||||
Channel
|
||||
.<UIEvent>create("ui")
|
||||
.addListener(UIShell.listener(configuration))
|
||||
.run(uiSink -> execute(configuration, uiSink))
|
||||
.start()
|
||||
.waitForShutdown();
|
||||
}
|
||||
|
||||
static void execute(Configuration configuration, Sink<UIEvent> uiSink) {
|
||||
try {
|
||||
uiSink.accept(UIEvent.showValidConfig());
|
||||
RemoteObjects remoteObjects = Storage.getInstance().list(configuration.bucket, configuration.prefix);
|
||||
Archive archive = UnversionedMirrorArchive.create();
|
||||
List<StorageEvent> storageEvents = new ArrayList<>();
|
||||
storageEvents.addAll(LocalFileSystem.scanCopyUpload(configuration, uiSink, remoteObjects, archive));
|
||||
storageEvents.addAll(LocalFileSystem.scanDelete(configuration, uiSink, remoteObjects, archive));
|
||||
Counters counters = countEvents(storageEvents);
|
||||
uiSink.accept(UIEvent.showSummary(counters));
|
||||
} catch (InterruptedException e) {
|
||||
// do nothing
|
||||
} finally {
|
||||
Storage.getInstance().shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
static Counters countEvents(List<StorageEvent> storageEvents) {
|
||||
AtomicInteger uploads = new AtomicInteger();
|
||||
AtomicInteger copies = new AtomicInteger();
|
||||
AtomicInteger deletes = new AtomicInteger();
|
||||
AtomicInteger errors = new AtomicInteger();
|
||||
storageEvents.forEach(storageEvent -> {
|
||||
if (storageEvent instanceof StorageEvent.UploadEvent) {
|
||||
uploads.incrementAndGet();
|
||||
} else if (storageEvent instanceof StorageEvent.CopyEvent) {
|
||||
copies.incrementAndGet();
|
||||
} else if (storageEvent instanceof StorageEvent.DeleteEvent) {
|
||||
deletes.incrementAndGet();
|
||||
} else if (storageEvent instanceof StorageEvent.ErrorEvent) {
|
||||
errors.incrementAndGet();
|
||||
}
|
||||
});
|
||||
return Counters.empty
|
||||
.withUploaded(uploads.get())
|
||||
.withCopied(copies.get())
|
||||
.withDeleted(deletes.get())
|
||||
.withErrors(errors.get());
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
package net.kemitix.thorp
|
||||
|
||||
object Main {
|
||||
|
||||
def main(args: Array[String]): Unit = {
|
||||
Program.run(args.toList)
|
||||
System.exit(0)
|
||||
}
|
||||
|
||||
}
|
|
@ -1,106 +0,0 @@
|
|||
package net.kemitix.thorp
|
||||
|
||||
import net.kemitix.thorp.cli.CliArgs
|
||||
import net.kemitix.thorp.config._
|
||||
import net.kemitix.thorp.console._
|
||||
import net.kemitix.thorp.domain.StorageEvent.{
|
||||
CopyEvent,
|
||||
DeleteEvent,
|
||||
ErrorEvent,
|
||||
UploadEvent
|
||||
}
|
||||
import net.kemitix.thorp.domain.channel.{Channel, Sink}
|
||||
import net.kemitix.thorp.domain.{Counters, StorageEvent}
|
||||
import net.kemitix.thorp.lib.{LocalFileSystem, UnversionedMirrorArchive}
|
||||
import net.kemitix.thorp.storage.Storage
|
||||
import net.kemitix.thorp.uishell.{UIEvent, UIShell}
|
||||
|
||||
import scala.io.AnsiColor.{RESET, WHITE}
|
||||
import scala.jdk.CollectionConverters._
|
||||
|
||||
trait Program {
|
||||
|
||||
val version = "1.1.0-SNAPSHOT"
|
||||
lazy val versionLabel = s"${WHITE}Thorp v$version$RESET"
|
||||
|
||||
def run(args: List[String]): Unit = {
|
||||
val cli = CliArgs.parse(args.toArray)
|
||||
val config = ConfigurationBuilder.buildConfig(cli)
|
||||
Console.putStrLn(versionLabel)
|
||||
if (!showVersion(cli)) {
|
||||
executeWithUI(config)
|
||||
}
|
||||
}
|
||||
|
||||
private def showVersion: ConfigOptions => Boolean =
|
||||
cli => ConfigQuery.showVersion(cli)
|
||||
|
||||
private def executeWithUI(configuration: Configuration): Unit = {
|
||||
Channel
|
||||
.create("ui")
|
||||
.addListener(UIShell.listener(configuration))
|
||||
.run(execute(configuration)(_))
|
||||
.start()
|
||||
.waitForShutdown()
|
||||
}
|
||||
|
||||
private def execute(
|
||||
configuration: Configuration
|
||||
)(uiSink: Sink[UIEvent]): Unit = {
|
||||
try {
|
||||
showValidConfig(uiSink)
|
||||
val remoteObjects =
|
||||
fetchRemoteData(configuration, uiSink)
|
||||
val archive = UnversionedMirrorArchive.create
|
||||
val storageEvents = LocalFileSystem
|
||||
.scanCopyUpload(configuration, uiSink, remoteObjects, archive)
|
||||
val deleteEvents = LocalFileSystem
|
||||
.scanDelete(configuration, uiSink, remoteObjects, archive)
|
||||
showSummary(uiSink)(
|
||||
(storageEvents.asScala ++ deleteEvents.asScala).toList
|
||||
)
|
||||
} finally {
|
||||
Storage.getInstance().shutdown()
|
||||
}
|
||||
}
|
||||
|
||||
private def showValidConfig(uiSink: Sink[UIEvent]): Unit =
|
||||
uiSink.accept(UIEvent.showValidConfig)
|
||||
|
||||
private def fetchRemoteData(configuration: Configuration,
|
||||
uiSink: Sink[UIEvent]) = {
|
||||
val bucket = configuration.bucket
|
||||
val prefix = configuration.prefix
|
||||
val objects = Storage.getInstance().list(bucket, prefix)
|
||||
uiSink.accept(UIEvent.remoteDataFetched(objects.byKey.size))
|
||||
objects
|
||||
}
|
||||
|
||||
//TODO not called
|
||||
private def logValidationErrors(throwable: Throwable) =
|
||||
throwable match {
|
||||
case validateError: ConfigValidationException =>
|
||||
validateError.getErrors.asScala
|
||||
.map(error => Console.putStrLn(s"- $error"))
|
||||
}
|
||||
|
||||
private def showSummary(
|
||||
uiSink: Sink[UIEvent]
|
||||
)(events: Seq[StorageEvent]): Unit = {
|
||||
val counters = events.foldLeft(Counters.empty)(countActivities)
|
||||
uiSink.accept(UIEvent.showSummary(counters))
|
||||
}
|
||||
|
||||
private def countActivities =
|
||||
(counters: Counters, s3Action: StorageEvent) => {
|
||||
s3Action match {
|
||||
case _: UploadEvent => counters.incrementUploaded()
|
||||
case _: CopyEvent => counters.incrementCopied()
|
||||
case _: DeleteEvent => counters.incrementDeleted()
|
||||
case _: ErrorEvent => counters.incrementErrors()
|
||||
case _ => counters
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
object Program extends Program
|
Binary file not shown.
Before Width: | Height: | Size: 177 KiB After Width: | Height: | Size: 190 KiB |
|
@ -66,9 +66,10 @@ public class Terminal {
|
|||
public static String enableAlternateBuffer = csi + "?1049h";
|
||||
public static String disableAlternateBuffer = csi + "?1049l";
|
||||
|
||||
public static String reset = "\u001B[0m";
|
||||
public static String red = "\u001B[31m";
|
||||
public static String green = "\u001B[32m";
|
||||
public static String reset = "\u001B[0m";
|
||||
public static String white = "\u001B[37m";
|
||||
|
||||
private static Map<Integer, String> getSubBars() {
|
||||
Map<Integer, String> subBars = new HashMap<>();
|
||||
|
|
|
@ -16,10 +16,8 @@
|
|||
<packaging>pom</packaging>
|
||||
|
||||
<properties>
|
||||
<scala-maven-plugin.version>4.4.0</scala-maven-plugin.version>
|
||||
<tiles-maven-plugin.version>2.17</tiles-maven-plugin.version>
|
||||
<kemitix-maven-tiles.version>2.7.0</kemitix-maven-tiles.version>
|
||||
<scala-library.version>2.13.3</scala-library.version>
|
||||
<lombok.version>1.18.12</lombok.version>
|
||||
<mon.version>2.2.0</mon.version>
|
||||
<junit.version>5.6.2</junit.version>
|
||||
|
@ -111,71 +109,10 @@
|
|||
<artifactId>assertj-core</artifactId>
|
||||
<version>${assertj.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- scala - scala -->
|
||||
<dependency>
|
||||
<groupId>org.scala-lang</groupId>
|
||||
<artifactId>scala-library</artifactId>
|
||||
<version>${scala-library.version}</version>
|
||||
</dependency>
|
||||
<!-- scala - command line parsing -->
|
||||
<dependency>
|
||||
<groupId>com.github.scopt</groupId>
|
||||
<artifactId>scopt_2.13</artifactId>
|
||||
<version>4.0.0-RC2</version>
|
||||
</dependency>
|
||||
<!-- scala - test -->
|
||||
<dependency>
|
||||
<groupId>org.scalatest</groupId>
|
||||
<artifactId>scalatest_2.13</artifactId>
|
||||
<version>3.0.8</version>
|
||||
</dependency>
|
||||
<dependency><!-- only used by storage-aws -->
|
||||
<groupId>org.scalamock</groupId>
|
||||
<artifactId>scalamock_2.13</artifactId>
|
||||
<version>4.4.0</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
<build>
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>net.alchim31.maven</groupId>
|
||||
<artifactId>scala-maven-plugin</artifactId>
|
||||
<version>${scala-maven-plugin.version}</version>
|
||||
<configuration>
|
||||
<args>
|
||||
<arg>-Ywarn-unused:imports</arg>
|
||||
<arg>-Xfatal-warnings</arg>
|
||||
<arg>-feature</arg>
|
||||
<arg>-deprecation</arg>
|
||||
<arg>-unchecked</arg>
|
||||
<arg>-language:postfixOps</arg>
|
||||
<arg>-language:higherKinds</arg>
|
||||
</args>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>scala-compile-first</id>
|
||||
<phase>process-resources</phase>
|
||||
<goals>
|
||||
<goal>add-source</goal>
|
||||
<goal>compile</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>scala-test-compile</id>
|
||||
<phase>process-test-resources</phase>
|
||||
<goals>
|
||||
<goal>testCompile</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>io.repaint.maven</groupId>
|
||||
|
|
Loading…
Reference in a new issue