Author: mreutegg
Date: Wed Jul 25 15:46:58 2018
New Revision: 1836642

URL: http://svn.apache.org/viewvc?rev=1836642&view=rev
Log:
OAK-7603: [DirectBinaryAccess] Oak API extensions

Additions to oak-api proposed by Matt Ryan

Added:
    
jackrabbit/oak/trunk/oak-api/src/main/java/org/apache/jackrabbit/oak/api/blob/
    
jackrabbit/oak/trunk/oak-api/src/main/java/org/apache/jackrabbit/oak/api/blob/BlobAccessProvider.java
   (with props)
    
jackrabbit/oak/trunk/oak-api/src/main/java/org/apache/jackrabbit/oak/api/blob/BlobDownloadOptions.java
   (with props)
    
jackrabbit/oak/trunk/oak-api/src/main/java/org/apache/jackrabbit/oak/api/blob/BlobUpload.java
   (with props)
    
jackrabbit/oak/trunk/oak-api/src/main/java/org/apache/jackrabbit/oak/api/blob/package-info.java
   (with props)

Added: 
jackrabbit/oak/trunk/oak-api/src/main/java/org/apache/jackrabbit/oak/api/blob/BlobAccessProvider.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-api/src/main/java/org/apache/jackrabbit/oak/api/blob/BlobAccessProvider.java?rev=1836642&view=auto
==============================================================================
--- 
jackrabbit/oak/trunk/oak-api/src/main/java/org/apache/jackrabbit/oak/api/blob/BlobAccessProvider.java
 (added)
+++ 
jackrabbit/oak/trunk/oak-api/src/main/java/org/apache/jackrabbit/oak/api/blob/BlobAccessProvider.java
 Wed Jul 25 15:46:58 2018
@@ -0,0 +1,128 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.jackrabbit.oak.api.blob;
+
+import java.net.URI;
+
+import org.apache.jackrabbit.oak.api.Blob;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.osgi.annotation.versioning.ProviderType;
+
+/**
+ * Extension interface applied to a class that indicates that the class
+ * implements the direct upload and direct download feature for {@link Blob}s.
+ */
+@ProviderType
+public interface BlobAccessProvider {
+
+    /**
+     * Begin a transaction to perform a direct blob upload to a storage
+     * location. This method will throw {@link IllegalArgumentException} if no
+     * valid upload can be arranged with the arguments specified. E.g. the max
+     * upload size specified divided by the number of URIs requested indicates
+     * the minimum size of each upload. If that size exceeds the maximum upload
+     * size supported by the service provider, {@link IllegalArgumentException}
+     * is thrown.
+     * <p>
+     * Each service provider has specific limitations with regard to maximum
+     * upload sizes, maximum overall blob sizes, numbers of URIs in multi-part
+     * uploads, etc. which can lead to {@link IllegalArgumentException} being
+     * thrown. You should consult the documentation for your specific service
+     * provider for details.
+     * <p>
+     * Beyond service provider limitations, the implementation may also choose
+     * to enforce its own limitations and may throw this exception based on
+     * those limitations. Configuration may also be used to set limitations so
+     * this exception may be thrown when configuration parameters are exceeded.
+     *
+     * @param maxUploadSizeInBytes the largest size of the blob to be
+     *         uploaded, in bytes, based on the caller's best guess.  If the
+     *         actual size of the file to be uploaded is known, that value
+     *         should be used.
+     * @param maxNumberOfURIs the maximum number of URIs the client is able to
+     *         accept. If the client does not support multi-part uploading, 
this
+     *         value should be 1. Note that the implementing class is not
+     *         required to support multi-part uploading so it may return only a
+     *         single upload URI regardless of the value passed in for this
+     *         parameter.  If the client is able to accept any number of URIs, 
a
+     *         value of -1 may be passed in to indicate that the implementation
+     *         is free to return as many URIs as it desires.
+     * @return A {@link BlobUpload} referencing this direct upload, or
+     *         {@code null} if the underlying implementation doesn't support
+     *         direct uploading.
+     * @throws IllegalArgumentException if {@code maxUploadSizeInBytes} is not
+     *         a positive value, or if {@code maxNumberOfURIs} is not either a
+     *         positive value or -1, or if the upload cannot be completed as
+     *         requested, due to a mismatch between the request parameters and
+     *         the capabilities of the service provider or the implementation.
+     */
+    @Nullable
+    BlobUpload initiateBlobUpload(long maxUploadSizeInBytes,
+                                  int maxNumberOfURIs)
+            throws IllegalArgumentException;
+
+    /**
+     * Complete a transaction for uploading a blob to a storage location via
+     * direct blob upload.
+     * <p>
+     * This requires an {@code uploadToken} that can be obtained from the
+     * returned {@link BlobUpload} from a previous call to {@link
+     * #initiateBlobUpload(long, int)}. This token is required to complete
+     * the transaction for an upload to be valid and complete.  The token
+     * includes encoded data about the transaction and may include a signature
+     * that will be verified by the implementation.
+     *
+     * @param uploadToken the upload token from a {@link BlobUpload} object
+     *         returned from a previous call to {@link
+     *         #initiateBlobUpload(long, int)}.
+     * @return The {@link Blob} that was created, or {@code null} if the object
+     *         could not be created.
+     * @throws IllegalArgumentException if the {@code uploadToken} is null,
+     *         empty, or cannot be parsed or is otherwise invalid, e.g. if the
+     *         included signature does not match.
+     */
+    @Nullable
+    Blob completeBlobUpload(@NotNull String uploadToken)
+            throws IllegalArgumentException;
+
+    /**
+     * Obtain a download URI for a {@link Blob). This is usually a signed URI
+     * that can be used to directly download the blob corresponding to the
+     * provided {@link Blob}.
+     * <p>
+     * A caller must specify a {@link BlobDownloadOptions} instance.  The
+     * implementation will attempt to apply the specified {@code
+     * downloadOptions} to the subsequent download.  For example, if the caller
+     * knows that the URI refers to a specific type of content, the caller can
+     * specify that content type by setting it in the {@code downloadOptions}.
+     * The caller may also use a default instance obtained via {@link
+     * BlobDownloadOptions#DEFAULT} in which case the caller is indicating that
+     * the default behavior of the service provider is acceptable.
+     *
+     * @param blob The {@link Blob} to be downloaded.
+     * @param downloadOptions A {@link BlobDownloadOptions} instance that
+     *         specifies any download options to be used for the download URI.
+     * @return A URI to download the blob directly or {@code null} if the blob
+     *         cannot be downloaded directly.
+     */
+    @Nullable
+    URI getDownloadURI(@NotNull Blob blob,
+                       @NotNull BlobDownloadOptions downloadOptions);
+}

