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