diff --git a/spotBugsExcludeFilter.xml b/spotBugsExcludeFilter.xml
index 31e4a5f86..c6b2fff2e 100644
--- a/spotBugsExcludeFilter.xml
+++ b/spotBugsExcludeFilter.xml
@@ -9,11 +9,11 @@ xsi:schemaLocation="https://github.com/spotbugs/filter/3.0.0 https://raw.githubu
-
+
-
+
diff --git a/src/main/java/com/microsoft/graph/http/CoreHttpProvider.java b/src/main/java/com/microsoft/graph/http/CoreHttpProvider.java
index 3ee61dea2..59d6b04c4 100644
--- a/src/main/java/com/microsoft/graph/http/CoreHttpProvider.java
+++ b/src/main/java/com/microsoft/graph/http/CoreHttpProvider.java
@@ -404,11 +404,6 @@ private Result processResponse(final Response re
// Call being executed
-
- if (handler != null) {
- handler.configConnection(response);
- }
-
logger.logDebug(String.format(Locale.ROOT, "Response code %d, %s",
response.code(),
response.message()));
diff --git a/src/main/java/com/microsoft/graph/http/IStatefulResponseHandler.java b/src/main/java/com/microsoft/graph/http/IStatefulResponseHandler.java
index b4343def5..893691a86 100644
--- a/src/main/java/com/microsoft/graph/http/IStatefulResponseHandler.java
+++ b/src/main/java/com/microsoft/graph/http/IStatefulResponseHandler.java
@@ -29,8 +29,6 @@
import javax.annotation.Nullable;
import javax.annotation.Nonnull;
-import okhttp3.Response;
-
/**
* The handler interface for requests having stateful response from server.
* The handler will custom the HTTP connection if needed and generate request
@@ -40,13 +38,6 @@
* @param the deserialize type for serializer
*/
public interface IStatefulResponseHandler {
- /**
- * Configure the response
- *
- * @param response the HTTP response
- */
- void configConnection(@Nonnull final Response response);
-
/**
* Generate result after receiving response
*
@@ -54,12 +45,13 @@ public interface IStatefulResponseHandler {
* @param response the HTTP connection
* @param serializer the serializer for parsing response
* @param logger the logger
+ * @param the native http client response type
* @return the result generated by this handler
* @throws Exception an exception occurs if the request was unable to complete for any reason
*/
@Nullable
- ResultType generateResult(@Nonnull final IHttpRequest request,
- @Nonnull final Response response,
+ ResultType generateResult(@Nonnull final IHttpRequest request,
+ @Nonnull final ResponseType response,
@Nonnull final ISerializer serializer,
@Nonnull final ILogger logger) throws Exception;
}
diff --git a/src/main/java/com/microsoft/graph/concurrency/IProgressCallback.java b/src/main/java/com/microsoft/graph/tasks/IProgressCallback.java
similarity index 97%
rename from src/main/java/com/microsoft/graph/concurrency/IProgressCallback.java
rename to src/main/java/com/microsoft/graph/tasks/IProgressCallback.java
index 66a295e5c..0a27f5d4f 100644
--- a/src/main/java/com/microsoft/graph/concurrency/IProgressCallback.java
+++ b/src/main/java/com/microsoft/graph/tasks/IProgressCallback.java
@@ -20,7 +20,7 @@
// THE SOFTWARE.
// ------------------------------------------------------------------------------
-package com.microsoft.graph.concurrency;
+package com.microsoft.graph.tasks;
/**
* A callback that describes how to deal with success, failure, and progress
diff --git a/src/main/java/com/microsoft/graph/concurrency/IUploadSession.java b/src/main/java/com/microsoft/graph/tasks/IUploadSession.java
similarity index 98%
rename from src/main/java/com/microsoft/graph/concurrency/IUploadSession.java
rename to src/main/java/com/microsoft/graph/tasks/IUploadSession.java
index 49e36e220..717bdde43 100644
--- a/src/main/java/com/microsoft/graph/concurrency/IUploadSession.java
+++ b/src/main/java/com/microsoft/graph/tasks/IUploadSession.java
@@ -20,7 +20,7 @@
// THE SOFTWARE.
// ------------------------------------------------------------------------------
-package com.microsoft.graph.concurrency;
+package com.microsoft.graph.tasks;
import java.util.List;
diff --git a/src/main/java/com/microsoft/graph/concurrency/ChunkedUploadRequest.java b/src/main/java/com/microsoft/graph/tasks/LargeFileUploadRequest.java
similarity index 79%
rename from src/main/java/com/microsoft/graph/concurrency/ChunkedUploadRequest.java
rename to src/main/java/com/microsoft/graph/tasks/LargeFileUploadRequest.java
index 7b9d6a10a..286c10d1a 100644
--- a/src/main/java/com/microsoft/graph/concurrency/ChunkedUploadRequest.java
+++ b/src/main/java/com/microsoft/graph/tasks/LargeFileUploadRequest.java
@@ -2,7 +2,7 @@
// Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License in the project root for license information.
// ------------------------------------------------------------------------------
-package com.microsoft.graph.concurrency;
+package com.microsoft.graph.tasks;
import java.util.List;
import java.util.Locale;
@@ -21,7 +21,7 @@
* The chunk upload request.
* @param The upload item type.
*/
-public class ChunkedUploadRequest {
+class LargeFileUploadRequest {
/**
* Content Range header name.
@@ -41,7 +41,7 @@ public class ChunkedUploadRequest {
/**
* The base request.
*/
- private final BaseRequest> baseRequest;
+ private final BaseRequest> baseRequest;
/**
* Construct the ChunkedUploadRequest
@@ -55,7 +55,7 @@ public class ChunkedUploadRequest {
* @param totalLength The total length of the input stream.
*/
@SuppressWarnings("unchecked")
- protected ChunkedUploadRequest(@Nonnull final String requestUrl,
+ protected LargeFileUploadRequest(@Nonnull final String requestUrl,
@Nonnull final IBaseClient> client,
@Nullable final List extends Option> options,
@Nonnull final byte[] chunk,
@@ -67,7 +67,7 @@ protected ChunkedUploadRequest(@Nonnull final String requestUrl,
Objects.requireNonNull(chunk, "parameter chunk cannot be null");
this.data = new byte[chunkSize];
System.arraycopy(chunk, 0, this.data, 0, chunkSize);
- this.baseRequest = new BaseRequest>(requestUrl, client, options, (Class extends ChunkedUploadResult>)(new ChunkedUploadResult<>((UploadType)null)).getClass()) {
+ this.baseRequest = new BaseRequest>(requestUrl, client, options, (Class extends LargeFileUploadResponse>)(new LargeFileUploadResponse<>((UploadType)null)).getClass()) {
};
this.baseRequest.setHttpMethod(HttpMethod.PUT);
this.baseRequest.addHeader(CONTENT_RANGE_HEADER_NAME,
@@ -86,16 +86,16 @@ protected ChunkedUploadRequest(@Nonnull final String requestUrl,
*/
@SuppressWarnings("unchecked")
@Nonnull
- public ChunkedUploadResult upload(
- @Nonnull final ChunkedUploadResponseHandler responseHandler) {
+ public LargeFileUploadResponse upload(
+ @Nonnull final LargeFileUploadResponseHandler responseHandler) {
Objects.requireNonNull(responseHandler, "parameter responseHandler cannot be null");
- ChunkedUploadResult result = null;
+ LargeFileUploadResponse result = null;
try {
result = this.baseRequest
.getClient()
.getHttpProvider()
- .send(baseRequest, (Class>)(Class>) ChunkedUploadResult.class, this.data, responseHandler);
+ .send(baseRequest, (Class>)(Class>) LargeFileUploadResponse.class, this.data, responseHandler);
} catch (final ClientException e) {
throw new ClientException("Request failed with error, retry if necessary.", e);
}
@@ -103,7 +103,7 @@ public ChunkedUploadResult upload(
if (result != null && result.chunkCompleted()) {
return result;
} else
- return new ChunkedUploadResult(
+ return new LargeFileUploadResponse(
new ClientException("Upload session failed.", result == null ? null : result.getError()));
}
}
diff --git a/src/main/java/com/microsoft/graph/concurrency/ChunkedUploadResult.java b/src/main/java/com/microsoft/graph/tasks/LargeFileUploadResponse.java
similarity index 65%
rename from src/main/java/com/microsoft/graph/concurrency/ChunkedUploadResult.java
rename to src/main/java/com/microsoft/graph/tasks/LargeFileUploadResponse.java
index 7894bb55c..bbf2a53a4 100644
--- a/src/main/java/com/microsoft/graph/concurrency/ChunkedUploadResult.java
+++ b/src/main/java/com/microsoft/graph/tasks/LargeFileUploadResponse.java
@@ -2,7 +2,7 @@
// Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License in the project root for license information.
// ------------------------------------------------------------------------------
-package com.microsoft.graph.concurrency;
+package com.microsoft.graph.tasks;
import com.microsoft.graph.core.ClientException;
import com.microsoft.graph.http.GraphServiceException;
@@ -16,7 +16,11 @@
/**
* Wrapper class for different upload response from server.
*/
-public class ChunkedUploadResult {
+class LargeFileUploadResponse {
+ /**
+ * The location header from the response if provided
+ */
+ private final String location;
/**
* The uploaded item response.
*/
@@ -33,44 +37,59 @@ public class ChunkedUploadResult {
private final ClientException error;
/**
- * Construct result with item created.
+ * Constructs response with the location header.
+ *
+ * @param location The location returned by the response
+ */
+ protected LargeFileUploadResponse(@Nullable final String location) {
+ this.location = location;
+ this.error = null;
+ this.session = null;
+ this.uploadedItem = null;
+ }
+
+ /**
+ * Construct response with item created.
*
* @param uploaded The created item.
*/
- protected ChunkedUploadResult(@Nullable final UploadType uploaded) {
+ protected LargeFileUploadResponse(@Nullable final UploadType uploaded) {
this.uploadedItem = uploaded;
this.session = null;
this.error = null;
+ this.location = null;
}
/**
- * Construct result with next session.
+ * Construct response with next session.
*
* @param session The next session.
*/
- protected ChunkedUploadResult(@Nullable final IUploadSession session) {
+ protected LargeFileUploadResponse(@Nullable final IUploadSession session) {
this.session = session;
this.uploadedItem = null;
this.error = null;
+ this.location = null;
}
/**
- * Construct result with error.
+ * Construct response with error.
*
* @param error The error occurred during uploading.
*/
- protected ChunkedUploadResult(@Nullable final ClientException error) {
+ protected LargeFileUploadResponse(@Nullable final ClientException error) {
this.error = error;
this.uploadedItem = null;
this.session = null;
+ this.location = null;
}
/**
- * Construct result with server exception.
+ * Construct response with server exception.
*
* @param exception The exception received from server.
*/
- protected ChunkedUploadResult(@Nonnull final GraphServiceException exception) {
+ protected LargeFileUploadResponse(@Nonnull final GraphServiceException exception) {
this(new ClientException(Objects
.requireNonNull(exception, "parameter exception cannot be null")
.getMessage(/* verbose */ true),
@@ -78,9 +97,9 @@ protected ChunkedUploadResult(@Nonnull final GraphServiceException exception) {
}
/**
- * Checks the chunk upload is completed.
+ * Checks the large upload range is completed.
*
- * @return true if current chunk upload is completed.
+ * @return true if current large upload range is completed.
*/
public boolean chunkCompleted() {
return this.uploadedItem != null || this.session != null;
@@ -92,7 +111,7 @@ public boolean chunkCompleted() {
* @return true if the response is an item.
*/
public boolean uploadCompleted() {
- return this.uploadedItem != null;
+ return this.uploadedItem != null || this.location != null;
}
/**
@@ -133,4 +152,12 @@ public IUploadSession getSession() {
public ClientException getError() {
return this.error;
}
+ /**
+ * Get the location.
+ * @return The location.
+ */
+ @Nullable
+ public String getLocation () {
+ return this.location;
+ }
}
diff --git a/src/main/java/com/microsoft/graph/concurrency/ChunkedUploadResponseHandler.java b/src/main/java/com/microsoft/graph/tasks/LargeFileUploadResponseHandler.java
similarity index 70%
rename from src/main/java/com/microsoft/graph/concurrency/ChunkedUploadResponseHandler.java
rename to src/main/java/com/microsoft/graph/tasks/LargeFileUploadResponseHandler.java
index c571407a0..9d28bbdb4 100644
--- a/src/main/java/com/microsoft/graph/concurrency/ChunkedUploadResponseHandler.java
+++ b/src/main/java/com/microsoft/graph/tasks/LargeFileUploadResponseHandler.java
@@ -20,7 +20,7 @@
// THE SOFTWARE.
// ------------------------------------------------------------------------------
-package com.microsoft.graph.concurrency;
+package com.microsoft.graph.tasks;
import com.google.common.io.ByteStreams;
@@ -51,8 +51,8 @@
*
* @param the expected uploaded item
*/
-public class ChunkedUploadResponseHandler
- implements IStatefulResponseHandler, UploadType> {
+class LargeFileUploadResponseHandler
+ implements IStatefulResponseHandler, UploadType> {
/**
* The expected deserialized upload type
*/
@@ -65,69 +65,54 @@ public class ChunkedUploadResponseHandler
* @param uploadType the expected upload item type
* @param uploadSessionType the type of the upload session
*/
- protected ChunkedUploadResponseHandler(@Nonnull final Class uploadType, @Nonnull final Class extends IUploadSession> uploadSessionType) {
+ protected LargeFileUploadResponseHandler(@Nonnull final Class uploadType, @Nonnull final Class extends IUploadSession> uploadSessionType) {
this.deserializeTypeClass = Objects.requireNonNull(uploadType, "parameter uploadType cannot be null");
this.uploadSessionClass = Objects.requireNonNull(uploadSessionType, "parameter uploadSessionType cannot be null");
}
- /**
- * Do nothing before getting the response
- *
- * @param response The response
- */
- @Override
- public void configConnection(@Nonnull final Response response) {
- return;
- }
-
- /**
- * Generate the chunked upload response result
- *
- * @param request the HTTP request
- * @param response the HTTP response
- * @param serializer the serializer
- * @param logger the system logger
- * @return the chunked upload result, which could be either an uploaded item or error
- * @throws Exception an exception occurs if the request was unable to complete for any reason
- */
@Override
@Nullable
- public ChunkedUploadResult generateResult(
+ public LargeFileUploadResponse generateResult(
@Nonnull final IHttpRequest request,
- @Nonnull final Response response,
+ @Nonnull final ResponseType response,
@Nonnull final ISerializer serializer,
@Nonnull final ILogger logger) throws Exception {
Objects.requireNonNull(request, "parameter request cannot be null");
Objects.requireNonNull(response, "parameter response cannot be null");
Objects.requireNonNull(serializer, "parameter serializer cannot be null");
Objects.requireNonNull(logger, "parameter logger cannot be null");
- if (response.code() >= HttpResponseCode.HTTP_CLIENT_ERROR) {
+ if(!(response instanceof Response)) {
+ throw new ClientException("unsupported response type", null);
+ }
+ final Response nativeResponse = (Response)response;
+
+ if (nativeResponse.code() >= HttpResponseCode.HTTP_CLIENT_ERROR) {
logger.logDebug("Receiving error during upload, see detail on result error");
- return new ChunkedUploadResult<>(
+ return new LargeFileUploadResponse<>(
GraphServiceException.createFromResponse(request, null, serializer,
- response, logger));
- } else if (response.code() >= HTTP_OK
- && response.code() < HttpResponseCode.HTTP_MULTIPLE_CHOICES) {
- try(final ResponseBody body = response.body()) {
- final String location = response.headers().get("Location");
+ nativeResponse, logger));
+ } else if (nativeResponse.code() >= HTTP_OK
+ && nativeResponse.code() < HttpResponseCode.HTTP_MULTIPLE_CHOICES) {
+ try(final ResponseBody body = nativeResponse.body()) {
+ final String location = nativeResponse.headers().get("Location");
final MediaType contentType = body.contentType();
final String subType = contentType == null ? null : contentType.subtype();
if (subType != null && subType.contains("json")) {
return parseJsonUploadResult(body, serializer, logger);
} else if (location != null) {
logger.logDebug("Upload session is completed (Outlook), uploaded item returned.");
- return new ChunkedUploadResult<>(this.deserializeTypeClass.getDeclaredConstructor().newInstance());
+ return new LargeFileUploadResponse<>(location);
} else {
logger.logDebug("Upload session returned an unexpected response");
}
}
}
- return new ChunkedUploadResult<>(new ClientException("Received an unexpected response from the service, response code: " + response.code(), null));
+ return new LargeFileUploadResponse<>(new ClientException("Received an unexpected response from the service, response code: " + nativeResponse.code(), null));
}
@Nonnull
- private ChunkedUploadResult parseJsonUploadResult(@Nonnull final ResponseBody responseBody, @Nonnull final ISerializer serializer, @Nonnull final ILogger logger) throws IOException {
+ private LargeFileUploadResponse parseJsonUploadResult(@Nonnull final ResponseBody responseBody, @Nonnull final ISerializer serializer, @Nonnull final ILogger logger) throws IOException {
try (final InputStream in = responseBody.byteStream()) {
final byte[] responseBytes = ByteStreams.toByteArray(in);
final IUploadSession session = serializer.deserializeObject(new ByteArrayInputStream(responseBytes), uploadSessionClass);
@@ -135,10 +120,10 @@ private ChunkedUploadResult parseJsonUploadResult(@Nonnull final Res
if (session == null || session.getNextExpectedRanges() == null) {
logger.logDebug("Upload session is completed (ODSP), uploaded item returned.");
final UploadType uploadedItem = serializer.deserializeObject(new ByteArrayInputStream(responseBytes), this.deserializeTypeClass);
- return new ChunkedUploadResult<>(uploadedItem);
+ return new LargeFileUploadResponse<>(uploadedItem);
} else {
logger.logDebug("Chunk bytes has been accepted by the server.");
- return new ChunkedUploadResult<>(session);
+ return new LargeFileUploadResponse<>(session);
}
}
}
diff --git a/src/main/java/com/microsoft/graph/tasks/LargeFileUploadResult.java b/src/main/java/com/microsoft/graph/tasks/LargeFileUploadResult.java
new file mode 100644
index 000000000..b1459adbc
--- /dev/null
+++ b/src/main/java/com/microsoft/graph/tasks/LargeFileUploadResult.java
@@ -0,0 +1,22 @@
+package com.microsoft.graph.tasks;
+
+import javax.annotation.Nullable;
+
+/**
+ * Respresents the result of a large file upload task.
+ *
+ * @param type of the deserialized response.
+ */
+public class LargeFileUploadResult {
+ /**
+ * Location response header value if provided.
+ */
+ @Nullable
+ public String location;
+
+ /**
+ * Deserialized response body if the response has content.
+ */
+ @Nullable
+ public ResultType responseBody;
+}
diff --git a/src/main/java/com/microsoft/graph/concurrency/ChunkedUploadProvider.java b/src/main/java/com/microsoft/graph/tasks/LargeFileUploadTask.java
similarity index 75%
rename from src/main/java/com/microsoft/graph/concurrency/ChunkedUploadProvider.java
rename to src/main/java/com/microsoft/graph/tasks/LargeFileUploadTask.java
index ce0c61989..897cc6d0f 100644
--- a/src/main/java/com/microsoft/graph/concurrency/ChunkedUploadProvider.java
+++ b/src/main/java/com/microsoft/graph/tasks/LargeFileUploadTask.java
@@ -20,7 +20,7 @@
// THE SOFTWARE.
// ------------------------------------------------------------------------------
-package com.microsoft.graph.concurrency;
+package com.microsoft.graph.tasks;
import com.microsoft.graph.core.ClientException;
import com.microsoft.graph.core.IBaseClient;
@@ -42,7 +42,7 @@
*
* @param the upload item type
*/
-public class ChunkedUploadProvider {
+public class LargeFileUploadTask {
/**
* The default chunk size for upload. Currently set to 5 MiB.
@@ -83,7 +83,7 @@ public class ChunkedUploadProvider {
/**
* The upload response handler
*/
- private final ChunkedUploadResponseHandler responseHandler;
+ private final LargeFileUploadResponseHandler responseHandler;
/**
* The counter for how many bytes have been read from input stream
@@ -99,7 +99,7 @@ public class ChunkedUploadProvider {
* @param streamSize the stream size
* @param uploadTypeClass the upload type class
*/
- public ChunkedUploadProvider(@Nonnull final IUploadSession uploadSession,
+ public LargeFileUploadTask(@Nonnull final IUploadSession uploadSession,
@Nonnull final IBaseClient> client,
@Nonnull final InputStream inputStream,
final long streamSize,
@@ -115,7 +115,7 @@ public ChunkedUploadProvider(@Nonnull final IUploadSession uploadSession,
this.inputStream = Objects.requireNonNull(inputStream, "Input stream is null.");
this.streamSize = streamSize;
this.uploadUrl = uploadSession.getUploadUrl();
- this.responseHandler = new ChunkedUploadResponseHandler(uploadTypeClass, uploadSession.getClass());
+ this.responseHandler = new LargeFileUploadResponseHandler(uploadTypeClass, uploadSession.getClass());
}
/**
@@ -128,7 +128,7 @@ public ChunkedUploadProvider(@Nonnull final IUploadSession uploadSession,
* @throws IOException the IO exception that occurred during upload
*/
@Nonnull
- public java.util.concurrent.CompletableFuture uploadAsync(@Nullable final int chunkSize, @Nullable final List