Propchange: 
jackrabbit/oak/trunk/oak-api/src/main/java/org/apache/jackrabbit/oak/api/blob/BlobAccessProvider.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: 
jackrabbit/oak/trunk/oak-api/src/main/java/org/apache/jackrabbit/oak/api/blob/BlobDownloadOptions.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-api/src/main/java/org/apache/jackrabbit/oak/api/blob/BlobDownloadOptions.java?rev=1836642&view=auto
==============================================================================
--- 
jackrabbit/oak/trunk/oak-api/src/main/java/org/apache/jackrabbit/oak/api/blob/BlobDownloadOptions.java
 (added)
+++ 
jackrabbit/oak/trunk/oak-api/src/main/java/org/apache/jackrabbit/oak/api/blob/BlobDownloadOptions.java
 Wed Jul 25 15:46:58 2018
@@ -0,0 +1,118 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.jackrabbit.oak.api.blob;
+
+import org.apache.jackrabbit.oak.api.Blob;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.osgi.annotation.versioning.ProviderType;
+
+/**
+ * Download options to be provided to a call to {@link
+ * BlobAccessProvider#getDownloadURI(Blob, BlobDownloadOptions)}.
+ * <p>
+ * This object is an internal corollary to {@code
+ * org.apache.jackrabbit.api.binary.BinaryDownloadOptions}.
+ */
+@ProviderType
+public class BlobDownloadOptions {
+    private static final String DISPOSITION_TYPE_INLINE = "inline";
+
+    private final String mediaType;
+    private final String characterEncoding;
+    private final String fileName;
+    private final String dispositionType;
+
+    public static final BlobDownloadOptions DEFAULT = new 
BlobDownloadOptions();
+
+    private BlobDownloadOptions() {
+        this(null, null, null, DISPOSITION_TYPE_INLINE);
+    }
+
+    /**
+     * Creates new download options.
+     *
+     * @param mediaType the internet media type for the blob.
+     * @param characterEncoding the character encoding for the blob.
+     * @param fileName the file name for the blob.
+     * @param dispositionType the disposition type.
+     */
+    public BlobDownloadOptions(@Nullable String mediaType,
+                               @Nullable String characterEncoding,
+                               @Nullable String fileName,
+                               @NotNull String dispositionType) {
+        if (dispositionType == null) {
+            throw new NullPointerException("dispositionType must not be null");
+        }
+        this.mediaType = mediaType;
+        this.characterEncoding = characterEncoding;
+        this.fileName = fileName;
+        this.dispositionType = dispositionType;
+    }
+
+    /**
+     * Returns the internet media type that should be assumed for the blob
+     * that is to be downloaded. This value should be a valid {@code
+     * jcr:mimeType}.
+     *
+     * @return The internet media type, or {@code null} if no type has been
+     *         specified.
+     */
+    @Nullable
+    public String getMediaType() {
+        return mediaType;
+    }
+
+    /**
+     * Returns the character encoding that should be assumed for the blob that
+     * is to be downloaded. This value should be a valid {@code jcr:encoding}.
+     *
+     * @return The character encoding, or {@code null} if no encoding has been
+     *         specified.
+     */
+    @Nullable
+    public String getCharacterEncoding() {
+        return characterEncoding;
+    }
+
+    /**
+     * Returns the filename that should be assumed for the blob that is to be
+     * downloaded.
+     *
+     * @return The file name, or {@code null} if no file name has been
+     *         specified.
+     */
+    @Nullable
+    public String getFileName() {
+        return fileName;
+    }
+
+    /**
+     * Returns the disposition type that should be assumed for the binary that
+     * is to be downloaded. The default value of this setting is "inline".
+     *
+     * @return The disposition type.
+     * @see <a href="https://tools.ietf.org/html/rfc6266#section-4.2";>RFC
+     *         6266, Section 4.2</a>
+     */
+    @NotNull
+    public String getDispositionType() {
+        return dispositionType;
+    }
+}

