Skip to content

Commit

Permalink
#70 Migrate json based state storage to H2
Browse files Browse the repository at this point in the history
  • Loading branch information
ylexus committed May 21, 2021
1 parent 0ac28fb commit efb17ac
Show file tree
Hide file tree
Showing 27 changed files with 456 additions and 283 deletions.
16 changes: 8 additions & 8 deletions .github/workflows/gradle.yml
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
name: Java CI

on: [push]
on: [ push ]

jobs:
build:

runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v1
- name: Set up JDK
uses: actions/setup-java@v1
with:
java-version: 14.0.2
- name: Build with Gradle
run: ./gradlew test --no-daemon
- uses: actions/checkout@v1
- name: Set up JDK
uses: actions/setup-java@v1
with:
java-version: 14.0.2
- name: Build with Gradle
run: ./gradlew test --no-daemon
5 changes: 3 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ dependencies {
ext.orgJunitJupiterVersion = '5.6.0'
ext.orgMockitoVersion = '3.2.4'
ext.orgImmutablesVersion = '2.8.3'
ext.netYudichevJiottyVersion = '1.6.5'
ext.netYudichevJiottyVersion = '1.7'

annotationProcessor "org.immutables:value:$orgImmutablesVersion"
testAnnotationProcessor "org.immutables:value:$orgImmutablesVersion"
Expand Down Expand Up @@ -80,11 +80,12 @@ dependencies {
implementation "com.google.api.grpc:proto-google-common-protos"
implementation "com.google.http-client:google-http-client"
implementation "commons-cli:commons-cli:1.4"
implementation "com.fasterxml.jackson.core:jackson-databind:2.9.9"
implementation "com.fasterxml.jackson.core:jackson-databind"
implementation "de.codecentric.centerdevice:centerdevice-nsmenufx:2.1.7"
implementation "io.grpc:grpc-api"
implementation "com.squareup.okhttp3:okhttp"
implementation "com.sandec:mdfx:0.1.8"
implementation 'com.h2database:h2:1.4.200'

// This is to test dependency analyser
//implementation "org.apache.commons:commons-skin:4.2"
Expand Down
13 changes: 9 additions & 4 deletions src/main/java/net/yudichev/googlephotosupload/cli/CliMain.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import net.yudichev.googlephotosupload.core.DependenciesModule;
import net.yudichev.googlephotosupload.core.ResourceBundleModule;
import net.yudichev.googlephotosupload.core.SettingsModule;
import net.yudichev.googlephotosupload.core.UploadPhotosModule;
import net.yudichev.jiotty.common.app.Application;
import org.apache.commons.cli.*;
Expand Down Expand Up @@ -31,10 +32,11 @@ public static void main(String[] args) {
logger.info("Version {}", buildVersion());
}
if (commandLine.hasOption('r')) {
if (otherInstanceRunning()) {
var settingsModule = new SettingsModule();
if (otherInstanceRunning(settingsModule.getSettingsRootPath())) {
logger.error("Another copy of the app is already running");
} else {
startApp(commandLine);
startApp(settingsModule, commandLine);
}
} else if (!helpRequested && !versionRequested) {
logger.error("Missing option -r");
Expand All @@ -47,9 +49,12 @@ public static void main(String[] args) {
LogManager.shutdown();
}

private static void startApp(CommandLine commandLine) {
private static void startApp(SettingsModule settingsModule, CommandLine commandLine) {
Application.builder()
.addModule(() -> DependenciesModule.builder().build())
.addModule(() -> settingsModule)
.addModule(() -> DependenciesModule.builder()
.setAppSettingsRootDir(settingsModule.getSettingsRootPath())
.build())
.addModule(UploadPhotosModule::new)
.addModule(ResourceBundleModule::new)
.addModule(() -> new CliModule(commandLine))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@
import static com.google.common.base.Preconditions.checkNotNull;
import static net.yudichev.jiotty.common.lang.CompletableFutures.logErrorOnFailure;

final class CliStarter extends BaseLifecycleComponent {
final class
CliStarter extends BaseLifecycleComponent {
private static final Logger logger = LoggerFactory.getLogger(CliStarter.class);
private final Path rootDir;
private final Uploader uploader;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@ private CompletionStage<Void> addToAlbum(Optional<GooglePhotosAlbum> googlePhoto
return googlePhotosAlbum
.map(album -> {
var pathMediaItemOrErrors = pathMediaItemOrErrorStream
.filter(pathMediaItemOrError -> itemStateRetriever.apply(pathMediaItemOrError.path()).albumId().isEmpty())
.collect(toImmutableList());
var mediaItemsToAddToAlbum = pathMediaItemOrErrors.stream()
.map(PathMediaItemOrError::mediaItem)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,7 @@
package net.yudichev.googlephotosupload.core;

import java.nio.file.Path;
import java.nio.file.Paths;

public final class AppGlobals {
public static final String APP_TITLE = "Jiotty Photos Uploader";
public static final String APP_SETTINGS_DIR_NAME = "jiottyphotosuploader";
public static final Path APP_SETTINGS_DIR = Paths.get(System.getProperty("user.home"), "." + APP_SETTINGS_DIR_NAME);
static final Path APP_SETTINGS_AUTH_DIR = APP_SETTINGS_DIR.resolve("auth");

private AppGlobals() {
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package net.yudichev.googlephotosupload.core;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
Expand All @@ -16,14 +17,13 @@
@PackagePrivateImmutablesStyle
@JsonSerialize
@JsonDeserialize
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(NON_NULL)
interface BaseItemState {
Optional<UploadMediaItemState> uploadState();

Optional<String> mediaId();

Optional<String> albumId();

@Immutable
@PackagePrivateImmutablesStyle
@JsonSerialize
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

final class Bindings {
public final class Bindings {
private Bindings() {
}

Expand All @@ -17,4 +17,10 @@ private Bindings() {
@Retention(RUNTIME)
@interface Backpressured {
}

@BindingAnnotation
@Target({FIELD, PARAMETER, METHOD})
@Retention(RUNTIME)
public @interface SettingsRoot {
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,29 +15,31 @@
import static com.google.common.io.Resources.toByteArray;
import static java.nio.file.Files.*;
import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
import static net.yudichev.googlephotosupload.core.AppGlobals.APP_SETTINGS_DIR;
import static net.yudichev.googlephotosupload.core.Bindings.SettingsRoot;
import static net.yudichev.jiotty.common.lang.MoreThrowables.asUnchecked;
import static net.yudichev.jiotty.common.lang.MoreThrowables.getAsUnchecked;

final class CustomCredentialsManagerImpl implements Provider<URL>, CustomCredentialsManager {
private static final URL STANDARD_CREDENTIALS_URL = getResource("client_secret.json");
private static final byte[] STANDARD_CREDENTIALS_URL_HASH = crc32(STANDARD_CREDENTIALS_URL);
private final PreferencesManager preferencesManager;
private final Path CUSTOM_CREDENTIALS_PATH = APP_SETTINGS_DIR.resolve("client_secret.json");
private final Path customCredentialsPath;
private final AtomicReference<Boolean> usingCustomCredentials = new AtomicReference<>();
@Nullable
private byte[] hashOfUsedCredentials;
@Nullable
private byte[] hashOfConfiguredCredentials;

@Inject
CustomCredentialsManagerImpl(PreferencesManager preferencesManager) {
CustomCredentialsManagerImpl(@SettingsRoot Path settingsRoot,
PreferencesManager preferencesManager) {
this.preferencesManager = checkNotNull(preferencesManager);
customCredentialsPath = settingsRoot.resolve("client_secret.json");
}

@Override
public void saveCustomCredentials(Path sourceFile) {
asUnchecked(() -> copy(sourceFile, CUSTOM_CREDENTIALS_PATH, REPLACE_EXISTING));
asUnchecked(() -> copy(sourceFile, customCredentialsPath, REPLACE_EXISTING));
refreshHashOfConfiguredCredentials();
}

Expand All @@ -48,12 +50,12 @@ public boolean usingCustomCredentials() {

@Override
public boolean configuredToUseCustomCredentials() {
return preferencesManager.get().useCustomCredentials() && isRegularFile(CUSTOM_CREDENTIALS_PATH);
return preferencesManager.get().useCustomCredentials() && isRegularFile(customCredentialsPath);
}

@Override
public void deleteCustomCredentials() {
asUnchecked(() -> deleteIfExists(CUSTOM_CREDENTIALS_PATH));
asUnchecked(() -> deleteIfExists(customCredentialsPath));
refreshHashOfConfiguredCredentials();
}

Expand All @@ -68,7 +70,7 @@ public URL get() {
this.usingCustomCredentials.set(usingCustomCredentials);
URL url;
if (usingCustomCredentials) {
url = getAsUnchecked(() -> CUSTOM_CREDENTIALS_PATH.toUri().toURL());
url = getAsUnchecked(() -> customCredentialsPath.toUri().toURL());
hashOfUsedCredentials = crc32(url);
} else {
url = STANDARD_CREDENTIALS_URL;
Expand All @@ -80,7 +82,7 @@ public URL get() {

private void refreshHashOfConfiguredCredentials() {
hashOfConfiguredCredentials = configuredToUseCustomCredentials() ?
crc32(getAsUnchecked(() -> CUSTOM_CREDENTIALS_PATH.toUri().toURL())) :
crc32(getAsUnchecked(() -> customCredentialsPath.toUri().toURL())) :
STANDARD_CREDENTIALS_URL_HASH;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import net.yudichev.jiotty.common.async.ExecutorModule;
import net.yudichev.jiotty.common.lang.TypedBuilder;
import net.yudichev.jiotty.common.time.TimeModule;
import net.yudichev.jiotty.common.varstore.VarStoreModule;
import net.yudichev.jiotty.connector.google.common.GoogleApiAuthSettings;
import net.yudichev.jiotty.connector.google.photos.GooglePhotosModule;

Expand All @@ -14,13 +13,16 @@
import java.util.function.Consumer;

import static com.google.common.base.Preconditions.checkNotNull;
import static net.yudichev.googlephotosupload.core.AppGlobals.*;
import static net.yudichev.googlephotosupload.core.AppGlobals.APP_TITLE;
import static net.yudichev.jiotty.common.inject.BindingSpec.providedBy;

public final class DependenciesModule extends AbstractModule {
private final Path appSettingsRootDir;
private final Consumer<GoogleApiAuthSettings.Builder> googleApiSettingsCustomiser;

private DependenciesModule(Consumer<GoogleApiAuthSettings.Builder> googleApiSettingsCustomiser) {
private DependenciesModule(Path appSettingsRootDir,
Consumer<GoogleApiAuthSettings.Builder> googleApiSettingsCustomiser) {
this.appSettingsRootDir = checkNotNull(appSettingsRootDir);
this.googleApiSettingsCustomiser = checkNotNull(googleApiSettingsCustomiser);
}

Expand All @@ -32,9 +34,8 @@ public static Builder builder() {
protected void configure() {
install(new TimeModule());
install(new ExecutorModule());
install(new VarStoreModule(APP_SETTINGS_DIR_NAME));

var authDataStoreRootDir = APP_SETTINGS_AUTH_DIR;
var authDataStoreRootDir = appSettingsRootDir.resolve("auth");
bind(Restarter.class).to(RestarterImpl.class);
bind(Path.class).annotatedWith(RestarterImpl.GoogleAuthRootDir.class).toInstance(authDataStoreRootDir);

Expand All @@ -51,16 +52,22 @@ protected void configure() {
}

public static final class Builder implements TypedBuilder<Module> {
private Path appSettingsRootDir;
private Consumer<GoogleApiAuthSettings.Builder> googleApiSettingsCustomiser = ignored -> {};

public Builder setAppSettingsRootDir(Path appSettingsRootDir) {
this.appSettingsRootDir = checkNotNull(appSettingsRootDir);
return this;
}

public Builder withGoogleApiSettingsCustomiser(Consumer<GoogleApiAuthSettings.Builder> googleApiSettingsCustomiser) {
this.googleApiSettingsCustomiser = checkNotNull(googleApiSettingsCustomiser);
return this;
}

@Override
public Module build() {
return new DependenciesModule(googleApiSettingsCustomiser);
return new DependenciesModule(appSettingsRootDir, googleApiSettingsCustomiser);
}
}
}
Loading

0 comments on commit efb17ac

Please sign in to comment.