diff --git a/pom.xml b/pom.xml index 4f09a984f..8e16429ca 100644 --- a/pom.xml +++ b/pom.xml @@ -209,6 +209,11 @@ n5 2.1.6 + + org.janelia.saalfeldlab + n5-aws-s3 + 2.1.1-SNAPSHOT + com.miglayout miglayout-swing diff --git a/src/main/java/bdv/export/n5/WriteSequenceToN5.java b/src/main/java/bdv/export/n5/WriteSequenceToN5.java index 62f5cc97c..7cb45b55a 100644 --- a/src/main/java/bdv/export/n5/WriteSequenceToN5.java +++ b/src/main/java/bdv/export/n5/WriteSequenceToN5.java @@ -8,7 +8,7 @@ import bdv.export.ExportScalePyramid.AfterEachPlane; import bdv.export.ExportScalePyramid.LoopbackHeuristic; import bdv.img.cache.SimpleCacheArrayLoader; -import bdv.img.n5.N5ImageLoader; +import bdv.img.n5.N5FSImageLoader; import java.io.File; import java.io.IOException; import java.util.ArrayList; @@ -325,7 +325,7 @@ public RandomAccessibleInterval< T > getImage( final int level ) throws IOExcept final long[] dimensions = attributes.getDimensions(); final int[] cellDimensions = attributes.getBlockSize(); final CellGrid grid = new CellGrid( dimensions, cellDimensions ); - final SimpleCacheArrayLoader< ? > cacheArrayLoader = N5ImageLoader.createCacheArrayLoader( n5, pathName ); + final SimpleCacheArrayLoader< ? > cacheArrayLoader = N5FSImageLoader.createCacheArrayLoader( n5, pathName ); return new ReadOnlyCachedCellImgFactory().createWithCacheLoader( dimensions, type, key -> { diff --git a/src/main/java/bdv/img/n5/N5FSImageLoader.java b/src/main/java/bdv/img/n5/N5FSImageLoader.java new file mode 100644 index 000000000..c631705e8 --- /dev/null +++ b/src/main/java/bdv/img/n5/N5FSImageLoader.java @@ -0,0 +1,52 @@ +/* + * #%L + * BigDataViewer core classes with minimal dependencies + * %% + * Copyright (C) 2012 - 2016 Tobias Pietzsch, Stephan Saalfeld, Stephan Preibisch, + * Jean-Yves Tinevez, HongKee Moon, Johannes Schindelin, Curtis Rueden, John Bogovic + * %% + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * #L% + */ +package bdv.img.n5; + +import mpicbg.spim.data.generic.sequence.AbstractSequenceDescription; +import org.janelia.saalfeldlab.n5.N5FSReader; + +import java.io.File; +import java.io.IOException; + +public class N5FSImageLoader extends N5ImageLoader +{ + private final File n5File; + + public N5FSImageLoader( final File n5File, final AbstractSequenceDescription< ?, ?, ? > sequenceDescription ) throws IOException + { + super( new N5FSReader( n5File.getAbsolutePath() ), sequenceDescription ); + this.n5File = n5File; + } + + public File getN5File() + { + return n5File; + } +} diff --git a/src/main/java/bdv/img/n5/N5ImageLoader.java b/src/main/java/bdv/img/n5/N5ImageLoader.java index 3a774d0b1..22b035ba7 100644 --- a/src/main/java/bdv/img/n5/N5ImageLoader.java +++ b/src/main/java/bdv/img/n5/N5ImageLoader.java @@ -36,98 +36,63 @@ import bdv.img.cache.VolatileGlobalCellCache; import bdv.util.ConstantRandomAccessible; import bdv.util.MipmapTransforms; -import java.io.File; -import java.io.IOException; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.concurrent.Callable; -import java.util.function.Function; +import com.amazonaws.SdkClientException; import mpicbg.spim.data.generic.sequence.AbstractSequenceDescription; import mpicbg.spim.data.generic.sequence.BasicViewSetup; import mpicbg.spim.data.generic.sequence.ImgLoaderHint; import mpicbg.spim.data.sequence.MultiResolutionImgLoader; import mpicbg.spim.data.sequence.MultiResolutionSetupImgLoader; import mpicbg.spim.data.sequence.VoxelDimensions; -import net.imglib2.Dimensions; -import net.imglib2.FinalDimensions; -import net.imglib2.FinalInterval; -import net.imglib2.RandomAccessibleInterval; -import net.imglib2.Volatile; +import net.imglib2.*; import net.imglib2.cache.queue.BlockingFetchQueues; import net.imglib2.cache.queue.FetcherThreads; import net.imglib2.cache.volatiles.CacheHints; import net.imglib2.cache.volatiles.LoadingStrategy; -import net.imglib2.img.basictypeaccess.volatiles.array.VolatileByteArray; -import net.imglib2.img.basictypeaccess.volatiles.array.VolatileDoubleArray; -import net.imglib2.img.basictypeaccess.volatiles.array.VolatileFloatArray; -import net.imglib2.img.basictypeaccess.volatiles.array.VolatileIntArray; -import net.imglib2.img.basictypeaccess.volatiles.array.VolatileLongArray; -import net.imglib2.img.basictypeaccess.volatiles.array.VolatileShortArray; +import net.imglib2.img.basictypeaccess.volatiles.array.*; import net.imglib2.img.cell.CellGrid; import net.imglib2.img.cell.CellImg; import net.imglib2.realtransform.AffineTransform3D; import net.imglib2.type.NativeType; -import net.imglib2.type.numeric.integer.ByteType; -import net.imglib2.type.numeric.integer.IntType; -import net.imglib2.type.numeric.integer.LongType; -import net.imglib2.type.numeric.integer.ShortType; -import net.imglib2.type.numeric.integer.UnsignedByteType; -import net.imglib2.type.numeric.integer.UnsignedIntType; -import net.imglib2.type.numeric.integer.UnsignedLongType; -import net.imglib2.type.numeric.integer.UnsignedShortType; +import net.imglib2.type.numeric.integer.*; import net.imglib2.type.numeric.real.DoubleType; import net.imglib2.type.numeric.real.FloatType; -import net.imglib2.type.volatiles.VolatileByteType; -import net.imglib2.type.volatiles.VolatileDoubleType; -import net.imglib2.type.volatiles.VolatileFloatType; -import net.imglib2.type.volatiles.VolatileIntType; -import net.imglib2.type.volatiles.VolatileLongType; -import net.imglib2.type.volatiles.VolatileShortType; -import net.imglib2.type.volatiles.VolatileUnsignedByteType; -import net.imglib2.type.volatiles.VolatileUnsignedIntType; -import net.imglib2.type.volatiles.VolatileUnsignedLongType; -import net.imglib2.type.volatiles.VolatileUnsignedShortType; +import net.imglib2.type.volatiles.*; import net.imglib2.util.Cast; import net.imglib2.view.Views; -import org.janelia.saalfeldlab.n5.DataBlock; -import org.janelia.saalfeldlab.n5.DataType; -import org.janelia.saalfeldlab.n5.DatasetAttributes; -import org.janelia.saalfeldlab.n5.N5FSReader; -import org.janelia.saalfeldlab.n5.N5Reader; +import org.janelia.saalfeldlab.n5.*; -import static bdv.img.n5.BdvN5Format.DATA_TYPE_KEY; -import static bdv.img.n5.BdvN5Format.DOWNSAMPLING_FACTORS_KEY; -import static bdv.img.n5.BdvN5Format.getPathName; +import java.io.File; +import java.io.IOException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.Callable; +import java.util.function.Function; + +import static bdv.img.n5.BdvN5Format.*; public class N5ImageLoader implements ViewerImgLoader, MultiResolutionImgLoader { - private final File n5File; + protected final N5Reader n5; // TODO: it would be good if this would not be needed // find available setups from the n5 - private final AbstractSequenceDescription< ?, ?, ? > seq; + protected final AbstractSequenceDescription< ?, ?, ? > seq; /** * Maps setup id to {@link SetupImgLoader}. */ private final Map< Integer, SetupImgLoader > setupImgLoaders = new HashMap<>(); - public N5ImageLoader( final File n5File, final AbstractSequenceDescription< ?, ?, ? > sequenceDescription ) - { - this.n5File = n5File; - this.seq = sequenceDescription; - } - - public File getN5File() - { - return n5File; - } - private volatile boolean isOpen = false; private FetcherThreads fetchers; private VolatileGlobalCellCache cache; - private N5Reader n5; + + public N5ImageLoader( N5Reader n5Reader, AbstractSequenceDescription< ?, ?, ? > sequenceDescription ) + { + this.n5 = n5Reader; + this.seq = sequenceDescription; + } private void open() { @@ -140,8 +105,6 @@ private void open() try { - this.n5 = new N5FSReader( n5File.getAbsolutePath() ); - int maxNumLevels = 0; final List< ? extends BasicViewSetup > setups = seq.getViewSetupsOrdered(); for ( final BasicViewSetup setup : setups ) @@ -353,7 +316,46 @@ private static class N5CacheArrayLoader< A > implements SimpleCacheArrayLoader< @Override public A loadArray( final long[] gridPosition ) throws IOException { - return createArray.apply( n5.readBlock( pathName, attributes, gridPosition ) ); + DataBlock< ? > block = null; + + try { + block = n5.readBlock( pathName, attributes, gridPosition ); + } + catch ( SdkClientException e ) + { + System.err.println( e ); // this happens sometimes, not sure yet why... + } + + if ( block == null ) + { + final int[] blockSize = attributes.getBlockSize(); + final int n = blockSize[ 0 ] * blockSize[ 1 ] * blockSize[ 2 ]; + switch ( attributes.getDataType() ) + { + case UINT8: + case INT8: + return createArray.apply( new ByteArrayDataBlock( blockSize, gridPosition, new byte[ n ] ) ); + case UINT16: + case INT16: + return createArray.apply( new ShortArrayDataBlock( blockSize, gridPosition, new short[ n ] ) ); + case UINT32: + case INT32: + return createArray.apply( new IntArrayDataBlock( blockSize, gridPosition, new int[ n ] ) ); + case UINT64: + case INT64: + return createArray.apply( new LongArrayDataBlock( blockSize, gridPosition, new long[ n ] ) ); + case FLOAT32: + return createArray.apply( new FloatArrayDataBlock( blockSize, gridPosition, new float[ n ] ) ); + case FLOAT64: + return createArray.apply( new DoubleArrayDataBlock( blockSize, gridPosition, new double[ n ] ) ); + default: + throw new IllegalArgumentException(); + } + } + else + { + return createArray.apply( block ); + } } } diff --git a/src/main/java/bdv/img/n5/N5S3ImageLoader.java b/src/main/java/bdv/img/n5/N5S3ImageLoader.java new file mode 100644 index 000000000..555d6d22a --- /dev/null +++ b/src/main/java/bdv/img/n5/N5S3ImageLoader.java @@ -0,0 +1,143 @@ +/* + * #%L + * BigDataViewer core classes with minimal dependencies + * %% + * Copyright (C) 2012 - 2016 Tobias Pietzsch, Stephan Saalfeld, Stephan Preibisch, + * Jean-Yves Tinevez, HongKee Moon, Johannes Schindelin, Curtis Rueden, John Bogovic + * %% + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * #L% + */ +package bdv.img.n5; + +import com.amazonaws.auth.AWSCredentialsProvider; +import com.amazonaws.auth.AWSStaticCredentialsProvider; +import com.amazonaws.auth.AnonymousAWSCredentials; +import com.amazonaws.auth.DefaultAWSCredentialsProviderChain; +import com.amazonaws.client.builder.AwsClientBuilder; +import com.amazonaws.services.s3.AmazonS3; +import com.amazonaws.services.s3.AmazonS3ClientBuilder; +import mpicbg.spim.data.generic.sequence.AbstractSequenceDescription; +import org.janelia.saalfeldlab.n5.s3.N5AmazonS3Reader; + +import java.io.IOException; + +public class N5S3ImageLoader extends N5ImageLoader +{ + private final String serviceEndpoint; + private final String signingRegion; + private final String bucketName; + private final String key; + private final N5AmazonS3ReaderCreator.Authentication authentication; + + static class N5AmazonS3ReaderCreator + { + /** + * It seems that the way S3 works is that when a user has no credentials it means anonymous, + * but as soon as you provide some credentials it tries to get access with those, + * which indeed don't have access for that specific bucket. + * So it seems the way to go is to define in the application whether + * you want to use anonymous access or credentials based access + */ + public enum Authentication + { + Anonymous, + Protected + } + + public N5AmazonS3Reader create( String serviceEndpoint, String signingRegion, String bucketName, String key, Authentication authentication ) throws IOException + { + final AwsClientBuilder.EndpointConfiguration endpoint = new AwsClientBuilder.EndpointConfiguration( serviceEndpoint, signingRegion ); + + final AmazonS3 s3 = AmazonS3ClientBuilder + .standard() + .withPathStyleAccessEnabled( true ) + .withEndpointConfiguration( endpoint ) + .withCredentials( getCredentialsProvider( authentication ) ) + .build(); + + return new N5AmazonS3Reader( s3, bucketName, key ); + } + + private AWSCredentialsProvider getCredentialsProvider( Authentication authentication ) + { + switch ( authentication ) + { + case Anonymous: + return new AWSStaticCredentialsProvider( new AnonymousAWSCredentials() ); + case Protected: + final DefaultAWSCredentialsProviderChain credentialsProvider = new DefaultAWSCredentialsProviderChain(); + checkCredentialsExistence( credentialsProvider ); + return credentialsProvider; + default: + throw new UnsupportedOperationException( "Authentication not supported: " + authentication ); + } + } + + private void checkCredentialsExistence( AWSCredentialsProvider credentialsProvider ) + { + try + { + credentialsProvider.getCredentials(); + } + catch ( Exception e ) + { + throw new RuntimeException( e ); // No credentials could be found + } + } + } + + public N5S3ImageLoader( String serviceEndpoint, String signingRegion, String bucketName, String key, N5AmazonS3ReaderCreator.Authentication authentication, AbstractSequenceDescription< ?, ?, ? > sequenceDescription ) throws IOException + { + super( new N5AmazonS3ReaderCreator().create( serviceEndpoint, signingRegion, bucketName, key, authentication ), sequenceDescription ); + this.serviceEndpoint = serviceEndpoint; + this.signingRegion = signingRegion; + this.bucketName = bucketName; + this.key = key; + this.authentication = authentication; + } + + public String getServiceEndpoint() + { + return serviceEndpoint; + } + + public String getSigningRegion() + { + return signingRegion; + } + + public String getBucketName() + { + return bucketName; + } + + public String getKey() + { + return key; + } + + public N5AmazonS3ReaderCreator.Authentication getAuthentication() + { + return authentication; + } +} diff --git a/src/main/java/bdv/img/n5/XmlIoN5ImageLoader.java b/src/main/java/bdv/img/n5/XmlIoN5FSImageLoader.java similarity index 75% rename from src/main/java/bdv/img/n5/XmlIoN5ImageLoader.java rename to src/main/java/bdv/img/n5/XmlIoN5FSImageLoader.java index 10e40feb6..a0ae90079 100644 --- a/src/main/java/bdv/img/n5/XmlIoN5ImageLoader.java +++ b/src/main/java/bdv/img/n5/XmlIoN5FSImageLoader.java @@ -30,6 +30,8 @@ package bdv.img.n5; import java.io.File; +import java.io.IOException; + import mpicbg.spim.data.XmlHelpers; import mpicbg.spim.data.generic.sequence.AbstractSequenceDescription; import mpicbg.spim.data.generic.sequence.ImgLoaderIo; @@ -39,24 +41,33 @@ import static mpicbg.spim.data.XmlHelpers.loadPath; import static mpicbg.spim.data.XmlKeys.IMGLOADER_FORMAT_ATTRIBUTE_NAME; -@ImgLoaderIo( format = "bdv.n5", type = N5ImageLoader.class ) -public class XmlIoN5ImageLoader implements XmlIoBasicImgLoader< N5ImageLoader > +@ImgLoaderIo( format = "bdv.n5", type = N5FSImageLoader.class ) +public class XmlIoN5FSImageLoader implements XmlIoBasicImgLoader< N5FSImageLoader > { + public static final String N5 = "n5"; + @Override - public Element toXml( final N5ImageLoader imgLoader, final File basePath ) + public Element toXml( final N5FSImageLoader imgLoader, final File basePath ) { final Element elem = new Element( "ImageLoader" ); elem.setAttribute( IMGLOADER_FORMAT_ATTRIBUTE_NAME, "bdv.n5" ); elem.setAttribute( "version", "1.0" ); - elem.addContent( XmlHelpers.pathElement( "n5", imgLoader.getN5File(), basePath ) ); + elem.addContent( XmlHelpers.pathElement( N5, imgLoader.getN5File(), basePath ) ); return elem; } @Override - public N5ImageLoader fromXml( final Element elem, final File basePath, final AbstractSequenceDescription< ?, ?, ? > sequenceDescription ) + public N5FSImageLoader fromXml( final Element elem, final File basePath, final AbstractSequenceDescription< ?, ?, ? > sequenceDescription ) { // final String version = elem.getAttributeValue( "version" ); - final File path = loadPath( elem, "n5", basePath ); - return new N5ImageLoader( path, sequenceDescription ); + final File path = loadPath( elem, N5, basePath ); + try + { + return new N5FSImageLoader( path, sequenceDescription ); + } + catch ( IOException e ) + { + throw new RuntimeException( e ); + } } } diff --git a/src/main/java/bdv/img/n5/XmlIoN5S3ImageLoader.java b/src/main/java/bdv/img/n5/XmlIoN5S3ImageLoader.java new file mode 100644 index 000000000..ab0894bc8 --- /dev/null +++ b/src/main/java/bdv/img/n5/XmlIoN5S3ImageLoader.java @@ -0,0 +1,90 @@ +/* + * #%L + * BigDataViewer core classes with minimal dependencies + * %% + * Copyright (C) 2012 - 2016 Tobias Pietzsch, Stephan Saalfeld, Stephan Preibisch, + * Jean-Yves Tinevez, HongKee Moon, Johannes Schindelin, Curtis Rueden, John Bogovic + * %% + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * #L% + */ +package bdv.img.n5; + +import mpicbg.spim.data.XmlHelpers; +import mpicbg.spim.data.generic.sequence.AbstractSequenceDescription; +import mpicbg.spim.data.generic.sequence.ImgLoaderIo; +import mpicbg.spim.data.generic.sequence.XmlIoBasicImgLoader; +import org.jdom2.Element; + +import java.io.File; +import java.io.IOException; + +import static bdv.img.n5.N5S3ImageLoader.N5AmazonS3ReaderCreator.*; +import static mpicbg.spim.data.XmlKeys.IMGLOADER_FORMAT_ATTRIBUTE_NAME; + +@ImgLoaderIo( format = "bdv.n5.s3", type = N5FSImageLoader.class ) +public class XmlIoN5S3ImageLoader implements XmlIoBasicImgLoader< N5S3ImageLoader > +{ + public static final String SERVICE_ENDPOINT = "ServiceEndpoint"; + public static final String SIGNING_REGION = "SigningRegion"; + public static final String BUCKET_NAME = "BucketName"; + public static final String KEY = "Key"; + public static final String AUTHENTICATION = "Authentication"; + + + @Override + public Element toXml( final N5S3ImageLoader imgLoader, final File basePath ) + { + final Element elem = new Element( "ImageLoader" ); + elem.setAttribute( IMGLOADER_FORMAT_ATTRIBUTE_NAME, "bdv.n5.s3" ); + elem.setAttribute( "version", "1.0" ); + elem.setAttribute( SERVICE_ENDPOINT, imgLoader.getServiceEndpoint() ); + elem.setAttribute( SIGNING_REGION, imgLoader.getSigningRegion() ); + elem.setAttribute( BUCKET_NAME, imgLoader.getBucketName() ); + elem.setAttribute( KEY, imgLoader.getKey() ); + elem.setAttribute( AUTHENTICATION, imgLoader.getAuthentication().toString() ); + + return elem; + } + + @Override + public N5S3ImageLoader fromXml( final Element elem, final File basePath, final AbstractSequenceDescription< ?, ?, ? > sequenceDescription ) + { +// final String version = elem.getAttributeValue( "version" ); + + final String serviceEndpoint = XmlHelpers.getText( elem, SERVICE_ENDPOINT ); + final String signingRegion = XmlHelpers.getText( elem, SIGNING_REGION ); + final String bucketName = XmlHelpers.getText( elem, BUCKET_NAME ); + final String key = XmlHelpers.getText( elem, KEY ); + final Authentication authentication = Authentication.valueOf( XmlHelpers.getText( elem, AUTHENTICATION ) ); + + + try + { + return new N5S3ImageLoader( serviceEndpoint, signingRegion, bucketName, key, authentication, sequenceDescription ); + } + catch ( IOException e ) + { + throw new RuntimeException( e ); + } + } +} diff --git a/src/test/java/bdv/n5/N5S3Example.java b/src/test/java/bdv/n5/N5S3Example.java new file mode 100644 index 000000000..a2e74cd04 --- /dev/null +++ b/src/test/java/bdv/n5/N5S3Example.java @@ -0,0 +1,13 @@ +package bdv.n5; + +import bdv.BigDataViewer; +import bdv.viewer.ViewerOptions; +import mpicbg.spim.data.SpimDataException; + +public class N5S3Example +{ + public static void main( String[] args ) throws SpimDataException + { + BigDataViewer.open( "https://raw.githubusercontent.com/platybrowser/platybrowser/master/data/1.0.1/images/remote/prospr-6dpf-1-whole-ache.xml", "", null, ViewerOptions.options().numRenderingThreads( 3 ) ); + } +}