Propchange: 
jackrabbit/oak/trunk/oak-api/src/main/java/org/apache/jackrabbit/oak/api/blob/BlobDownloadOptions.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: 
jackrabbit/oak/trunk/oak-api/src/main/java/org/apache/jackrabbit/oak/api/blob/BlobUpload.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-api/src/main/java/org/apache/jackrabbit/oak/api/blob/BlobUpload.java?rev=1836642&view=auto
==============================================================================
--- 
jackrabbit/oak/trunk/oak-api/src/main/java/org/apache/jackrabbit/oak/api/blob/BlobUpload.java
 (added)
+++ 
jackrabbit/oak/trunk/oak-api/src/main/java/org/apache/jackrabbit/oak/api/blob/BlobUpload.java
 Wed Jul 25 15:46:58 2018
@@ -0,0 +1,123 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.jackrabbit.oak.api.blob;
+
+import java.net.URI;
+import java.util.Collection;
+
+import org.jetbrains.annotations.NotNull;
+import org.osgi.annotation.versioning.ProviderType;
+
+/**
+ * An object containing information needed to complete a direct binary upload.
+ * A client wishing to perform a direct binary upload first calls {@link
+ * BlobAccessProvider#initiateBlobUpload(long, int)} which returns an
+ * instance of this type.  The client then uses the provided URIs via {@link
+ * #getUploadURIs()} to upload the binary.  After this is done, the client
+ * calls {@link BlobAccessProvider#completeBlobUpload(String)} passing
+ * in the upload token string obtained from this object via {@link
+ * #getUploadToken()}.
+ */
+@ProviderType
+public interface BlobUpload {
+    /**
+     * Returns a token that uniquely identifies this upload.  This token must 
be
+     * provided in a subsequent call to {@link
+     * BlobAccessProvider#completeBlobUpload(String)}.
+     *
+     * @return The unique upload token for this upload.
+     */
+    @NotNull
+    String getUploadToken();
+
+    /**
+     * The smallest part size the client can send in a multi-part upload (not
+     * counting the final part).  There is no guarantee made that splitting the
+     * binary into parts of this size can complete the full upload without
+     * exhausting the full supply of uploadURIs.  In other words, clients
+     * wishing to perform a multi-part upload MUST split the binary into parts
+     * of at least this size, in bytes, but clients may need to use larger part
+     * sizes in order to upload the entire binary with the number of URIs
+     * provided.
+     * <p>
+     * Note that some backends have lower-bound limits for the size of a part 
of
+     * a multi-part upload.  You should consult the documentation for your
+     * specific service provider for details.
+     *
+     * @return The smallest part size acceptable, for multi-part uploads.
+     */
+    long getMinPartSize();
+
+    /**
+     * The largest part size the client can send in a multi-part upload.  The
+     * API guarantees that splitting the file into parts of this size will 
allow
+     * the client to complete the multi-part upload without requiring more URIs
+     * than those provided, SO LONG AS the file being uploaded is not larger
+     * than the {@code maxUploadSizeInBytes} specified in the original call.
+     * <p>
+     * A smaller upload part size may also be used so long as it exceeds the
+     * value returned by {@link #getMinPartSize()}.  Such smaller values may be
+     * more desirable for clients who wish to tune uploads to match network
+     * conditions; however, the only guarantee offered by the API is that using
+     * parts of the size returned by this method will work without using more
+     * URIs than those available in the Collection returned by
+     * {@link #getUploadURIs()}.
+     * <p>
+     * If a client calls {@link
+     * BlobAccessProvider#initiateBlobUpload(long, int)} with a value of
+     * {@code maxUploadSizeInBytes} that ends up being smaller than the actual
+     * size of the binary to be uploaded, it may not be possible to complete 
the
+     * upload with the URIs provided.  The client should initiate the
+     * transaction again with the correct size.
+     * <p>
+     * Note that some backends have upper-bound limits for the size of a part 
of
+     * a multi-part upload.  You should consult the documentation for your
+     * specific service provider for details.
+     *
+     * @return The largest part size acceptable, for multi-part uploads.
+     */
+    long getMaxPartSize();
+
+    /**
+     * Returns a collection of direct-writable upload URIs for uploading a 
file,
+     * or file part in the case of multi-part uploading.  This collection may
+     * contain only a single URI in the following cases:
+     *  - If the client requested 1 as the value of {@code maxNumberOfURIs} in 
a
+     *    call to {@link
+     *    BlobAccessProvider#initiateBlobUpload(long, int)}, OR
+     *  - If the implementing data store does not support multi-part uploading,
+     *    OR
+     *  - If the client-specified value for {@code maxUploadSizeInBytes} in a
+     *    call to {@link
+     *    BlobAccessProvider#initiateBlobUpload(long, int)} is less than
+     *    or equal to the minimum supported size of a multi-part upload part.
+     * <p>
+     * If the collection contains only a single URI the client should treat 
that
+     * URI as a direct single-put upload and write the entire binary to the
+     * single URI.  Otherwise the client may choose to consume any number of
+     * URIs in the collection, up to the entire collection of URIs provided.
+     * <p>
+     * Note that ordering matters; URIs should be consumed in sequence and
+     * should not be skipped.
+     *
+     * @return ordered collection of URIs to be consumed in sequence.
+     */
+    @NotNull
+    Collection<URI> getUploadURIs();
+}

Propchange: 
jackrabbit/oak/trunk/oak-api/src/main/java/org/apache/jackrabbit/oak/api/blob/BlobUpload.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: 
jackrabbit/oak/trunk/oak-api/src/main/java/org/apache/jackrabbit/oak/api/blob/package-info.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-api/src/main/java/org/apache/jackrabbit/oak/api/blob/package-info.java?rev=1836642&view=auto
==============================================================================
--- 
jackrabbit/oak/trunk/oak-api/src/main/java/org/apache/jackrabbit/oak/api/blob/package-info.java
 (added)
+++ 
jackrabbit/oak/trunk/oak-api/src/main/java/org/apache/jackrabbit/oak/api/blob/package-info.java
 Wed Jul 25 15:46:58 2018
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Package related to direct upload/download of blobs.
+ */
+@Version("1.0.0")
+package org.apache.jackrabbit.oak.api.blob;
+
+import org.osgi.annotation.versioning.Version;
+

Propchange: 
jackrabbit/oak/trunk/oak-api/src/main/java/org/apache/jackrabbit/oak/api/blob/package-info.java
------------------------------------------------------------------------------
    svn:eol-style = native


Reply via email to