Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

storage from keys and shallow discovery (without listing) #31

Merged
merged 16 commits into from
Dec 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@
<parent>
<groupId>org.scijava</groupId>
<artifactId>pom-scijava</artifactId>
<version>38.0.1</version>
<version>40.0.0</version>
<relativePath />
</parent>

<groupId>org.janelia.saalfeldlab</groupId>
<artifactId>n5-universe</artifactId>
<version>1.6.1-SNAPSHOT</version>
<version>1.7.0-SNAPSHOT</version>

<name>N5-Universe</name>
<description>Utilities spanning all of the N5 repositories</description>
Expand Down Expand Up @@ -111,16 +111,16 @@
<!-- NB: Deploy releases to the SciJava Maven repository. -->
<releaseProfiles>sign,deploy-to-scijava</releaseProfiles>

<n5.version>3.3.0</n5.version>
<n5-aws-s3.version>4.2.1</n5-aws-s3.version>
<n5-google-cloud.version>4.1.1</n5-google-cloud.version>
<n5-zarr.version>1.3.5</n5-zarr.version>
<n5-aws-s3.version>4.2.2</n5-aws-s3.version>
<n5-google-cloud.version>4.1.2</n5-google-cloud.version>
<n5-zarr.version>1.4.0</n5-zarr.version>

<jackson-jq.version>1.0.0-preview.20191208</jackson-jq.version>
<alphanumeric-comparator.version>1.4.1</alphanumeric-comparator.version>

<s3mock_2.12.version>0.2.5</s3mock_2.12.version>
<jaxb-api.version>2.2.2</jaxb-api.version>
<json-simple.version>1.1.1</json-simple.version>
</properties>

<dependencies>
Expand Down Expand Up @@ -203,7 +203,7 @@
<dependency>
<groupId>com.googlecode.json-simple</groupId>
<artifactId>json-simple</artifactId>
<version>1.1.1</version>
<version>${json-simple.version}</version>
<scope>test</scope>
</dependency>
<dependency>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
package org.janelia.saalfeldlab.n5.universe;

import com.amazonaws.services.s3.AmazonS3;
import org.janelia.saalfeldlab.googlecloud.GoogleCloudStorageURI;
import org.janelia.saalfeldlab.googlecloud.GoogleCloudUtils;
import org.janelia.saalfeldlab.n5.FileSystemKeyValueAccess;
import org.janelia.saalfeldlab.n5.KeyValueAccess;
import org.janelia.saalfeldlab.n5.N5Reader;
import org.janelia.saalfeldlab.n5.N5Writer;
import org.janelia.saalfeldlab.n5.googlecloud.GoogleCloudStorageKeyValueAccess;
import org.janelia.saalfeldlab.n5.s3.AmazonS3KeyValueAccess;
import org.janelia.saalfeldlab.n5.s3.AmazonS3Utils;

import javax.annotation.Nullable;
import java.net.URI;
import java.nio.file.FileSystems;
import java.util.function.BiFunction;
import java.util.function.Predicate;
import java.util.regex.Pattern;

/**
* Enum to discover and provide {@link KeyValueAccess} for {@link N5Reader}s and {@link N5Writer}s.
* IMPORTANT: If ever new {@link KeyValueAccess} backends are adding, they MUST be re-ordered
* such that the earliest predicates are the most restrictive, and the later predicates
* are the least restrictive. This ensures that when iterating through the values of
* {@link KeyValueAccessBackend} you can test them in order, and stop at the first
* {@link KeyValueAccess} that is generated.
*/
public enum KeyValueAccessBackend implements Predicate<URI>, BiFunction<URI, N5Factory, KeyValueAccess> {
GOOGLE_CLOUD(uri -> {
final String scheme = uri.getScheme();
final boolean hasScheme = scheme != null;
return hasScheme && GoogleCloudUtils.GS_SCHEME.asPredicate().test(scheme)
|| hasScheme && N5Factory.HTTPS_SCHEME.asPredicate().test(scheme)
&& uri.getHost() != null && GoogleCloudUtils.GS_HOST.asPredicate().test(uri.getHost());
}, KeyValueAccessBackend::newGoogleCloudKeyValueAccess),
AWS(uri -> {
final String scheme = uri.getScheme();
final boolean hasScheme = scheme != null;
return hasScheme && AmazonS3Utils.S3_SCHEME.asPredicate().test(scheme)
|| uri.getHost() != null && hasScheme && N5Factory.HTTPS_SCHEME.asPredicate().test(scheme);
}, KeyValueAccessBackend::newAmazonS3KeyValueAccess),
FILE(uri -> {
final String scheme = uri.getScheme();
final boolean hasScheme = scheme != null;
return !hasScheme || N5Factory.FILE_SCHEME.asPredicate().test(scheme);
}, KeyValueAccessBackend::newFileSystemKeyValueAccess);

private final Predicate<URI> backendTest;
private final BiFunction<URI, N5Factory, KeyValueAccess> backendGenerator;

KeyValueAccessBackend(Predicate<URI> test, BiFunction<URI, N5Factory, KeyValueAccess> generator) {

backendTest = test;
backendGenerator = generator;
}

@Override public KeyValueAccess apply(final URI uri, final N5Factory factory) {

if (test(uri))
return backendGenerator.apply(uri, factory);
return null;
}

@Override public boolean test(URI uri) {

return backendTest.test(uri);
}

/**
* Test the provided {@link URI} to and return the appropriate {@link KeyValueAccess}.
* If no appropriate {@link KeyValueAccess} is found, may be null
*
* @param uri to create a {@link KeyValueAccess} from.
* @return the {@link KeyValueAccess} and container path, or null if none are valid
*/
@Nullable
public static KeyValueAccess getKeyValueAccess(final URI uri) {

return getKeyValueAccess(uri, N5Factory.FACTORY);
}

@Nullable
static KeyValueAccess getKeyValueAccess(final URI uri, final N5Factory factory) {

/*NOTE: The order of these tests is very important, as the predicates for each
* backend take into account reasonable defaults when possible.
* Here we test from most to least restrictive.
* See the Javadoc for more details. */
for (final KeyValueAccessBackend backend : KeyValueAccessBackend.values()) {
final KeyValueAccess kva = backend.apply(uri, factory);
if (kva != null)
return kva;
}
return null;
}

private static GoogleCloudStorageKeyValueAccess newGoogleCloudKeyValueAccess(final URI uri, final N5Factory factory) {

final GoogleCloudStorageURI googleCloudUri = new GoogleCloudStorageURI(uri);
return new GoogleCloudStorageKeyValueAccess(factory.createGoogleCloudStorage(), googleCloudUri, true);
}

private static AmazonS3KeyValueAccess newAmazonS3KeyValueAccess(final URI uri, final N5Factory factory) {

final String uriString = uri.toString();
final AmazonS3 s3 = factory.createS3(uriString);

return new AmazonS3KeyValueAccess(s3, uri, true);
}

private static FileSystemKeyValueAccess newFileSystemKeyValueAccess(final URI uri, final N5Factory factory) {

return new FileSystemKeyValueAccess(FileSystems.getDefault());
}
}
Loading
Loading