diff --git a/src/main/java/com/microsoft/graph/concurrency/ChunkedUploadProvider.java b/src/main/java/com/microsoft/graph/concurrency/ChunkedUploadProvider.java index d3aafbbc3..8e9ce8f33 100644 --- a/src/main/java/com/microsoft/graph/concurrency/ChunkedUploadProvider.java +++ b/src/main/java/com/microsoft/graph/concurrency/ChunkedUploadProvider.java @@ -22,10 +22,6 @@ package com.microsoft.graph.concurrency; -import com.microsoft.graph.concurrency.ChunkedUploadResponseHandler; -import com.microsoft.graph.concurrency.ChunkedUploadRequest; -import com.microsoft.graph.concurrency.ChunkedUploadResult; -import com.microsoft.graph.concurrency.IUploadSession; import com.microsoft.graph.core.ClientException; import com.microsoft.graph.core.IBaseClient; import com.microsoft.graph.options.Option; @@ -66,7 +62,7 @@ public class ChunkedUploadProvider { /** * The client */ - private final IBaseClient client; + private final IBaseClient client; /** * The input stream @@ -103,7 +99,7 @@ public class ChunkedUploadProvider { * @param uploadTypeClass the upload type class */ public ChunkedUploadProvider(@Nonnull final IUploadSession uploadSession, - @Nonnull final IBaseClient client, + @Nonnull final IBaseClient client, @Nonnull final InputStream inputStream, final long streamSize, @Nonnull final Class uploadTypeClass) { @@ -173,7 +169,7 @@ public java.util.concurrent.CompletableFuture uploadAsync(@Nullable } final ChunkedUploadRequest request = - new ChunkedUploadRequest(this.uploadUrl, this.client, options, buffer, buffRead, + new ChunkedUploadRequest<>(this.uploadUrl, this.client, options, buffer, buffRead, this.readSoFar, this.streamSize); final ChunkedUploadResult result = request.upload(this.responseHandler); // TODO: upload should return a future, use sendfuture instead and the futures should be chained with completableFuture.then apply diff --git a/src/main/java/com/microsoft/graph/concurrency/ChunkedUploadRequest.java b/src/main/java/com/microsoft/graph/concurrency/ChunkedUploadRequest.java index e0e0f861b..badb00375 100644 --- a/src/main/java/com/microsoft/graph/concurrency/ChunkedUploadRequest.java +++ b/src/main/java/com/microsoft/graph/concurrency/ChunkedUploadRequest.java @@ -10,7 +10,6 @@ import javax.annotation.Nullable; import javax.annotation.Nonnull; -import com.microsoft.graph.concurrency.ChunkedUploadResponseHandler; import com.microsoft.graph.core.ClientException; import com.microsoft.graph.http.BaseRequest; import com.microsoft.graph.http.HttpMethod; @@ -56,7 +55,7 @@ public class ChunkedUploadRequest { */ @SuppressWarnings("unchecked") protected ChunkedUploadRequest(@Nonnull final String requestUrl, - @Nonnull final IBaseClient client, + @Nonnull final IBaseClient client, @Nullable final List options, @Nonnull final byte[] chunk, final int chunkSize, diff --git a/src/main/java/com/microsoft/graph/content/BatchRequest.java b/src/main/java/com/microsoft/graph/content/BatchRequest.java new file mode 100644 index 000000000..ce65cdb42 --- /dev/null +++ b/src/main/java/com/microsoft/graph/content/BatchRequest.java @@ -0,0 +1,85 @@ +// ------------------------------------------------------------------------------ +// Copyright (c) 2021 Microsoft Corporation +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sub-license, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// ------------------------------------------------------------------------------ + +package com.microsoft.graph.content; + +import java.util.List; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +import com.microsoft.graph.core.ClientException; +import com.microsoft.graph.core.IBaseClient; +import com.microsoft.graph.http.BaseRequest; +import com.microsoft.graph.http.HttpMethod; +import com.microsoft.graph.options.Option; + +/** Request for batch requests */ +public class BatchRequest extends BaseRequest { + + /** + * Instantiates a new batch request + * + * @param requestUrl the URL to send the request to + * @param client the client to use to execute the request + * @param options the options to apply to the request + */ + public BatchRequest(@Nonnull final String requestUrl, @Nonnull final IBaseClient client, @Nonnull final List options) { + super(requestUrl, client, options, BatchResponseContent.class); + } + + /** + * Send this request + * + * @return the response object + * @param content content of the batch request to execute + * @throws ClientException an exception occurs if there was an error while the request was sent + */ + @Nullable + public BatchResponseContent post(@Nonnull final BatchRequestContent content) throws ClientException { + this.setHttpMethod(HttpMethod.POST); + final BatchResponseContent response = this.getClient().getHttpProvider().send(this, BatchResponseContent.class, content); + setSerializerOnSteps(response); + return response; + } + /** + * Send this request + * + * @return the response object + * @param content content of the batch request to execute + * @throws ClientException an exception occurs if there was an error while the request was sent + */ + @Nullable + public java.util.concurrent.CompletableFuture postAsync(@Nonnull final BatchRequestContent content) throws ClientException { + this.setHttpMethod(HttpMethod.POST); + return this.getClient().getHttpProvider().sendAsync(this, BatchResponseContent.class, content).thenApply(response -> { + setSerializerOnSteps(response); + return response; + }); + } + private void setSerializerOnSteps(final BatchResponseContent response) { + if(response.responses != null) + for(final BatchResponseStep step : response.responses) { + step.serializer = this.getClient().getSerializer(); + } + } +} diff --git a/src/main/java/com/microsoft/graph/content/BatchRequestBuilder.java b/src/main/java/com/microsoft/graph/content/BatchRequestBuilder.java new file mode 100644 index 000000000..731dfd9aa --- /dev/null +++ b/src/main/java/com/microsoft/graph/content/BatchRequestBuilder.java @@ -0,0 +1,66 @@ +// ------------------------------------------------------------------------------ +// Copyright (c) 2021 Microsoft Corporation +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sub-license, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// ------------------------------------------------------------------------------ + +package com.microsoft.graph.content; + +import java.util.List; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +import com.microsoft.graph.core.IBaseClient; +import com.microsoft.graph.http.BaseRequestBuilder; +import com.microsoft.graph.options.Option; + +/** Request builder for batch requests */ +public class BatchRequestBuilder extends BaseRequestBuilder { + /** + * Instantiates a new batch request builder + * @param requestUrl the URL for the request + * @param client the client to use to execute the request + * @param options the request options + */ + public BatchRequestBuilder(@Nonnull final String requestUrl, @Nonnull final IBaseClient client, @Nonnull final List options) { + super(requestUrl, client, options); + } + /** + * Creates the request + * + * @param requestOptions the options for this request + * @return the IUserRequest instance + */ + @Nonnull + public BatchRequest buildRequest(@Nullable final com.microsoft.graph.options.Option... requestOptions) { + return buildRequest(getOptions(requestOptions)); + } + + /** + * Creates the request + * + * @param requestOptions the options for this request + * @return the IUserRequest instance + */ + @Nonnull + public BatchRequest buildRequest(@Nonnull final java.util.List requestOptions) { + return new BatchRequest(this.getRequestUrl(), getClient(), requestOptions); + } +} diff --git a/src/main/java/com/microsoft/graph/content/BatchRequestContent.java b/src/main/java/com/microsoft/graph/content/BatchRequestContent.java new file mode 100644 index 000000000..8a6f7d163 --- /dev/null +++ b/src/main/java/com/microsoft/graph/content/BatchRequestContent.java @@ -0,0 +1,184 @@ +// ------------------------------------------------------------------------------ +// Copyright (c) 2021 Microsoft Corporation +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sub-license, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// ------------------------------------------------------------------------------ + +package com.microsoft.graph.content; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Locale; +import java.util.Objects; +import java.util.concurrent.ThreadLocalRandom; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; +import com.microsoft.graph.http.HttpMethod; +import com.microsoft.graph.http.IHttpRequest; +import com.microsoft.graph.options.HeaderOption; +import com.microsoft.graph.serializer.IJsonBackedObject; + +/** Respresents the content of a JSON batch request */ +public class BatchRequestContent { + /** Steps part of the batch request */ + @Expose + @Nullable + @SerializedName("requests") + public List> requests; + + /** + * Adds a request as a step to the current batch. Defaults to GET if the HTTP method is not set in the request. + * @param request the request to add as a step + * @return the id of the step that was just added to the batch + */ + @Nonnull + public String addBatchRequestStep(@Nonnull final IHttpRequest request) { + Objects.requireNonNull(request, "request parameter cannot be null"); + return addBatchRequestStep(request, request.getHttpMethod() == null ? HttpMethod.GET : request.getHttpMethod()); + } + /** + * Adds a request as a step to the current batch + * @param request the request to add as a step + * @param httpMethod the HttpMethod to execute the request with + * @return the id of the step that was just added to the batch + */ + @Nonnull + public String addBatchRequestStep(@Nonnull final IHttpRequest request, @Nonnull final HttpMethod httpMethod) { + return addBatchRequestStep(request, httpMethod, null); + } + /** + * Adds a request as a step to the current batch + * @param request the request to add as a step + * @param httpMethod the HttpMethod to execute the request with + * @param the type of the request body + * @param serializableBody the body of the request to be serialized + * @return the id of the step that was just added to the batch + */ + @Nonnull + public String addBatchRequestStep(@Nonnull final IHttpRequest request, @Nonnull final HttpMethod httpMethod, @Nullable final T serializableBody) { + return addBatchRequestStep(request, httpMethod, serializableBody, (String[])null); + } + /** + * Adds a request as a step to the current batch + * @param request the request to add as a step + * @param httpMethod the HttpMethod to execute the request with + * @param the type of the request body + * @param serializableBody the body of the request to be serialized + * @param dependsOnRequestsIds the ids of steps this request depends on + * @return the id of the step that was just added to the batch + */ + @Nonnull + public String addBatchRequestStep(@Nonnull final IHttpRequest request, @Nonnull final HttpMethod httpMethod, @Nullable final T serializableBody, @Nullable final String ...dependsOnRequestsIds) { + Objects.requireNonNull(request, "request parameter cannot be null"); + Objects.requireNonNull(httpMethod, "httpMethod parameter cannot be null"); + if(dependsOnRequestsIds != null) + for(final String id : dependsOnRequestsIds) { + if(getStepById(id) == null) + throw new IllegalArgumentException("the current request depends on a inexisting request"); + } + + if(requests == null) + requests = new ArrayList<>(); + + final Matcher protocolAndHostReplacementMatcher = protocolAndHostReplacementPattern.matcher(request.getRequestUrl().toString()); + final BatchRequestStep step = new BatchRequestStep() {{ + url = protocolAndHostReplacementMatcher.replaceAll(""); + body = serializableBody; + method = httpMethod.toString().toUpperCase(Locale.getDefault()); + dependsOn = dependsOnRequestsIds != null && dependsOnRequestsIds.length > 0 ? new HashSet(Arrays.asList(dependsOnRequestsIds)) : null; + id = getNextRequestId(); + }}; + + if(!request.getHeaders().isEmpty()) { + step.headers = new HashMap<>(); + for(final HeaderOption headerOption : request.getHeaders()) + step.headers.putIfAbsent(headerOption.getName().toLowerCase(Locale.getDefault()), headerOption.getValue().toString()); + } + if(step.body != null && step.body instanceof IJsonBackedObject && + (step.headers == null || !step.headers.containsKey(contentTypeHeaderKey))) { + if(step.headers == null) + step.headers = new HashMap<>(); + step.headers.putIfAbsent(contentTypeHeaderKey, "application/json"); + } + requests.add(step); + return step.id; + } + private static final String contentTypeHeaderKey = "content-type"; + /** + * Removes requests from the requests to be executed by the batch. Also removes any dependency references that might exist. + * @param stepIds ids of steps to be removed. + */ + public void removeBatchRequestStepWithId(@Nonnull final String ...stepIds) { + if(requests == null) return; + + for(final String stepId : stepIds) { + Objects.requireNonNull(stepId, "parameter stepIds cannot contain null values"); + requests.removeIf(x -> x.id == stepId); + for(final BatchRequestStep step : requests) { + if(step.dependsOn != null) { + step.dependsOn.removeIf(x -> x == stepId); + if(step.dependsOn.isEmpty()) + step.dependsOn = null; // so we don't send dependsOn: [] over the wire + } + } + } + } + /** + * Gets a step by its step id + * @param the type of the request body + * @param stepId the request step id returned from the add method + * @return the request corresponding to the provided id or null + */ + @Nullable + @SuppressWarnings("unchecked") + public BatchRequestStep getStepById(@Nonnull final String stepId) { + Objects.requireNonNull(stepId, "parameter stepId cannot be null"); + if(requests == null) return null; + + for(final BatchRequestStep step : requests) { + if(stepId.equals(step.id)) + return (BatchRequestStep)step; + } + return null; + } + /** pattern to replace the protocol and host part of the request if specified */ + @Nonnull + protected static final Pattern protocolAndHostReplacementPattern = Pattern.compile("(?i)^http[s]?:\\/\\/graph\\.microsoft\\.com\\/(?>v1\\.0|beta)\\/?"); // (?i) case insensitive + /** + * Generates a randomly available request id + * @return a random request id + */ + @Nonnull + protected String getNextRequestId() { + String requestId; + do { + requestId = Integer.toString(ThreadLocalRandom.current().nextInt(1, Integer.MAX_VALUE)); + } while(getStepById(requestId) != null); + return requestId; + } +} diff --git a/src/main/java/com/microsoft/graph/content/BatchRequestStep.java b/src/main/java/com/microsoft/graph/content/BatchRequestStep.java new file mode 100644 index 000000000..cb6ae415a --- /dev/null +++ b/src/main/java/com/microsoft/graph/content/BatchRequestStep.java @@ -0,0 +1,49 @@ +// ------------------------------------------------------------------------------ +// Copyright (c) 2021 Microsoft Corporation +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sub-license, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// ------------------------------------------------------------------------------ + +package com.microsoft.graph.content; + +import java.util.HashSet; + +import javax.annotation.Nullable; + +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; + +/** the http request for the batch step */ +public class BatchRequestStep extends BatchStep { + /** The URL to query for the step */ + @Nullable + @Expose + @SerializedName("url") + public String url; + /** The HTTP method to use to execute the request */ + @Nullable + @Expose + @SerializedName("method") + public String method; + /** The IDs of the steps this step depends on before being executed */ + @Nullable + @Expose + @SerializedName("dependsOn") + public HashSet dependsOn; +} diff --git a/src/main/java/com/microsoft/graph/content/BatchResponseContent.java b/src/main/java/com/microsoft/graph/content/BatchResponseContent.java new file mode 100644 index 000000000..fe8022524 --- /dev/null +++ b/src/main/java/com/microsoft/graph/content/BatchResponseContent.java @@ -0,0 +1,59 @@ +// ------------------------------------------------------------------------------ +// Copyright (c) 2021 Microsoft Corporation +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sub-license, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// ------------------------------------------------------------------------------ + +package com.microsoft.graph.content; + +import java.util.List; +import java.util.Objects; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +import com.google.gson.JsonElement; +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; + +/** Respresents the result of a JSON batch request */ +public class BatchResponseContent { + /** Responses to the steps from the request */ + @Nullable + @Expose + @SerializedName("responses") + public List> responses; + + /** + * Gets a response to a request in the batch by its id + * @param stepId Id of the request step in the batch request + * @return The step response corresponding to the ID or null + */ + @Nullable + public BatchResponseStep getResponseById(@Nonnull final String stepId) { + Objects.requireNonNull(stepId, "parameter stepId cannot be null"); + if(responses == null) return null; + + for(final BatchResponseStep step : responses) { + if(stepId.equals(step.id)) + return step; + } + return null; + } +} diff --git a/src/main/java/com/microsoft/graph/content/BatchResponseStep.java b/src/main/java/com/microsoft/graph/content/BatchResponseStep.java new file mode 100644 index 000000000..feb1d13a1 --- /dev/null +++ b/src/main/java/com/microsoft/graph/content/BatchResponseStep.java @@ -0,0 +1,67 @@ +// ------------------------------------------------------------------------------ +// Copyright (c) 2021 Microsoft Corporation +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sub-license, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// ------------------------------------------------------------------------------ +package com.microsoft.graph.content; + +import java.util.ArrayList; +import java.util.Objects; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +import com.google.gson.JsonElement; +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; +import com.microsoft.graph.http.GraphErrorResponse; +import com.microsoft.graph.http.GraphFatalServiceException; +import com.microsoft.graph.http.GraphServiceException; +import com.microsoft.graph.serializer.ISerializer; + +/** Response for the batch step */ +public class BatchResponseStep extends BatchStep { + /** Http status code of the response */ + @Expose + @SerializedName("status") + public int status; + /** Serializer to use for response deserialization */ + @Nullable + protected ISerializer serializer; + + /** + * Returned the deserialized response body of the current step + * @param type of the response body + * @param resultClass class of the resulting response body + * @return the deserialized response body + * @throws GraphServiceException when a bad request was sent + * @throws GraphFatalServiceException when the service did not complete the operation as expected because of an internal error + */ + @Nullable + public T2 getDeserializedBody(@Nonnull final Class resultClass) throws GraphServiceException, GraphFatalServiceException { + Objects.requireNonNull(resultClass, "parameter resultClass cannot be null"); + if(serializer == null || body == null || !(body instanceof JsonElement)) return null; + + final GraphErrorResponse error = serializer.deserializeObject((JsonElement)body, GraphErrorResponse.class); + if(error == null || error.error == null) { + return serializer.deserializeObject((JsonElement)body, resultClass); + } else + throw GraphServiceException.createFromResponse("", "", new ArrayList<>(), "", headers, "", status, error, false); + } +} diff --git a/src/main/java/com/microsoft/graph/content/BatchStep.java b/src/main/java/com/microsoft/graph/content/BatchStep.java new file mode 100644 index 000000000..89773904e --- /dev/null +++ b/src/main/java/com/microsoft/graph/content/BatchStep.java @@ -0,0 +1,49 @@ +// ------------------------------------------------------------------------------ +// Copyright (c) 2021 Microsoft Corporation +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sub-license, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// ------------------------------------------------------------------------------ + +package com.microsoft.graph.content; + +import java.util.HashMap; + +import javax.annotation.Nullable; + +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; + +/** Common abstractions between batch request steps and batch response steps */ +public abstract class BatchStep { + /** The Id of the step */ + @Expose + @Nullable + @SerializedName("id") + public String id; + /** The request/response headers for the step */ + @Expose + @Nullable + @SerializedName("headers") + public HashMap headers; + /** The body of request/response for the step */ + @Nullable + @Expose + @SerializedName("body") + public T body; +} diff --git a/src/main/java/com/microsoft/graph/content/MSBatchRequestContent.java b/src/main/java/com/microsoft/graph/content/MSBatchRequestContent.java deleted file mode 100644 index 013f47509..000000000 --- a/src/main/java/com/microsoft/graph/content/MSBatchRequestContent.java +++ /dev/null @@ -1,242 +0,0 @@ -package com.microsoft.graph.content; - -import java.io.IOException; -import java.util.HashSet; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ThreadLocalRandom; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import javax.annotation.Nullable; -import javax.annotation.Nonnull; - -import com.google.gson.JsonArray; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParser; -import com.google.gson.JsonPrimitive; -import com.microsoft.graph.core.ClientException; -import com.microsoft.graph.core.IBaseClient; -import com.microsoft.graph.logger.DefaultLogger; -import com.microsoft.graph.logger.ILogger; -import com.google.gson.JsonParseException; - -import okhttp3.Headers; -import okhttp3.Request; -import okhttp3.RequestBody; -import okio.Buffer; - -/** - * Represents the content of a batch request - */ -public class MSBatchRequestContent { - private final LinkedHashMap batchRequestStepsHashMap; - - /** - * Maximum number of requests that can be sent in a batch - */ - public static final int MAX_NUMBER_OF_REQUESTS = 20; - private final ILogger logger; - - /** - * Creates Batch request content using list provided - * - * @param batchRequestStepsArray List of batch steps for batching - */ - public MSBatchRequestContent(@Nonnull final MSBatchRequestStep... batchRequestStepsArray) { - this(new DefaultLogger(), batchRequestStepsArray); - } - - /** - * Creates Batch request content using list provided - * - * @param batchRequestStepsArray List of batch steps for batching - * @param logger logger to use for telemetry - */ - public MSBatchRequestContent(@Nonnull final ILogger logger, @Nonnull final MSBatchRequestStep... batchRequestStepsArray) { - if (batchRequestStepsArray.length > MAX_NUMBER_OF_REQUESTS) - throw new IllegalArgumentException("Number of batch request steps cannot exceed " + MAX_NUMBER_OF_REQUESTS); - - this.logger = Objects.requireNonNull(logger, "logger cannot be null"); - - this.batchRequestStepsHashMap = new LinkedHashMap<>(); - for (final MSBatchRequestStep requestStep : batchRequestStepsArray) - if(requestStep != null) - addBatchRequestStep(requestStep); - } - - /** - * Adds a step to the current batch - * @param batchRequestStep Batch request step adding to batch content - * @return true or false based on addition or no addition of batch request step - * given - */ - public boolean addBatchRequestStep(@Nonnull final MSBatchRequestStep batchRequestStep) { - Objects.requireNonNull(batchRequestStep, "batchRequestStep parameter cannot be null"); - if (batchRequestStepsHashMap.containsKey(batchRequestStep.getRequestId()) || - batchRequestStepsHashMap.size() >= MAX_NUMBER_OF_REQUESTS) - return false; - batchRequestStepsHashMap.put(batchRequestStep.getRequestId(), batchRequestStep); - return true; - } - - /** - * Add steps to batch from OkHttp.Request - * @param request the request to add to the batch - * @param arrayOfDependsOnIds ids of steps this step depends on - * @return the step id - */ - @Nonnull - public String addBatchRequestStep(@Nonnull final Request request, @Nullable final String... arrayOfDependsOnIds) { - Objects.requireNonNull(request, "request parameter cannot be null"); - String requestId; - do { - requestId = Integer.toString(ThreadLocalRandom.current().nextInt(1, Integer.MAX_VALUE)); - } while(batchRequestStepsHashMap.keySet().contains(requestId)); - if(addBatchRequestStep(new MSBatchRequestStep(requestId, request, arrayOfDependsOnIds))) - return requestId; - else - throw new IllegalArgumentException("unable to add step to batch. Number of batch request steps cannot exceed " + MAX_NUMBER_OF_REQUESTS); - } - - /** - * @param requestId Id of Batch request step to be removed - * - * @return true or false based on removal or no removal of batch request step - * with given id - */ - public boolean removeBatchRequestStepWithId(@Nonnull final String requestId) { - boolean removed = false; - if (batchRequestStepsHashMap.containsKey(requestId)) { - batchRequestStepsHashMap.remove(requestId); - removed = true; - for (final Map.Entry steps : batchRequestStepsHashMap.entrySet()) { - if (steps.getValue() != null && steps.getValue().getDependsOnIds() != null) { - while (steps.getValue().getDependsOnIds().remove(requestId)) - ; - } - } - } - return removed; - } - - private JsonObject getBatchRequestContentAsJson() { - final JsonObject batchRequestContentMap = new JsonObject(); - final JsonArray batchContentArray = new JsonArray(); - for (final Map.Entry requestStep : batchRequestStepsHashMap.entrySet()) { - batchContentArray.add(getBatchRequestObjectFromRequestStep(requestStep.getValue())); - } - batchRequestContentMap.add("requests", batchContentArray); - return batchRequestContentMap; - } - /** - * @return Batch request content's json as String - */ - @Nonnull - public String getBatchRequestContent() { - return getBatchRequestContentAsJson().toString(); - } - - /** - * Executes the batch requests and returns the response - * @param client client to use for the request - * @return the batch response - * @throws ClientException when the batch couldn't be executed because of client issues. - */ - @Nonnull - public MSBatchResponseContent execute(@Nonnull final IBaseClient client) { - final JsonObject content = getBatchRequestContentAsJson(); - return new MSBatchResponseContent(logger, client.getServiceRoot() + "/", - content, - client.customRequest("/$batch") - .buildRequest() - .post(content) - .getAsJsonObject()); - } - /** - * Executes the batch requests asynchronously and returns the response - * @param client client to use for the request - * @return a future with the batch response - */ - @Nonnull - public CompletableFuture executeAsync(@Nonnull final IBaseClient client) { - Objects.requireNonNull(client, "client parameter cannot be null"); - final JsonObject content = getBatchRequestContentAsJson(); - return client.customRequest("/$batch") - .buildRequest() - .postAsync(content) - .thenApply(resp -> new MSBatchResponseContent(logger, client.getServiceRoot() + "/", content, resp.getAsJsonObject())); - } - - private static final Pattern protocolAndHostReplacementPattern = Pattern.compile("(?i)^http[s]?:\\/\\/graph\\.microsoft\\.com\\/(?>v1\\.0|beta)\\/?"); // (?i) case insensitive - private JsonObject getBatchRequestObjectFromRequestStep(final MSBatchRequestStep batchRequestStep) { - final JsonObject contentmap = new JsonObject(); - contentmap.add("id", new JsonPrimitive(batchRequestStep.getRequestId())); - - final Matcher protocolAndHostReplacementMatcher = protocolAndHostReplacementPattern.matcher(batchRequestStep.getRequest().url().toString()); - - final String url = protocolAndHostReplacementMatcher.replaceAll(""); - contentmap.add("url", new JsonPrimitive(url)); - - contentmap.add("method", new JsonPrimitive(batchRequestStep.getRequest().method().toString())); - - final Headers headers = batchRequestStep.getRequest().headers(); - if (headers != null && headers.size() != 0) { - final JsonObject headerMap = new JsonObject(); - for (final Map.Entry> entry : headers.toMultimap().entrySet()) { - headerMap.add(entry.getKey(), new JsonPrimitive(getHeaderValuesAsString(entry.getValue()))); - } - contentmap.add("headers", headerMap); - } - - final HashSet arrayOfDependsOnIds = batchRequestStep.getDependsOnIds(); - if (arrayOfDependsOnIds != null) { - final JsonArray array = new JsonArray(arrayOfDependsOnIds.size()); - for (final String dependsOnId : arrayOfDependsOnIds) - array.add(dependsOnId); - contentmap.add("dependsOn", array); - } - - final RequestBody body = batchRequestStep.getRequest().body(); - if (body != null) { - try { - contentmap.add("body", requestBodyToJSONObject(batchRequestStep.getRequest())); - } catch (IOException | JsonParseException e) { - logger.logError("error pasing the request JSON body", e); - } - } - return contentmap; - } - - private String getHeaderValuesAsString(final List list) { - if (list == null || list.size() == 0) - return ""; - final StringBuilder builder = new StringBuilder(list.get(0)); - for (int i = 1; i < list.size(); i++) { - builder.append(";"); - builder.append(list.get(i)); - } - return builder.toString(); - } - - private JsonObject requestBodyToJSONObject(final Request request) throws IOException, JsonParseException { - if (request == null || request.body() == null) - return null; - final Request copy = request.newBuilder().build(); - final Buffer buffer = new Buffer(); - copy.body().writeTo(buffer); - final String requestBody = buffer.readUtf8(); - if(requestBody == null || requestBody == "") - return null; - final JsonElement requestBodyElement = JsonParser.parseString(requestBody); - if(requestBodyElement == null || !requestBodyElement.isJsonObject()) - return null; - else - return requestBodyElement.getAsJsonObject(); - } - -} diff --git a/src/main/java/com/microsoft/graph/content/MSBatchRequestStep.java b/src/main/java/com/microsoft/graph/content/MSBatchRequestStep.java deleted file mode 100644 index edb36b9d7..000000000 --- a/src/main/java/com/microsoft/graph/content/MSBatchRequestStep.java +++ /dev/null @@ -1,62 +0,0 @@ -package com.microsoft.graph.content; - -import java.util.Arrays; -import java.util.HashSet; -import java.util.Objects; - -import javax.annotation.Nullable; -import javax.annotation.Nonnull; - -import okhttp3.Request; - -/** - * Respresents a step in a batch request - */ -public class MSBatchRequestStep { - private String requestId; - private Request request; - private HashSet dependsOnIds; - - /** - * Initializes a batch step from a raw HTTP request - * @param requestId the id to assign to this step - * @param request the request to send in the batch - * @param arrayOfDependsOnIds the ids of steps this step depends on - */ - public MSBatchRequestStep(@Nonnull final String requestId, @Nonnull final Request request, @Nullable final String... arrayOfDependsOnIds) { - Objects.requireNonNull(requestId, "Request Id cannot be null."); - if(requestId.isEmpty()) - throw new IllegalArgumentException("Request Id cannot be empty."); - - this.requestId = requestId; - this.request = Objects.requireNonNull(request, "Request cannot be null."); - this.dependsOnIds = new HashSet<>(Arrays.asList(arrayOfDependsOnIds)); - } - - /** - * Gets the current step ID - * @return the current step ID - */ - @Nonnull - public String getRequestId() { - return requestId; - } - - /** - * Gets the raw HTTP request representation for the step - * @return the raw HTTP request representation for the step - */ - @Nonnull - public Request getRequest() { - return request; - } - - /** - * Gets the list of steps this step depends on - * @return the list of steps this step depends on - */ - @Nullable - public HashSet getDependsOnIds(){ - return dependsOnIds; - } -} diff --git a/src/main/java/com/microsoft/graph/content/MSBatchResponseContent.java b/src/main/java/com/microsoft/graph/content/MSBatchResponseContent.java deleted file mode 100644 index 9bdb8d242..000000000 --- a/src/main/java/com/microsoft/graph/content/MSBatchResponseContent.java +++ /dev/null @@ -1,310 +0,0 @@ -package com.microsoft.graph.content; - -import java.io.IOException; -import java.util.LinkedHashMap; -import java.util.Iterator; -import java.util.Map; -import java.util.Objects; - -import javax.annotation.Nullable; -import javax.annotation.Nonnull; - -import com.google.gson.JsonArray; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParser; -import com.microsoft.graph.logger.DefaultLogger; -import com.microsoft.graph.logger.ILogger; -import com.google.gson.JsonParseException; - -import okhttp3.MediaType; -import okhttp3.Protocol; -import okhttp3.Request; -import okhttp3.RequestBody; -import okhttp3.Response; -import okhttp3.ResponseBody; -import okio.Buffer; - -/** - * Represents the response of a batch request - */ -public class MSBatchResponseContent { - - private final Protocol protocol; - private final String message; - private LinkedHashMap batchRequestsHashMap = new LinkedHashMap<>(); - private JsonArray batchResponseArray; - private String nextLink; - private final ILogger logger; - - /** - * @param batchResponse OkHttp batch response on execution of batch requests - */ - public MSBatchResponseContent(@Nullable final Response batchResponse) { - this(new DefaultLogger(), batchResponse); - } - - /** - * @param batchResponse OkHttp batch response on execution of batch requests - * @param logger logger to use for telemetry - */ - public MSBatchResponseContent(@Nonnull final ILogger logger, @Nullable final Response batchResponse) { - this.logger = Objects.requireNonNull(logger, "logger parameter cannot be null"); - update(batchResponse); - this.message = batchResponse.message(); - this.protocol = batchResponse.protocol(); - } - /** - * instantiates a new response - * internal only, used when the content executes the requests - * @param baseUrl the base service URL without a trailing slash - * @param batchRequestData the batch request payload data as a JSON string - * @param batchResponseData the batch response body as a JSON string - * @param logger logger to use for telemetry - */ - protected MSBatchResponseContent(@Nonnull final ILogger logger, @Nonnull final String baseUrl, @Nonnull final JsonObject batchRequestData, @Nonnull final JsonObject batchResponseData) { - this.logger = logger; - this.protocol = Protocol.HTTP_1_1; - this.message = "OK"; - final Map requestMap = createBatchRequestsHashMap(baseUrl, batchRequestData); - if (requestMap != null) - batchRequestsHashMap.putAll(requestMap); - updateFromResponseBody(batchResponseData); - } - - /** - * Returns OkHttp Response of given request Id - * - * @param requestId Request Id of batch step - * - * @return OkHttp Response corresponding to requestId - */ - @Nullable - public Response getResponseById(@Nonnull final String requestId) { - if (batchResponseArray == null) - return null; - - final JsonArray responses = batchResponseArray; - - for (final JsonElement response : responses) { - if(!response.isJsonObject()) - continue; - final JsonObject jsonresponse = response.getAsJsonObject(); - final JsonElement idElement = jsonresponse.get("id"); - if (idElement != null && idElement.isJsonPrimitive()) { - final String id = idElement.getAsString(); - if (id.compareTo(requestId) == 0) { - final Response.Builder builder = new Response.Builder(); - - // Put corresponding request into the constructed response - builder.request(batchRequestsHashMap.get(requestId)); - // copy protocol and message same as of batch response - builder.protocol(protocol); - builder.message(message); - - // Put status code of the corresponding request in JsonArray - final JsonElement statusElement = jsonresponse.get("status"); - if (statusElement != null && statusElement.isJsonPrimitive()) { - builder.code(statusElement.getAsInt()); - } - - // Put body from response array for corresponding id into constructing response - final JsonElement jsonBodyElement = jsonresponse.get("body"); - if (jsonBodyElement != null && jsonBodyElement.isJsonObject()) { - final JsonObject JsonObject = jsonBodyElement.getAsJsonObject(); - final String bodyAsString = JsonObject.toString(); - final ResponseBody responseBody = ResponseBody - .create(bodyAsString, MediaType.parse("application/json; charset=utf-8")); - builder.body(responseBody); - } - - // Put headers from response array for corresponding id into constructing - // response - final JsonElement jsonheadersElement = jsonresponse.get("headers"); - if (jsonheadersElement != null && jsonheadersElement.isJsonObject()) { - final JsonObject jsonheaders = jsonheadersElement.getAsJsonObject(); - for (final String key : jsonheaders.keySet()) { - final JsonElement strValueElement = jsonheaders.get(key); - if (strValueElement != null && strValueElement.isJsonPrimitive()) { - final String strvalue = strValueElement.getAsString(); - for (final String value : strvalue.split(";")) { - builder.header(key, value); - } - } - } - } - return builder.build(); - } - } - } - return null; - } - - /** - * Get map of id and responses - * - * @return responses in Map of id and response - */ - @Nonnull - public Map getResponses() { - if (batchResponseArray == null) - return null; - final Map responsesMap = new LinkedHashMap<>(); - for (final String id : batchRequestsHashMap.keySet()) { - responsesMap.put(id, getResponseById(id)); - } - return responsesMap; - } - - /** - * Get iterator over the responses - * - * @return iterator for responses - */ - @Nullable - public Iterator> getResponsesIterator() { - final Map responsesMap = getResponses(); - return responsesMap != null ? responsesMap.entrySet().iterator() : null; - } - - /** - * Updates the response content using the raw http response object - * @param batchResponse the response from the service. - */ - public void update(@Nonnull final Response batchResponse) { - final Map requestMap = createBatchRequestsHashMap(Objects.requireNonNull(batchResponse, "Batch Response cannot be null")); - if (requestMap != null) - batchRequestsHashMap.putAll(requestMap); - - if (batchResponse.body() != null) { - try { - final String batchResponseData = batchResponse.body().string(); - if (batchResponseData != null) { - updateFromResponseBody(stringToJSONObject(batchResponseData)); - } - } catch (final IOException e) { - logger.logError("error updating batch response content from response body", e); - } - } - } - private void updateFromResponseBody(@Nonnull final JsonObject batchResponseObj) { - if (batchResponseObj != null) { - final JsonElement nextLinkElement = batchResponseObj.get("@odata.nextLink"); - if (nextLinkElement != null && nextLinkElement.isJsonPrimitive()) - nextLink = nextLinkElement.getAsString(); - - if (batchResponseArray == null) - batchResponseArray = new JsonArray(); - - final JsonElement responseArrayElement = batchResponseObj.get("responses"); - if (responseArrayElement != null && responseArrayElement.isJsonArray()) { - final JsonArray responseArray = responseArrayElement.getAsJsonArray(); - batchResponseArray.addAll(responseArray); - } - } - } - - /** - * @return nextLink of batch response - */ - @Nullable - public String nextLink() { - return nextLink; - } - - private Map createBatchRequestsHashMap(final Response batchResponse) { - if (batchResponse == null) - return null; - try { - final JsonObject requestJSONObject = requestBodyToJSONObject(batchResponse.request()); - final String baseUrl = batchResponse.request().url().toString().replace("$batch", ""); - return createBatchRequestsHashMap(baseUrl, requestJSONObject); - } catch (IOException ex) { - logger.logError("error parsing batch requests to get batch response content", ex); - return null; - } - } - private Map createBatchRequestsHashMap(@Nonnull final String baseUrl, @Nonnull final JsonObject requestJSONObject) { - if(baseUrl == null || baseUrl == "" || requestJSONObject == null) { - return null; - } - try { - final Map batchRequestsHashMap = new LinkedHashMap<>(); - final JsonElement requestArrayElement = requestJSONObject.get("requests"); - if (requestArrayElement != null && requestArrayElement.isJsonArray()) { - final JsonArray requestArray = requestArrayElement.getAsJsonArray(); - for (final JsonElement item : requestArray) { - if(!item.isJsonObject()) - continue; - final JsonObject requestObject = item.getAsJsonObject(); - - final Request.Builder builder = new Request.Builder(); - - final JsonElement urlElement = requestObject.get("url"); - if (urlElement != null && urlElement.isJsonPrimitive()) { - final StringBuilder fullUrl = new StringBuilder(baseUrl); - fullUrl.append(urlElement.getAsString()); - builder.url(fullUrl.toString()); - } - final JsonElement jsonHeadersElement = requestObject.get("headers"); - if (jsonHeadersElement != null && jsonHeadersElement.isJsonObject()) { - final JsonObject jsonheaders = jsonHeadersElement.getAsJsonObject(); - for (final String key : jsonheaders.keySet()) { - final JsonElement strvalueElement = jsonheaders.get(key); - if (strvalueElement != null && strvalueElement.isJsonPrimitive()) { - final String strvalue = strvalueElement.getAsString(); - for (final String value : strvalue.split("; ")) { - builder.header(key, value); - } - } - } - } - final JsonElement jsonBodyElement = requestObject.get("body"); - final JsonElement jsonMethodElement = requestObject.get("method"); - if (jsonBodyElement != null && jsonMethodElement != null - && jsonBodyElement.isJsonObject() && jsonMethodElement.isJsonPrimitive()) { - final JsonObject JsonObject = jsonBodyElement.getAsJsonObject(); - final String bodyAsString = JsonObject.toString(); - final RequestBody requestBody = RequestBody - .create(bodyAsString, MediaType.parse("application/json; charset=utf-8")); - builder.method(jsonMethodElement.getAsString(), requestBody); - } else if (jsonMethodElement != null) { - builder.method(jsonMethodElement.getAsString(), null); - } - final JsonElement jsonIdElement = requestObject.get("id"); - if (jsonIdElement != null && jsonIdElement.isJsonPrimitive()) { - batchRequestsHashMap.put(jsonIdElement.getAsString(), builder.build()); - } - } - } - return batchRequestsHashMap; - - } catch (JsonParseException e) { - logger.logError("error parsing batch request", e); - } - return null; - } - - private JsonObject stringToJSONObject(final String input) { - JsonObject JsonObject = null; - try { - if (input != null) { - JsonObject = JsonParser.parseString(input).getAsJsonObject(); - } - } catch (final Exception e) { - logger.logError("error parsing input into JSONObject", e); - } - return JsonObject; - } - - private JsonObject requestBodyToJSONObject(final Request request) throws IOException, JsonParseException { - if (request == null || request.body() == null) - return null; - final Request copy = request.newBuilder().build(); - final Buffer buffer = new Buffer(); - copy.body().writeTo(buffer); - final String requestBody = buffer.readUtf8(); - final JsonObject JsonObject = JsonParser.parseString(requestBody).getAsJsonObject(); - return JsonObject; - } -} diff --git a/src/main/java/com/microsoft/graph/core/BaseClient.java b/src/main/java/com/microsoft/graph/core/BaseClient.java index bcf49d951..a97f6c030 100644 --- a/src/main/java/com/microsoft/graph/core/BaseClient.java +++ b/src/main/java/com/microsoft/graph/core/BaseClient.java @@ -27,6 +27,7 @@ import com.microsoft.graph.http.IHttpProvider; import com.microsoft.graph.httpcore.HttpClients; import com.microsoft.graph.authentication.IAuthenticationProvider; +import com.microsoft.graph.content.BatchRequestBuilder; import com.microsoft.graph.logger.DefaultLogger; import com.microsoft.graph.logger.ILogger; import com.microsoft.graph.serializer.DefaultSerializer; @@ -39,11 +40,13 @@ import javax.annotation.Nonnull; import okhttp3.OkHttpClient; +import okhttp3.Request; /** * A client that communications with an OData service + * @param type of a request for the native http client */ -public class BaseClient implements IBaseClient { +public class BaseClient implements IBaseClient { /** * Restricted constructor */ @@ -85,7 +88,7 @@ public void setServiceRoot(@Nonnull final String value) { */ @Nonnull public CustomRequestBuilder customRequest(@Nonnull final String url, @Nonnull final Class responseType) { - return new CustomRequestBuilder(getServiceRoot() + url, this, null, responseType); + return new CustomRequestBuilder<>(getServiceRoot() + url, this, null, responseType); } /** @@ -97,27 +100,51 @@ public CustomRequestBuilder customRequest(@Nonnull final String url, @Non */ @Nonnull public CustomRequestBuilder customRequest(@Nonnull final String url) { - return new CustomRequestBuilder(getServiceRoot() + url, this, null, + return new CustomRequestBuilder<>(getServiceRoot() + url, this, null, JsonElement.class); + } + + /** + * Get the batch request builder. + * @return a request builder to execute a batch. + */ + @Nonnull + public BatchRequestBuilder batch() { + return new BatchRequestBuilder(getServiceRoot() + "/$batch", this, null); + } + + /** + * Gets the builder to start configuring the client + * + * @return builder to start configuring the client + */ + @Nonnull + public static Builder builder() { + return builder(OkHttpClient.class, Request.class); } /** * Gets the builder to start configuring the client * + * @param the type of the native http client + * @param the type of the native http request + * @param nativeClientClass the class of the native http client + * @param nativeRequestClass the class of the native http request * @return builder to start configuring the client */ @Nonnull - public static Builder builder() { + public static Builder builder(@Nonnull final Class nativeClientClass, @Nonnull final Class nativeRequestClass) { return new Builder<>(); } /** * Builder to help configure the Graph service client * @param type of the native http library client + * @param type of a request for the native http client */ - public static class Builder { + public static class Builder { private ISerializer serializer; - private IHttpProvider httpProvider; + private IHttpProvider httpProvider; private ILogger logger; private httpClientType httpClient; private IAuthenticationProvider auth; @@ -150,10 +177,11 @@ private httpClientType getHttpClient() { } else { return httpClient; } - } - private IHttpProvider getHttpProvider() { + } + @SuppressWarnings("unchecked") + private IHttpProvider getHttpProvider() { if(httpProvider == null) { - return new CoreHttpProvider(getSerializer(), getLogger(), (OkHttpClient)getHttpClient()); + return (IHttpProvider)new CoreHttpProvider(getSerializer(), getLogger(), (OkHttpClient)getHttpClient()); } else { return httpProvider; } @@ -167,7 +195,7 @@ private IHttpProvider getHttpProvider() { * @return the instance of this builder */ @Nonnull - public Builder serializer(@Nonnull final ISerializer serializer) { + public Builder serializer(@Nonnull final ISerializer serializer) { checkNotNull(serializer, "serializer"); this.serializer = serializer; return this; @@ -181,7 +209,7 @@ public Builder serializer(@Nonnull final ISerializer serializer) * @return the instance of this builder */ @Nonnull - public Builder httpProvider(@Nonnull final IHttpProvider httpProvider) { + public Builder httpProvider(@Nonnull final IHttpProvider httpProvider) { checkNotNull(httpProvider, "httpProvider"); this.httpProvider = httpProvider; return this; @@ -195,7 +223,7 @@ public Builder httpProvider(@Nonnull final IHttpProvider httpPro * @return the instance of this builder */ @Nonnull - public Builder logger(@Nonnull final ILogger logger) { + public Builder logger(@Nonnull final ILogger logger) { checkNotNull(logger, "logger"); this.logger = logger; return this; @@ -209,7 +237,7 @@ public Builder logger(@Nonnull final ILogger logger) { * @return the instance of this builder */ @Nonnull - public Builder httpClient(@Nonnull final httpClientType client) { + public Builder httpClient(@Nonnull final httpClientType client) { checkNotNull(client, "client"); this.httpClient = client; return this; @@ -222,7 +250,7 @@ public Builder httpClient(@Nonnull final httpClientType client) * @return the instance of this builder */ @Nonnull - public Builder authenticationProvider(@Nonnull final IAuthenticationProvider auth) { + public Builder authenticationProvider(@Nonnull final IAuthenticationProvider auth) { checkNotNull(auth, "auth"); this.auth = auth; return this; @@ -238,7 +266,7 @@ public Builder authenticationProvider(@Nonnull final IAuthentica * if there was an exception creating the client */ @Nonnull - protected ClientType buildClient(@Nonnull ClientType instance) throws ClientException { + protected > ClientType buildClient(@Nonnull ClientType instance) throws ClientException { Objects.requireNonNull(instance, "The instance cannot be null"); instance.setHttpProvider(this.getHttpProvider()); instance.setLogger(this.getLogger()); @@ -254,8 +282,8 @@ protected ClientType buildClient(@Nonnull Client * if there was an exception creating the client */ @Nonnull - public IBaseClient buildClient() throws ClientException { - return buildClient(new BaseClient()); + public IBaseClient buildClient() throws ClientException { + return buildClient(new BaseClient<>()); } } @@ -274,7 +302,7 @@ protected static void checkNotNull(@Nullable final Object o, @Nonnull final Stri /** * The HTTP provider instance */ - private IHttpProvider httpProvider; + private IHttpProvider httpProvider; /** * The logger @@ -293,7 +321,7 @@ protected static void checkNotNull(@Nullable final Object o, @Nonnull final Stri */ @Override @Nullable - public IHttpProvider getHttpProvider() { + public IHttpProvider getHttpProvider() { return httpProvider; } @@ -333,7 +361,7 @@ protected void setLogger(@Nonnull final ILogger logger) { * * @param httpProvider The HTTP provider */ - protected void setHttpProvider(@Nonnull final IHttpProvider httpProvider) { + protected void setHttpProvider(@Nonnull final IHttpProvider httpProvider) { checkNotNull(httpProvider, "httpProvider"); this.httpProvider = httpProvider; } diff --git a/src/main/java/com/microsoft/graph/core/CustomRequestBuilder.java b/src/main/java/com/microsoft/graph/core/CustomRequestBuilder.java index 1b878a037..6354965b6 100644 --- a/src/main/java/com/microsoft/graph/core/CustomRequestBuilder.java +++ b/src/main/java/com/microsoft/graph/core/CustomRequestBuilder.java @@ -5,7 +5,6 @@ import javax.annotation.Nullable; import javax.annotation.Nonnull; -import com.microsoft.graph.core.IBaseClient; import com.microsoft.graph.http.BaseRequestBuilder; import com.microsoft.graph.http.CustomRequest; import com.microsoft.graph.options.Option; @@ -18,23 +17,23 @@ public class CustomRequestBuilder extends BaseRequestBuilder { /** Type to use for response deserialization */ public final Class responseType; - + /** * Instanciates a new custom request builder - * + * * @param requestUrl the URL to send the request to * @param client the client to use for the request * @param requestOptions options to apply to the request * @param responseType type to use for response deserialization */ - public CustomRequestBuilder(@Nonnull final String requestUrl, @Nonnull final IBaseClient client, @Nullable final List requestOptions, @Nonnull final Class responseType) { + public CustomRequestBuilder(@Nonnull final String requestUrl, @Nonnull final IBaseClient client, @Nullable final List requestOptions, @Nonnull final Class responseType) { super(requestUrl, client, requestOptions); this.responseType = responseType; } - + /** * Builds the request to be executed - * + * * @return the request to be executed * @param requestOptions the options to apply to the request */ @@ -42,10 +41,10 @@ public CustomRequestBuilder(@Nonnull final String requestUrl, @Nonnull final IBa public CustomRequest buildRequest(@Nullable final com.microsoft.graph.options.Option... requestOptions) { return buildRequest(getOptions(requestOptions)); } - + /** * Builds the request to be executed - * + * * @return the request to be executed * @param requestOptions the options to apply to the request */ diff --git a/src/main/java/com/microsoft/graph/core/IBaseClient.java b/src/main/java/com/microsoft/graph/core/IBaseClient.java index 9941f6417..c260831a8 100644 --- a/src/main/java/com/microsoft/graph/core/IBaseClient.java +++ b/src/main/java/com/microsoft/graph/core/IBaseClient.java @@ -26,14 +26,16 @@ import javax.annotation.Nonnull; import com.google.gson.JsonElement; +import com.microsoft.graph.content.BatchRequestBuilder; import com.microsoft.graph.http.IHttpProvider; import com.microsoft.graph.logger.ILogger; import com.microsoft.graph.serializer.ISerializer; /** * A client that communications with an OData service + * @param type of a request for the native http client */ -public interface IBaseClient { +public interface IBaseClient { /** * Gets the service root * @@ -55,7 +57,7 @@ public interface IBaseClient { * @return the HTTP provider */ @Nullable - IHttpProvider getHttpProvider(); + IHttpProvider getHttpProvider(); /** * Gets the logger @@ -93,6 +95,13 @@ public interface IBaseClient { @Nonnull CustomRequestBuilder customRequest(@Nonnull final String url); + /** + * Get the batch request builder. + * @return a request builder to execute a batch. + */ + @Nonnull + public BatchRequestBuilder batch(); + /** * Gets the service SDK version if the service SDK is in use, null otherwise * @return the service SDK version if the service SDK is in use, null otherwise diff --git a/src/main/java/com/microsoft/graph/http/BaseActionCollectionRequest.java b/src/main/java/com/microsoft/graph/http/BaseActionCollectionRequest.java index b2d4b8afe..a9c38b4ec 100644 --- a/src/main/java/com/microsoft/graph/http/BaseActionCollectionRequest.java +++ b/src/main/java/com/microsoft/graph/http/BaseActionCollectionRequest.java @@ -22,18 +22,14 @@ package com.microsoft.graph.http; -import java.net.URL; import java.lang.NoSuchFieldException; import java.lang.IllegalAccessException; -import java.util.ArrayList; import java.util.List; import javax.annotation.Nullable; import javax.annotation.Nonnull; import com.microsoft.graph.core.ClientException; import com.microsoft.graph.core.IBaseClient; -import com.microsoft.graph.http.ICollectionResponse; -import com.microsoft.graph.http.BaseCollectionPage; import com.microsoft.graph.options.Option; /** @@ -58,7 +54,7 @@ public abstract class BaseActionCollectionRequest client, @Nullable final List options, @Nonnull final Class responseCollectionClass, @Nonnull final Class collectionPageClass, diff --git a/src/main/java/com/microsoft/graph/http/BaseActionCollectionRequestBuilder.java b/src/main/java/com/microsoft/graph/http/BaseActionCollectionRequestBuilder.java index f315271c6..000cac4cd 100644 --- a/src/main/java/com/microsoft/graph/http/BaseActionCollectionRequestBuilder.java +++ b/src/main/java/com/microsoft/graph/http/BaseActionCollectionRequestBuilder.java @@ -5,12 +5,9 @@ package com.microsoft.graph.http; import com.microsoft.graph.core.IBaseClient; -import com.microsoft.graph.http.BaseRequestBuilder; import com.microsoft.graph.options.Option; -import java.util.HashMap; import java.util.List; -import java.util.Map; import javax.annotation.Nonnull; import javax.annotation.Nullable; @@ -34,7 +31,7 @@ public class BaseActionCollectionRequestBuilder client, @Nullable final List options, @Nonnull final Class requestBuilderClass, @Nonnull final Class collectionRequestClass diff --git a/src/main/java/com/microsoft/graph/http/BaseActionRequestBuilder.java b/src/main/java/com/microsoft/graph/http/BaseActionRequestBuilder.java index 46427e0a5..17aff1f98 100644 --- a/src/main/java/com/microsoft/graph/http/BaseActionRequestBuilder.java +++ b/src/main/java/com/microsoft/graph/http/BaseActionRequestBuilder.java @@ -5,12 +5,9 @@ package com.microsoft.graph.http; import com.microsoft.graph.core.IBaseClient; -import com.microsoft.graph.http.BaseRequestBuilder; import com.microsoft.graph.options.Option; -import java.util.HashMap; import java.util.List; -import java.util.Map; import javax.annotation.Nullable; import javax.annotation.Nonnull; @@ -28,7 +25,7 @@ public class BaseActionRequestBuilder extends BaseRequestBuilder { */ public BaseActionRequestBuilder( @Nonnull final String requestUrl, - @Nonnull final IBaseClient client, + @Nonnull final IBaseClient client, @Nullable final List options ) { super(requestUrl, client, options); diff --git a/src/main/java/com/microsoft/graph/http/BaseCollectionReferenceRequestBuilder.java b/src/main/java/com/microsoft/graph/http/BaseCollectionReferenceRequestBuilder.java index 326a11c37..ae833394c 100644 --- a/src/main/java/com/microsoft/graph/http/BaseCollectionReferenceRequestBuilder.java +++ b/src/main/java/com/microsoft/graph/http/BaseCollectionReferenceRequestBuilder.java @@ -23,10 +23,6 @@ package com.microsoft.graph.http; import com.microsoft.graph.core.IBaseClient; -import com.microsoft.graph.options.Option; - -import java.lang.reflect.InvocationTargetException; -import java.util.List; import javax.annotation.Nonnull; import javax.annotation.Nullable; @@ -47,7 +43,7 @@ public class BaseCollectionReferenceRequestBuilder requestOptions, + public BaseCollectionReferenceRequestBuilder(@Nonnull final String requestUrl, @Nonnull final IBaseClient client, @Nullable final java.util.List requestOptions, @Nonnull final Class requestBuilderClass, @Nonnull final Class collectionRequestClass) { super(requestUrl, client, requestOptions, requestBuilderClass, collectionRequestClass); diff --git a/src/main/java/com/microsoft/graph/http/BaseCollectionRequest.java b/src/main/java/com/microsoft/graph/http/BaseCollectionRequest.java index c71dd5a4f..5ff5921af 100644 --- a/src/main/java/com/microsoft/graph/http/BaseCollectionRequest.java +++ b/src/main/java/com/microsoft/graph/http/BaseCollectionRequest.java @@ -37,8 +37,6 @@ import com.microsoft.graph.options.Option; import com.microsoft.graph.options.QueryOption; -import okhttp3.Request; - /** * A request against a collection * @@ -78,7 +76,7 @@ public abstract class BaseCollectionRequest * @param collectionRequestBuilderClass the class for the collection request builder */ public BaseCollectionRequest(@Nonnull final String requestUrl, - @Nonnull final IBaseClient client, + @Nonnull final IBaseClient client, @Nullable final List options, @Nonnull final Class responseCollectionClass, @Nonnull final Class collectionPageClass, @@ -418,26 +416,18 @@ public IHttpRequest withHttpMethod(@Nonnull final HttpMethod httpMethod) { baseRequest.setHttpMethod(httpMethod); return this; } - /** - * Returns the Request object to be executed - * @return the Request object to be executed - */ - @Override - @Nullable - public Request getHttpRequest() throws ClientException { - return baseRequest.getHttpRequest(); - } /** * Returns the Request object to be executed * @param serializedObject the object to serialize at the body of the request * @param the type of the serialized object * @param the type of the response + * @param type of a request for the native http client * @return the Request object to be executed */ @Override @Nullable - public Request getHttpRequest(@Nonnull final requestBodyType serializedObject) throws ClientException { + public nativeRequestType getHttpRequest(@Nonnull final requestBodyType serializedObject) throws ClientException { return baseRequest.getHttpRequest(serializedObject); } } diff --git a/src/main/java/com/microsoft/graph/http/BaseCollectionRequestBuilder.java b/src/main/java/com/microsoft/graph/http/BaseCollectionRequestBuilder.java index 9d2402612..2428cefc7 100644 --- a/src/main/java/com/microsoft/graph/http/BaseCollectionRequestBuilder.java +++ b/src/main/java/com/microsoft/graph/http/BaseCollectionRequestBuilder.java @@ -30,7 +30,7 @@ public class BaseCollectionRequestBuilder, * @param requestBuilderClass the class for the request builder * @param collectionRequestClass the class for the collection request */ - public BaseCollectionRequestBuilder(@Nonnull final String requestUrl, @Nonnull final IBaseClient client, @Nullable final java.util.List requestOptions, + public BaseCollectionRequestBuilder(@Nonnull final String requestUrl, @Nonnull final IBaseClient client, @Nullable final java.util.List requestOptions, @Nonnull final Class requestBuilderClass, @Nonnull final Class collectionRequestClass) { super(requestUrl, client, requestOptions); @@ -67,7 +67,7 @@ public T5 buildRequest(@Nullable final java.util.List requestOptions, + public BaseCollectionWithReferencesRequest(@Nonnull final String requestUrl, @Nonnull final IBaseClient client, @Nullable final java.util.List requestOptions, @Nonnull final Class collectionResponseClass, @Nonnull final Class collectionPageClass, @Nonnull final Class, ? extends BaseCollectionReferenceRequestBuilder>>> collectionWithReferencesRequestBuilderClass) { diff --git a/src/main/java/com/microsoft/graph/http/BaseCollectionWithReferencesRequestBuilder.java b/src/main/java/com/microsoft/graph/http/BaseCollectionWithReferencesRequestBuilder.java index bc647d28b..e9005b43c 100644 --- a/src/main/java/com/microsoft/graph/http/BaseCollectionWithReferencesRequestBuilder.java +++ b/src/main/java/com/microsoft/graph/http/BaseCollectionWithReferencesRequestBuilder.java @@ -23,13 +23,7 @@ package com.microsoft.graph.http; import com.microsoft.graph.core.IBaseClient; -import com.microsoft.graph.options.Option; -import java.lang.reflect.InvocationTargetException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Arrays; import java.lang.reflect.InvocationTargetException; import javax.annotation.Nullable; @@ -56,7 +50,7 @@ public abstract class BaseCollectionWithReferencesRequestBuilder requestOptions, + public BaseCollectionWithReferencesRequestBuilder(@Nonnull final String requestUrl, @Nonnull final IBaseClient client, @Nullable final java.util.List requestOptions, @Nonnull final Class referenceRequestBuilderClass, @Nonnull final Class collectionWithReferencesRequestClass, @Nonnull final Class collectionWithReferenceRequestBuilderClass) { diff --git a/src/main/java/com/microsoft/graph/http/BaseDeltaCollectionRequest.java b/src/main/java/com/microsoft/graph/http/BaseDeltaCollectionRequest.java index 9a2c0410f..0d959e300 100644 --- a/src/main/java/com/microsoft/graph/http/BaseDeltaCollectionRequest.java +++ b/src/main/java/com/microsoft/graph/http/BaseDeltaCollectionRequest.java @@ -22,9 +22,6 @@ package com.microsoft.graph.http; -import java.net.URL; -import java.lang.reflect.InvocationTargetException; -import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -32,10 +29,7 @@ import javax.annotation.Nullable; import javax.annotation.Nonnull; -import com.microsoft.graph.core.ClientException; import com.microsoft.graph.core.IBaseClient; -import com.microsoft.graph.http.ICollectionResponse; -import com.microsoft.graph.http.BaseCollectionPage; import com.microsoft.graph.options.Option; import com.microsoft.graph.options.QueryOption; @@ -61,7 +55,7 @@ public abstract class BaseDeltaCollectionRequest client, @Nullable final List options, @Nonnull final Class responseCollectionClass, @Nonnull final Class collectionPageClass, diff --git a/src/main/java/com/microsoft/graph/http/BaseEntityCollectionRequest.java b/src/main/java/com/microsoft/graph/http/BaseEntityCollectionRequest.java index e0b405115..fd937b64d 100644 --- a/src/main/java/com/microsoft/graph/http/BaseEntityCollectionRequest.java +++ b/src/main/java/com/microsoft/graph/http/BaseEntityCollectionRequest.java @@ -22,17 +22,12 @@ package com.microsoft.graph.http; -import java.net.URL; -import java.lang.reflect.InvocationTargetException; -import java.util.ArrayList; import java.util.List; import javax.annotation.Nullable; import javax.annotation.Nonnull; import com.microsoft.graph.core.ClientException; import com.microsoft.graph.core.IBaseClient; -import com.microsoft.graph.http.ICollectionResponse; -import com.microsoft.graph.http.BaseCollectionPage; import com.microsoft.graph.options.Option; /** @@ -57,7 +52,7 @@ public abstract class BaseEntityCollectionRequest client, @Nullable final List options, @Nonnull final Class responseCollectionClass, @Nonnull final Class collectionPageClass, diff --git a/src/main/java/com/microsoft/graph/http/BaseFunctionCollectionRequest.java b/src/main/java/com/microsoft/graph/http/BaseFunctionCollectionRequest.java index c54e3c634..19ca7a08f 100644 --- a/src/main/java/com/microsoft/graph/http/BaseFunctionCollectionRequest.java +++ b/src/main/java/com/microsoft/graph/http/BaseFunctionCollectionRequest.java @@ -22,17 +22,12 @@ package com.microsoft.graph.http; -import java.net.URL; -import java.lang.reflect.InvocationTargetException; -import java.util.ArrayList; import java.util.List; import javax.annotation.Nullable; import javax.annotation.Nonnull; import com.microsoft.graph.core.ClientException; import com.microsoft.graph.core.IBaseClient; -import com.microsoft.graph.http.ICollectionResponse; -import com.microsoft.graph.http.BaseCollectionPage; import com.microsoft.graph.options.Option; /** @@ -57,7 +52,7 @@ public abstract class BaseFunctionCollectionRequest client, @Nullable final List options, @Nonnull final Class responseCollectionClass, @Nonnull final Class collectionPageClass, diff --git a/src/main/java/com/microsoft/graph/http/BaseFunctionCollectionRequestBuilder.java b/src/main/java/com/microsoft/graph/http/BaseFunctionCollectionRequestBuilder.java index 68b856fc3..58d409ee6 100644 --- a/src/main/java/com/microsoft/graph/http/BaseFunctionCollectionRequestBuilder.java +++ b/src/main/java/com/microsoft/graph/http/BaseFunctionCollectionRequestBuilder.java @@ -39,7 +39,7 @@ public class BaseFunctionCollectionRequestBuilder client, @Nullable final List options, @Nonnull final Class requestBuilderClass, @Nonnull final Class collectionRequestClass diff --git a/src/main/java/com/microsoft/graph/http/BaseFunctionRequestBuilder.java b/src/main/java/com/microsoft/graph/http/BaseFunctionRequestBuilder.java index 7de5a7e65..d8555d9af 100644 --- a/src/main/java/com/microsoft/graph/http/BaseFunctionRequestBuilder.java +++ b/src/main/java/com/microsoft/graph/http/BaseFunctionRequestBuilder.java @@ -5,7 +5,6 @@ package com.microsoft.graph.http; import com.microsoft.graph.core.IBaseClient; -import com.microsoft.graph.http.BaseRequestBuilder; import com.microsoft.graph.options.FunctionOption; import com.microsoft.graph.options.Option; @@ -35,7 +34,7 @@ public class BaseFunctionRequestBuilder extends BaseRequestBuilder { */ public BaseFunctionRequestBuilder( @Nonnull final String requestUrl, - @Nonnull final IBaseClient client, + @Nonnull final IBaseClient client, @Nullable final List options ) { super(requestUrl, client, options); diff --git a/src/main/java/com/microsoft/graph/http/BaseReferenceRequest.java b/src/main/java/com/microsoft/graph/http/BaseReferenceRequest.java index e93089a06..13d5d3f6e 100644 --- a/src/main/java/com/microsoft/graph/http/BaseReferenceRequest.java +++ b/src/main/java/com/microsoft/graph/http/BaseReferenceRequest.java @@ -24,9 +24,6 @@ import com.microsoft.graph.core.IBaseClient; import com.microsoft.graph.core.ClientException; -import com.microsoft.graph.options.Option; - -import java.util.List; import javax.annotation.Nullable; import javax.annotation.Nonnull; @@ -46,7 +43,7 @@ public abstract class BaseReferenceRequest extends BaseRequest { * @param requestOptions the options for this request * @param entityType the class for the entity */ - public BaseReferenceRequest(@Nonnull final String requestUrl, @Nonnull final IBaseClient client, @Nullable final java.util.List requestOptions, @Nonnull final Class entityType) { + public BaseReferenceRequest(@Nonnull final String requestUrl, @Nonnull final IBaseClient client, @Nullable final java.util.List requestOptions, @Nonnull final Class entityType) { super(requestUrl, client, requestOptions, entityType); } diff --git a/src/main/java/com/microsoft/graph/http/BaseReferenceRequestBuilder.java b/src/main/java/com/microsoft/graph/http/BaseReferenceRequestBuilder.java index 768a49cd1..aea14506c 100644 --- a/src/main/java/com/microsoft/graph/http/BaseReferenceRequestBuilder.java +++ b/src/main/java/com/microsoft/graph/http/BaseReferenceRequestBuilder.java @@ -1,16 +1,16 @@ // ------------------------------------------------------------------------------ // Copyright (c) 2017 Microsoft Corporation -// +// // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sub-license, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: -// +// // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. -// +// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,10 +23,8 @@ package com.microsoft.graph.http; import com.microsoft.graph.core.IBaseClient; -import com.microsoft.graph.options.Option; import java.lang.reflect.InvocationTargetException; -import java.util.List; import javax.annotation.Nullable; import javax.annotation.Nonnull; @@ -46,7 +44,7 @@ public abstract class BaseReferenceRequestBuilder requestOptions, @Nonnull final Class referenceRequestClass) { + public BaseReferenceRequestBuilder(@Nonnull final String requestUrl, @Nonnull final IBaseClient client, @Nullable final java.util.List requestOptions, @Nonnull final Class referenceRequestClass) { super(requestUrl, client, requestOptions); this.refRequestClass = referenceRequestClass; } diff --git a/src/main/java/com/microsoft/graph/http/BaseRequest.java b/src/main/java/com/microsoft/graph/http/BaseRequest.java index a2b0f953c..a73776532 100644 --- a/src/main/java/com/microsoft/graph/http/BaseRequest.java +++ b/src/main/java/com/microsoft/graph/http/BaseRequest.java @@ -23,7 +23,6 @@ package com.microsoft.graph.http; import okhttp3.HttpUrl; -import okhttp3.Request; import okhttp3.HttpUrl.Builder; import com.microsoft.graph.core.IBaseClient; @@ -77,7 +76,7 @@ public abstract class BaseRequest implements IHttpRequest { /** * The backing client for this request */ - private final IBaseClient client; + private final IBaseClient client; /** * The header options for this request @@ -138,7 +137,7 @@ public abstract class BaseRequest implements IHttpRequest { * @param responseClass the class for the response */ public BaseRequest(@Nonnull final String requestUrl, - @Nonnull final IBaseClient client, + @Nonnull final IBaseClient client, @Nullable final List options, @Nonnull final Class responseClass) { this.requestUrl = requestUrl; @@ -197,28 +196,19 @@ public URL getRequestUrl() { return null; } - /** - * Returns the Request object to be executed - * @return the Request object to be executed - */ - @Override - @Nullable - public Request getHttpRequest() throws ClientException { - return getHttpRequest(null); - } - /** * Returns the Request object to be executed * @param serializedObject the object to serialize at the body of the request * @param the type of the serialized object * @param the type of the response + * @param type of a request for the native http client * @return the Request object to be executed */ @Override @Nullable @SuppressWarnings("unchecked") - public Request getHttpRequest(@Nonnull final requestBodyType serializedObject) throws ClientException { - return client.getHttpProvider().getHttpRequest(this, (Class) responseClass, serializedObject); + public nativeRequestType getHttpRequest(@Nonnull final requestBodyType serializedObject) throws ClientException { + return (nativeRequestType)client.getHttpProvider().getHttpRequest(this, (Class) responseClass, serializedObject); } private String addFunctionParameters() { @@ -486,7 +476,7 @@ public IHttpRequest withHttpMethod(@Nonnull final HttpMethod httpMethod) { * @return the client */ @Nonnull - public IBaseClient getClient() { + public IBaseClient getClient() { return client; } diff --git a/src/main/java/com/microsoft/graph/http/BaseRequestBuilder.java b/src/main/java/com/microsoft/graph/http/BaseRequestBuilder.java index 638ddae48..aff5e8795 100644 --- a/src/main/java/com/microsoft/graph/http/BaseRequestBuilder.java +++ b/src/main/java/com/microsoft/graph/http/BaseRequestBuilder.java @@ -1,16 +1,16 @@ // ------------------------------------------------------------------------------ // Copyright (c) 2017 Microsoft Corporation -// +// // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sub-license, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: -// +// // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. -// +// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -41,7 +41,7 @@ public abstract class BaseRequestBuilder implements IRequestBuilder { /** * The backing client for this request. */ - private final IBaseClient client; + private final IBaseClient client; /** * The URL for this request @@ -62,7 +62,7 @@ public abstract class BaseRequestBuilder implements IRequestBuilder { */ public BaseRequestBuilder( @Nonnull final String requestUrl, - @Nonnull final IBaseClient client, + @Nonnull final IBaseClient client, @Nullable final List options ) { this.requestUrl = requestUrl; @@ -78,7 +78,7 @@ public BaseRequestBuilder( * @return the client */ @Nullable - public IBaseClient getClient() { + public IBaseClient getClient() { return client; } @@ -100,8 +100,8 @@ public String getRequestUrl() { */ @Nonnull public List getOptions(@Nonnull final Option... requestOptions) { - return Collections.unmodifiableList(requestOptions != null && requestOptions.length > 0 ? - Arrays.asList(requestOptions) + return Collections.unmodifiableList(requestOptions != null && requestOptions.length > 0 ? + Arrays.asList(requestOptions) : options); } diff --git a/src/main/java/com/microsoft/graph/http/BaseStreamRequest.java b/src/main/java/com/microsoft/graph/http/BaseStreamRequest.java index 516439bf9..adb8a7ee9 100644 --- a/src/main/java/com/microsoft/graph/http/BaseStreamRequest.java +++ b/src/main/java/com/microsoft/graph/http/BaseStreamRequest.java @@ -29,8 +29,6 @@ import com.microsoft.graph.options.HeaderOption; import com.microsoft.graph.options.Option; -import okhttp3.Request; - import java.io.InputStream; import java.net.URL; import java.util.List; @@ -59,7 +57,7 @@ public abstract class BaseStreamRequest implements IHttpStreamRequest { * @param responseClass the class for the response */ public BaseStreamRequest(@Nonnull final String requestUrl, - @Nonnull final IBaseClient client, + @Nonnull final IBaseClient client, @Nullable final List options, @Nonnull final Class responseClass) { baseRequest = new BaseRequest(requestUrl, client, options, responseClass) { @@ -293,26 +291,17 @@ public IHttpRequest withHttpMethod(@Nonnull final HttpMethod httpMethod) { return this; } - /** - * Returns the Request object to be executed - * @return the Request object to be executed - */ - @Override - @Nullable - public Request getHttpRequest() throws ClientException { - return baseRequest.getHttpRequest(); - } - /** * Returns the Request object to be executed * @param serializedObject the object to serialize at the body of the request * @param the type of the serialized object * @param the type of the response + * @param type of a request for the native http client * @return the Request object to be executed */ @Override @Nullable - public Request getHttpRequest(@Nonnull final requestBodyType serializedObject) throws ClientException { + public nativeRequestType getHttpRequest(@Nonnull final requestBodyType serializedObject) throws ClientException { return baseRequest.getHttpRequest(serializedObject); } } diff --git a/src/main/java/com/microsoft/graph/http/BaseVoidActionCollectionRequest.java b/src/main/java/com/microsoft/graph/http/BaseVoidActionCollectionRequest.java index d358815c4..c9108640a 100644 --- a/src/main/java/com/microsoft/graph/http/BaseVoidActionCollectionRequest.java +++ b/src/main/java/com/microsoft/graph/http/BaseVoidActionCollectionRequest.java @@ -22,18 +22,14 @@ package com.microsoft.graph.http; -import java.net.URL; import java.lang.NoSuchFieldException; import java.lang.IllegalAccessException; -import java.util.ArrayList; import java.util.List; import javax.annotation.Nullable; import javax.annotation.Nonnull; import com.microsoft.graph.core.ClientException; import com.microsoft.graph.core.IBaseClient; -import com.microsoft.graph.http.ICollectionResponse; -import com.microsoft.graph.http.BaseCollectionPage; import com.microsoft.graph.options.Option; /** @@ -58,7 +54,7 @@ public abstract class BaseVoidActionCollectionRequest client, @Nullable final List options, @Nonnull final Class responseCollectionClass, @Nonnull final Class collectionPageClass, diff --git a/src/main/java/com/microsoft/graph/http/BaseWithReferenceRequest.java b/src/main/java/com/microsoft/graph/http/BaseWithReferenceRequest.java index 279b05078..51caf56e5 100644 --- a/src/main/java/com/microsoft/graph/http/BaseWithReferenceRequest.java +++ b/src/main/java/com/microsoft/graph/http/BaseWithReferenceRequest.java @@ -24,11 +24,8 @@ import com.microsoft.graph.core.IBaseClient; import com.microsoft.graph.core.ClientException; -import com.microsoft.graph.options.Option; import com.microsoft.graph.serializer.IJsonBackedObject; -import java.util.List; - import javax.annotation.Nullable; import javax.annotation.Nonnull; @@ -47,7 +44,7 @@ public abstract class BaseWithReferenceRequest extends BaseRequest { * @param requestOptions the options for this request * @param entityClass the class for the entity */ - public BaseWithReferenceRequest(@Nonnull final String requestUrl, @Nonnull final IBaseClient client, @Nullable final java.util.List requestOptions, + public BaseWithReferenceRequest(@Nonnull final String requestUrl, @Nonnull final IBaseClient client, @Nullable final java.util.List requestOptions, @Nonnull final Class entityClass) { super(requestUrl, client, requestOptions, entityClass); } diff --git a/src/main/java/com/microsoft/graph/http/BaseWithReferenceRequestBuilder.java b/src/main/java/com/microsoft/graph/http/BaseWithReferenceRequestBuilder.java index a2661564e..a87e67a43 100644 --- a/src/main/java/com/microsoft/graph/http/BaseWithReferenceRequestBuilder.java +++ b/src/main/java/com/microsoft/graph/http/BaseWithReferenceRequestBuilder.java @@ -1,16 +1,16 @@ // ------------------------------------------------------------------------------ // Copyright (c) 2017 Microsoft Corporation -// +// // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sub-license, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: -// +// // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. -// +// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,10 +23,8 @@ package com.microsoft.graph.http; import com.microsoft.graph.core.IBaseClient; -import com.microsoft.graph.options.Option; import java.lang.reflect.InvocationTargetException; -import java.util.List; import javax.annotation.Nullable; import javax.annotation.Nonnull; @@ -49,7 +47,7 @@ public abstract class BaseWithReferenceRequestBuilder requestOptions, + public BaseWithReferenceRequestBuilder(@Nonnull final String requestUrl, @Nonnull final IBaseClient client, @Nullable final java.util.List requestOptions, @Nonnull final Class withReferenceRequestClass, @Nonnull final Class referenceRequestBuilderClass) { super(requestUrl, client, requestOptions); @@ -86,7 +84,7 @@ public T2 buildRequest(@Nullable final java.util.List { /** * The content type header */ diff --git a/src/main/java/com/microsoft/graph/http/CustomRequest.java b/src/main/java/com/microsoft/graph/http/CustomRequest.java index 31be6256c..594f4bba7 100644 --- a/src/main/java/com/microsoft/graph/http/CustomRequest.java +++ b/src/main/java/com/microsoft/graph/http/CustomRequest.java @@ -47,7 +47,7 @@ public class CustomRequest extends BaseRequest { * @param requestOptions the options to apply to the request * @param responseClass the class for response deserialization */ - public CustomRequest(@Nonnull final String requestUrl, @Nonnull final IBaseClient client, @Nullable final java.util.List requestOptions, @Nonnull final Class responseClass) { + public CustomRequest(@Nonnull final String requestUrl, @Nonnull final IBaseClient client, @Nullable final java.util.List requestOptions, @Nonnull final Class responseClass) { super(requestUrl, client, requestOptions, responseClass); } @@ -60,7 +60,7 @@ public CustomRequest(@Nonnull final String requestUrl, @Nonnull final IBaseClien * @return the request to execute against the service */ @Nonnull - public static CustomRequest create(@Nonnull final String requestUrl, @Nonnull final IBaseClient client, @Nullable final java.util.List requestOptions) { + public static CustomRequest create(@Nonnull final String requestUrl, @Nonnull final IBaseClient client, @Nullable final java.util.List requestOptions) { return new CustomRequest(requestUrl, client, requestOptions, JsonObject.class); } diff --git a/src/main/java/com/microsoft/graph/http/GraphFatalServiceException.java b/src/main/java/com/microsoft/graph/http/GraphFatalServiceException.java index d7ae1a1c4..ed3fdacb7 100644 --- a/src/main/java/com/microsoft/graph/http/GraphFatalServiceException.java +++ b/src/main/java/com/microsoft/graph/http/GraphFatalServiceException.java @@ -1,16 +1,16 @@ // ------------------------------------------------------------------------------ // Copyright (c) 2017 Microsoft Corporation -// +// // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sub-license, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: -// +// // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. -// +// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -36,7 +36,7 @@ public class GraphFatalServiceException extends GraphServiceException { /** * Create a fatal Graph service exception - * + * * @param method the method that caused the exception * @param url the URL * @param requestHeaders the request headers diff --git a/src/main/java/com/microsoft/graph/http/GraphServiceException.java b/src/main/java/com/microsoft/graph/http/GraphServiceException.java index eece63096..d5b6516dc 100644 --- a/src/main/java/com/microsoft/graph/http/GraphServiceException.java +++ b/src/main/java/com/microsoft/graph/http/GraphServiceException.java @@ -342,7 +342,7 @@ public static GraphServiceException createFromResponse(@Nonnull final IHttpR for (final HeaderOption option : request.getHeaders()) { requestHeaders.add(option.getName() + " : " + option.getValue()); } - boolean isVerbose = logger.getLoggingLevel() == LoggerLevel.DEBUG; + final boolean isVerbose = logger.getLoggingLevel() == LoggerLevel.DEBUG; final String requestBody; if (serializable instanceof byte[]) { final byte[] bytes = (byte[]) serializable; @@ -368,8 +368,32 @@ public static GraphServiceException createFromResponse(@Nonnull final IHttpR } final int responseCode = response.code(); - final List responseHeaders = new LinkedList<>(); final Map headers = getResponseHeadersAsMapStringString(response); + final String responseMessage = response.message(); + GraphErrorResponse error = parseErrorResponse(serializer, response); + + return createFromResponse(url, method, requestHeaders, requestBody, headers, responseMessage, responseCode, error, isVerbose); + + } + /** + * Creates a Graph service exception. + * @param url url of the original request + * @param method http method of the original request + * @param requestHeaders headers of the original request + * @param requestBody body of the original request + * @param headers response headers + * @param responseMessage reponse status message + * @param responseCode response status code + * @param error graph error response object + * @param isVerbose whether to display a verbose message or not + * @return the Exception to be thrown + */ + @Nonnull + public static GraphServiceException createFromResponse(@Nullable final String url, @Nullable final String method, @Nonnull final List requestHeaders, + @Nullable final String requestBody, + @Nonnull final Map headers, @Nonnull final String responseMessage, final int responseCode, + @Nonnull final GraphErrorResponse error, final boolean isVerbose) { + final List responseHeaders = new LinkedList<>(); for (final String key : headers.keySet()) { final String fieldPrefix; if (key == null) { @@ -380,9 +404,7 @@ public static GraphServiceException createFromResponse(@Nonnull final IHttpR responseHeaders.add(fieldPrefix + headers.get(key)); } - final String responseMessage = response.message(); - GraphErrorResponse error = parseErrorResponse(serializer, response); if (responseCode >= INTERNAL_SERVER_ERROR) { return new GraphFatalServiceException(method, diff --git a/src/main/java/com/microsoft/graph/http/IHttpProvider.java b/src/main/java/com/microsoft/graph/http/IHttpProvider.java index 00d0abe27..55e4d7b96 100644 --- a/src/main/java/com/microsoft/graph/http/IHttpProvider.java +++ b/src/main/java/com/microsoft/graph/http/IHttpProvider.java @@ -24,19 +24,16 @@ import javax.annotation.Nullable; -import java.util.concurrent.ExecutorService; - import javax.annotation.Nonnull; import com.microsoft.graph.core.ClientException; import com.microsoft.graph.serializer.ISerializer; -import okhttp3.Request; - /** * Sends HTTP requests + * @param type of a request for the native http client */ -public interface IHttpProvider { +public interface IHttpProvider { /** * Get the serializer for this HTTP provider @@ -130,7 +127,7 @@ Result send(@Nonnull final IHttpRequest requ * @throws ClientException an exception occurs if the request was unable to complete for any reason */ @Nullable - Request getHttpRequest(@Nonnull final IHttpRequest request, + nativeRequestType getHttpRequest(@Nonnull final IHttpRequest request, @Nonnull final Class resultClass, @Nullable final BodyType serializable) throws ClientException; diff --git a/src/main/java/com/microsoft/graph/http/IHttpRequest.java b/src/main/java/com/microsoft/graph/http/IHttpRequest.java index 0885b32a5..76f674e17 100644 --- a/src/main/java/com/microsoft/graph/http/IHttpRequest.java +++ b/src/main/java/com/microsoft/graph/http/IHttpRequest.java @@ -1,16 +1,16 @@ // ------------------------------------------------------------------------------ // Copyright (c) 2017 Microsoft Corporation -// +// // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sub-license, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: -// +// // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. -// +// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -28,8 +28,6 @@ import com.microsoft.graph.options.HeaderOption; import com.microsoft.graph.options.Option; -import okhttp3.Request; - import java.net.URL; import java.util.List; @@ -43,7 +41,7 @@ public interface IHttpRequest { /** * Gets the request URL - * + * * @return the request URL */ @Nullable @@ -51,7 +49,7 @@ public interface IHttpRequest { /** * Gets the HTTP method - * + * * @return the HTTP method */ @Nullable @@ -59,7 +57,7 @@ public interface IHttpRequest { /** * Gets the headers - * + * * @return the headers */ @Nullable @@ -67,7 +65,7 @@ public interface IHttpRequest { /** * Gets the options - * + * * @return the options */ @Nullable @@ -75,7 +73,7 @@ public interface IHttpRequest { /** * Adds a header to this request - * + * * @param header the name of the header * @param value the value of the header */ @@ -83,86 +81,86 @@ public interface IHttpRequest { /** * Sets useCaches parameter to cache the response - * + * * @param useCaches the value of useCaches */ void setUseCaches(boolean useCaches); /** * Gets useCaches parameter - * + * * @return the value of useCaches */ boolean getUseCaches(); - + /** * Sets the max redirects - * + * * @param maxRedirects Max redirects that a request can take */ void setMaxRedirects(int maxRedirects); - + /** * Gets the max redirects - * + * * @return Max redirects that a request can take */ int getMaxRedirects(); - + /** * Sets the should redirect callback - * + * * @param shouldRedirect Callback called before doing a redirect */ void setShouldRedirect(@Nonnull IShouldRedirect shouldRedirect); - + /** * Gets the should redirect callback - * + * * @return Callback which is called before redirect */ @Nullable IShouldRedirect getShouldRedirect(); - + /** * Sets the should retry callback - * + * * @param shouldretry The callback called before retry */ void setShouldRetry(@Nonnull IShouldRetry shouldretry); - + /** * Gets the should retry callback - * + * * @return Callback called before retry */ @Nullable IShouldRetry getShouldRetry(); - + /** * Sets the max retries - * + * * @param maxRetries Max retries for a request */ void setMaxRetries(int maxRetries); - + /** - * Gets max retries - * + * Gets max retries + * * @return Max retries for a request */ int getMaxRetries(); - + /** * Sets the delay in seconds between retires - * + * * @param delay Delay in seconds between retries */ void setDelay(long delay); - + /** * Gets delay between retries - * + * * @return Delay between retries in seconds */ long getDelay(); @@ -175,22 +173,26 @@ public interface IHttpRequest { */ @Nullable IHttpRequest withHttpMethod(@Nonnull final HttpMethod httpMethod); - + /** * Returns the Request object to be executed + * @param type of a request for the native http client * @return the Request object to be executed */ @Nullable - Request getHttpRequest() throws ClientException; + default nativeRequestType getHttpRequest() throws ClientException { + return getHttpRequest(null); //TODO do something for the nonnull annotation + } /** * Returns the Request object to be executed * @param serializedObject the object to serialize at the body of the request * @param the type of the serialized object * @param the type of the response + * @param type of a request for the native http client * @return the Request object to be executed */ @Nullable - Request getHttpRequest(@Nonnull final requestBodyType serializedObject) throws ClientException; + nativeRequestType getHttpRequest(@Nonnull final requestBodyType serializedObject) throws ClientException; } diff --git a/src/main/java/com/microsoft/graph/http/IHttpStreamRequest.java b/src/main/java/com/microsoft/graph/http/IHttpStreamRequest.java index cdb6582e3..77b8d6065 100644 --- a/src/main/java/com/microsoft/graph/http/IHttpStreamRequest.java +++ b/src/main/java/com/microsoft/graph/http/IHttpStreamRequest.java @@ -1,16 +1,16 @@ // ------------------------------------------------------------------------------ // Copyright (c) 2017 Microsoft Corporation -// +// // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sub-license, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: -// +// // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. -// +// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE diff --git a/src/main/java/com/microsoft/graph/http/IRequestBuilder.java b/src/main/java/com/microsoft/graph/http/IRequestBuilder.java index a32742cbf..896aa0d75 100644 --- a/src/main/java/com/microsoft/graph/http/IRequestBuilder.java +++ b/src/main/java/com/microsoft/graph/http/IRequestBuilder.java @@ -1,16 +1,16 @@ // ------------------------------------------------------------------------------ // Copyright (c) 2017 Microsoft Corporation -// +// // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sub-license, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: -// +// // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. -// +// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -35,15 +35,15 @@ public interface IRequestBuilder { /** * Gets the client for this request builder - * + * * @return the client for this request builder */ @Nullable - IBaseClient getClient(); + IBaseClient getClient(); /** * Gets the request URL - * + * * @return the request URL */ @Nullable @@ -51,7 +51,7 @@ public interface IRequestBuilder { /** * Gets the request URL with an additional segment - * + * * @param urlSegment the segment to add to the URL * @return the new request URL */ diff --git a/src/main/java/com/microsoft/graph/http/PrimitiveRequest.java b/src/main/java/com/microsoft/graph/http/PrimitiveRequest.java index b50ffc1a5..6754c4f98 100644 --- a/src/main/java/com/microsoft/graph/http/PrimitiveRequest.java +++ b/src/main/java/com/microsoft/graph/http/PrimitiveRequest.java @@ -22,13 +22,10 @@ package com.microsoft.graph.http; -import com.microsoft.graph.http.IRequestBuilder; import com.microsoft.graph.core.ClientException; import javax.annotation.Nullable; import javax.annotation.Nonnull; import com.microsoft.graph.core.IBaseClient; -import com.microsoft.graph.http.BaseRequest; -import com.microsoft.graph.http.HttpMethod; /** * The class for the Primitive Request. @@ -44,7 +41,7 @@ public class PrimitiveRequest extends BaseRequest { * @param requestOptions the options for this request * @param primitiveTypeClass the return type class for the request */ - public PrimitiveRequest(@Nonnull final String requestUrl, @Nonnull final IBaseClient client, @Nullable final java.util.List requestOptions, @Nonnull final Class primitiveTypeClass) { + public PrimitiveRequest(@Nonnull final String requestUrl, @Nonnull final IBaseClient client, @Nullable final java.util.List requestOptions, @Nonnull final Class primitiveTypeClass) { super(requestUrl, client, requestOptions, primitiveTypeClass); } diff --git a/src/main/java/com/microsoft/graph/http/PrimitiveRequestBuilder.java b/src/main/java/com/microsoft/graph/http/PrimitiveRequestBuilder.java index a82d79fc6..8260c8744 100644 --- a/src/main/java/com/microsoft/graph/http/PrimitiveRequestBuilder.java +++ b/src/main/java/com/microsoft/graph/http/PrimitiveRequestBuilder.java @@ -22,14 +22,9 @@ package com.microsoft.graph.http; -import com.microsoft.graph.http.IRequestBuilder; -import com.microsoft.graph.core.ClientException; -import java.util.Arrays; -import java.util.EnumSet; import javax.annotation.Nullable; import javax.annotation.Nonnull; import com.microsoft.graph.core.IBaseClient; -import com.microsoft.graph.http.BaseRequestBuilder; /** * The class for the Primitive Request Builder. @@ -46,7 +41,7 @@ public class PrimitiveRequestBuilder extends BaseRequestBuilder { * @param requestOptions the options for this request * @param primitiveTypeClass the return type class for the request */ - public PrimitiveRequestBuilder(@Nonnull final String requestUrl, @Nonnull final IBaseClient client, @Nullable final java.util.List requestOptions, @Nonnull final Class primitiveTypeClass) { + public PrimitiveRequestBuilder(@Nonnull final String requestUrl, @Nonnull final IBaseClient client, @Nullable final java.util.List requestOptions, @Nonnull final Class primitiveTypeClass) { super(requestUrl, client, requestOptions); this._returnTypeClass = primitiveTypeClass; } @@ -70,6 +65,6 @@ public PrimitiveRequest buildRequest(@Nullable final com.microsoft.graph.opti */ @Nonnull public PrimitiveRequest buildRequest(@Nonnull final java.util.List requestOptions) { - return new PrimitiveRequest(getRequestUrl(), getClient(), requestOptions, this._returnTypeClass); + return new PrimitiveRequest<>(getRequestUrl(), getClient(), requestOptions, this._returnTypeClass); } } diff --git a/src/main/java/com/microsoft/graph/serializer/CollectionPageSerializer.java b/src/main/java/com/microsoft/graph/serializer/CollectionPageSerializer.java index 8c73cb686..6431aa676 100644 --- a/src/main/java/com/microsoft/graph/serializer/CollectionPageSerializer.java +++ b/src/main/java/com/microsoft/graph/serializer/CollectionPageSerializer.java @@ -24,6 +24,7 @@ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Type; +import java.util.ArrayList; import java.util.List; import javax.annotation.Nullable; diff --git a/src/test/java/com/microsoft/graph/content/BatchRequestContentTest.java b/src/test/java/com/microsoft/graph/content/BatchRequestContentTest.java new file mode 100644 index 000000000..4c970fa9f --- /dev/null +++ b/src/test/java/com/microsoft/graph/content/BatchRequestContentTest.java @@ -0,0 +1,245 @@ +package com.microsoft.graph.content; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.net.MalformedURLException; +import java.net.URL; +import java.util.Arrays; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.concurrent.ThreadLocalRandom; + +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import com.microsoft.graph.authentication.IAuthenticationProvider; +import com.microsoft.graph.core.BaseClient; +import com.microsoft.graph.core.IBaseClient; +import com.microsoft.graph.http.CoreHttpProvider; +import com.microsoft.graph.http.HttpMethod; +import com.microsoft.graph.http.IHttpRequest; +import com.microsoft.graph.logger.ILogger; +import com.microsoft.graph.options.HeaderOption; +import com.microsoft.graph.serializer.AdditionalDataManager; +import com.microsoft.graph.serializer.DefaultSerializer; +import com.microsoft.graph.serializer.IJsonBackedObject; +import com.microsoft.graph.serializer.ISerializer; + +import org.junit.jupiter.api.Test; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; + +import okhttp3.Call; +import okhttp3.MediaType; +import okhttp3.OkHttpClient; +import okhttp3.Protocol; +import okhttp3.Request; +import okhttp3.Response; +import okhttp3.ResponseBody; + +public class BatchRequestContentTest { + + String testurl = "http://graph.microsoft.com/me"; + + @Test + public void testBatchRequestContentCreation() throws MalformedURLException { + BatchRequestContent requestContent = new BatchRequestContent(); + for (int i = 0; i < 5; i++) { + IHttpRequest requestStep = mock(IHttpRequest.class); + when(requestStep.getRequestUrl()).thenReturn(new URL(testurl)); + requestContent.addBatchRequestStep(requestStep); + } + assertTrue(requestContent.requests != null); + } + + @Test + public void testGetBatchRequestContent() throws MalformedURLException { + IHttpRequest requestStep = mock(IHttpRequest.class); + when(requestStep.getRequestUrl()).thenReturn(new URL(testurl)); + BatchRequestContent requestContent = new BatchRequestContent(); + String stepId = requestContent.addBatchRequestStep(requestStep); + String content = new DefaultSerializer(mock(ILogger.class)).serializeObject(requestContent); + String expectedContent = "{\"requests\":[{\"url\":\"http://graph.microsoft.com/me\",\"method\":\"GET\",\"id\":\"" + + stepId + "\"}]}"; + assertEquals(expectedContent, content); + } + + @Test + public void testGetBatchRequestContentWithHeader() throws MalformedURLException { + IHttpRequest requestStep = mock(IHttpRequest.class); + when(requestStep.getRequestUrl()).thenReturn(new URL(testurl)); + when(requestStep.getHeaders()).thenReturn(Arrays.asList(new HeaderOption("testkey", "testvalue"))); + BatchRequestContent requestContent = new BatchRequestContent(); + String stepId = requestContent.addBatchRequestStep(requestStep); + String content = new DefaultSerializer(mock(ILogger.class)).serializeObject(requestContent); + String expectedContent = "{\"requests\":[{\"url\":\"http://graph.microsoft.com/me\",\"method\":\"GET\",\"id\":\"" + + stepId + "\",\"headers\":{\"testkey\":\"testvalue\"}}]}"; + assertEquals(expectedContent, content); + } + + @Test + public void testRemoveBatchRequesStepWithId() throws MalformedURLException { + IHttpRequest requestStep = mock(IHttpRequest.class); + when(requestStep.getRequestUrl()).thenReturn(new URL(testurl)); + BatchRequestContent requestContent = new BatchRequestContent(); + String stepId = requestContent.addBatchRequestStep(requestStep); + requestContent.removeBatchRequestStepWithId(stepId); + String content = new DefaultSerializer(mock(ILogger.class)).serializeObject(requestContent); + String expectedContent = "{\"requests\":[]}"; + assertEquals(expectedContent, content); + } + + @Test + public void testRemoveBatchRequesStepWithIdByAddingMultipleBatchSteps() throws MalformedURLException { + IHttpRequest requestStep = mock(IHttpRequest.class); + when(requestStep.getRequestUrl()).thenReturn(new URL(testurl)); + BatchRequestContent requestContent = new BatchRequestContent(); + String stepId = requestContent.addBatchRequestStep(requestStep); + + IHttpRequest requestStep1 = mock(IHttpRequest.class); + when(requestStep1.getRequestUrl()).thenReturn(new URL(testurl)); + + String step1Id = requestContent.addBatchRequestStep(requestStep1, HttpMethod.GET, null, stepId); + + requestContent.removeBatchRequestStepWithId(stepId); + String content = new DefaultSerializer(mock(ILogger.class)).serializeObject(requestContent); + String expectedContent = "{\"requests\":[{\"url\":\"http://graph.microsoft.com/me\",\"method\":\"GET\",\"id\":\"" + + step1Id + "\"}]}"; + assertEquals(expectedContent, content); + } + + @Test + public void defensiveProgrammingTests() { + assertThrows(NullPointerException.class, () -> { + new BatchRequestContent().addBatchRequestStep(null); + }, "should throw argument exception"); + assertThrows(NullPointerException.class, () -> { + new BatchRequestContent().addBatchRequestStep(mock(IHttpRequest.class), null); + }, "null http method throws"); + + assertThrows(NullPointerException.class, () -> { + new BatchRequestContent().getStepById(null); + }, "get step by id with null id throws"); + + assertThrows(NullPointerException.class, () -> { + new BatchRequestContent() { + { + requests = new ArrayList<>(); + } + }.removeBatchRequestStepWithId((String) null); + }, "remove step by id with null id throws"); + + assertThrows(IllegalArgumentException.class, () -> { + new BatchRequestContent().addBatchRequestStep(mock(IHttpRequest.class), HttpMethod.GET, null, "1"); + }, "dependency on inexisting step throws"); + } + + @Test + public void executeBatchTest() throws Throwable { + final BatchRequestContent content = new BatchRequestContent(); + IHttpRequest requestStep = mock(IHttpRequest.class); + when(requestStep.getRequestUrl()).thenReturn(new URL(testurl)); + final String stepId = content.addBatchRequestStep(requestStep); + + final OkHttpClient mHttpClient = mock(OkHttpClient.class); + final Call mCall = mock(Call.class); + when(mHttpClient.newCall(any(Request.class))).thenReturn(mCall); + + final CoreHttpProvider mHttpProvider = new CoreHttpProvider(new DefaultSerializer(mock(ILogger.class)), + mock(ILogger.class), mHttpClient); + final IBaseClient mClient = BaseClient.builder().authenticationProvider(mock(IAuthenticationProvider.class)) + .httpProvider(mHttpProvider).buildClient(); + final Response mResponse = new Response.Builder() + .request(new Request.Builder().url("https://graph.microsoft.com/v1.0/$batch").build()).code(200) + .protocol(Protocol.HTTP_1_1).message("OK").addHeader("Content-type", "application/json") + .body(ResponseBody.create( + "{\"responses\": [{\"id\": \"" + stepId + "\",\"status\": 200,\"body\": null}]}", + MediaType.parse("application/json"))) + .build(); + when(mCall.execute()).thenReturn(mResponse); + final BatchResponseContent batchResponse = mClient.batch().buildRequest().post(content); + assertNotNull(mClient.batch().buildRequest().postAsync(content)); + final BatchResponseStep response = batchResponse.getResponseById(stepId); + assertNotNull(response); + } + + @Test + public void usesHttpMethodFromRequestIfAlreadySet() throws MalformedURLException { + IHttpRequest requestStep = mock(IHttpRequest.class); + when(requestStep.getRequestUrl()).thenReturn(new URL(testurl)); + when(requestStep.getHttpMethod()).thenReturn(HttpMethod.DELETE); + final BatchRequestContent batchRequest = new BatchRequestContent(); + final String stepId = batchRequest.addBatchRequestStep(requestStep); + assertEquals("DELETE", batchRequest.getStepById(stepId).method); + } + + @Test + public void doesntThrowWhenTryingToRemoveRequestFromNull() { + final BatchRequestContent batchRequest = new BatchRequestContent(); + batchRequest.removeBatchRequestStepWithId("id"); + } + + @Test + public void doesntRemoveDependsOnWhenNotEmpty() throws MalformedURLException { + IHttpRequest requestStep = mock(IHttpRequest.class); + when(requestStep.getRequestUrl()).thenReturn(new URL(testurl)); + final BatchRequestContent batchRequest = new BatchRequestContent(); + final String stepId = batchRequest.addBatchRequestStep(requestStep); + final String stepId2 = batchRequest.addBatchRequestStep(requestStep); + final String stepId3 = batchRequest.addBatchRequestStep(requestStep, HttpMethod.GET, null, stepId, stepId2); + + batchRequest.removeBatchRequestStepWithId(stepId); + + assertNotNull(batchRequest.getStepById(stepId3).dependsOn); + } + + @Test + public void addsContentTypeForBodies() throws MalformedURLException { + IHttpRequest requestStep = mock(IHttpRequest.class); + when(requestStep.getRequestUrl()).thenReturn(new URL(testurl)); + final BatchRequestContent batchRequest = new BatchRequestContent(); + final IJsonBackedObject body = new IJsonBackedObject() { + + @Override + public void setRawObject(ISerializer serializer, JsonObject json) { + // TODO Auto-generated method stub + + } + + @Override + public AdditionalDataManager additionalDataManager() { + // TODO Auto-generated method stub + return null; + } + + }; + final String stepId = batchRequest.addBatchRequestStep(requestStep, HttpMethod.POST, body); + final BatchRequestStep step = batchRequest.getStepById(stepId); + assertNotNull(step.headers); + assertEquals("application/json", step.headers.get("content-type")); + + when(requestStep.getHeaders()).thenReturn(Arrays.asList(new HeaderOption("dummy", "dummy"))); + final String stepId2 = batchRequest.addBatchRequestStep(requestStep, HttpMethod.POST, body); + final BatchRequestStep step2 = batchRequest.getStepById(stepId2); + assertNotNull(step2.headers); + assertEquals("application/json", step2.headers.get("content-type")); + + final String stepId3 = batchRequest.addBatchRequestStep(requestStep, HttpMethod.POST, Integer.valueOf(10)); + final BatchRequestStep step3 = batchRequest.getStepById(stepId3); + assertNotNull(step3.headers); + assertNull(step3.headers.get("content-type")); + + when(requestStep.getHeaders()).thenReturn(Arrays.asList(new HeaderOption("Content-type", "application/octect-stream"))); + final String stepId4 = batchRequest.addBatchRequestStep(requestStep, HttpMethod.POST, Integer.valueOf(10)); + final BatchRequestStep step4 = batchRequest.getStepById(stepId4); + assertNotNull(step4.headers); + assertEquals("application/octect-stream", step4.headers.get("content-type")); + } +} diff --git a/src/test/java/com/microsoft/graph/content/MSBatchResponseContentTest.java b/src/test/java/com/microsoft/graph/content/BatchResponseContentTest.java similarity index 66% rename from src/test/java/com/microsoft/graph/content/MSBatchResponseContentTest.java rename to src/test/java/com/microsoft/graph/content/BatchResponseContentTest.java index eda781691..27ae876e5 100644 --- a/src/test/java/com/microsoft/graph/content/MSBatchResponseContentTest.java +++ b/src/test/java/com/microsoft/graph/content/BatchResponseContentTest.java @@ -2,11 +2,22 @@ import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.mockito.Mockito.mock; import java.io.IOException; import java.util.Iterator; import java.util.Map; +import com.google.gson.JsonElement; +import com.microsoft.graph.http.GraphErrorResponse; +import com.microsoft.graph.http.GraphServiceException; +import com.microsoft.graph.logger.ILogger; +import com.microsoft.graph.serializer.DefaultSerializer; +import com.microsoft.graph.serializer.ISerializer; + import org.junit.jupiter.api.Test; import okhttp3.MediaType; @@ -16,105 +27,95 @@ import okhttp3.Response; import okhttp3.ResponseBody; -public class MSBatchResponseContentTest { - - @Test - public void testNullMSBatchResponseContent() { - assertThrows(NullPointerException.class, () -> { - new MSBatchResponseContent((Response)null); - }, "should throw argument exception"); - } - +public class BatchResponseContentTest { @Test - public void testValidMSBatchResponseContent() { + public void testValidBatchResponseContent() { String responsebody = "{\"responses\": [{\"id\": \"1\",\"status\":200,\"headers\" : {\"Cache-Control\":\"no-cache\",\"OData-Version\":\"4.0\",\"Content-Type\":\"application/json;odata.metadata=minimal;odata.streaming=true;IEEE754Compatible=false;charset=utf-8\"},\"body\":{\"@odata.context\":\"https://graph.microsoft.com/v1.0/$metadata#users/$entity\",\"businessPhones\":[\"8006427676\"],\"displayName\":\"MOD Administrator\",\"givenName\":\"MOD\",\"jobTitle\":null,\"mail\":\"admin@M365x751487.OnMicrosoft.com\",\"mobilePhone\":\"425-882-1032\",\"officeLocation\":null,\"preferredLanguage\":\"en-US\",\"surname\":\"Administrator\",\"userPrincipalName\":\"admin@M365x751487.onmicrosoft.com\",\"id\":\"6b4fa8ea-7e6e-486e-a8f4-d00a5b23488c\"}},{\"id\": \"2\",\"status\":200,\"headers\" : {\"Cache-Control\":\"no-store, no-cache\",\"OData-Version\":\"4.0\",\"Content-Type\":\"application/json;odata.metadata=minimal;odata.streaming=true;IEEE754Compatible=false;charset=utf-8\"},\"body\":{\"@odata.context\":\"https://graph.microsoft.com/v1.0/$metadata#drives/$entity\",\"createdDateTime\":\"2019-01-12T09:05:38Z\",\"description\":\"\",\"id\":\"b!nlu9o5I9g0y8gsHXfUM_bPTZ0oM_wVNArHM5R4-VkHLlnxx5SpqHRJledwfICP9f\",\"lastModifiedDateTime\":\"2019-03-06T06:59:04Z\",\"name\":\"OneDrive\",\"webUrl\":\"https://m365x751487-my.sharepoint.com/personal/admin_m365x751487_onmicrosoft_com/Documents\",\"driveType\":\"business\",\"createdBy\":{\"user\":{\"displayName\":\"System Account\"}},\"lastModifiedBy\":{\"user\":{\"displayName\":\"System Account\"}},\"owner\":{\"user\":{\"email\":\"admin@M365x751487.OnMicrosoft.com\",\"id\":\"6b4fa8ea-7e6e-486e-a8f4-d00a5b23488c\",\"displayName\":\"MOD Administrator\"}},\"quota\":{\"deleted\":0,\"remaining\":1099509670098,\"state\":\"normal\",\"total\":1099511627776,\"used\":30324}}},{\"id\": \"3\",\"status\":201,\"headers\" : {\"Location\":\"https://graph.microsoft.com/v1.0/users/6b4fa8ea-7e6e-486e-a8f4-d00a5b23488c/onenote/notebooks/1-94e4376a-a1c1-441a-8b41-af5c86ee39d0\",\"Preference-Applied\":\"odata.include-annotations=*\",\"Cache-Control\":\"no-cache\",\"OData-Version\":\"4.0\",\"Content-Type\":\"application/json;odata.metadata=minimal;odata.streaming=true;IEEE754Compatible=false;charset=utf-8\"},\"body\":{\"@odata.context\":\"https://graph.microsoft.com/v1.0/$metadata#users('6b4fa8ea-7e6e-486e-a8f4-d00a5b23488c')/onenote/notebooks/$entity\",\"id\":\"1-94e4376a-a1c1-441a-8b41-af5c86ee39d0\",\"self\":\"https://graph.microsoft.com/v1.0/users/6b4fa8ea-7e6e-486e-a8f4-d00a5b23488c/onenote/notebooks/1-94e4376a-a1c1-441a-8b41-af5c86ee39d0\",\"createdDateTime\":\"2019-03-06T08:08:09Z\",\"displayName\":\"My Notebook -442293399\",\"lastModifiedDateTime\":\"2019-03-06T08:08:09Z\",\"isDefault\":false,\"userRole\":\"Owner\",\"isShared\":false,\"sectionsUrl\":\"https://graph.microsoft.com/v1.0/users/6b4fa8ea-7e6e-486e-a8f4-d00a5b23488c/onenote/notebooks/1-94e4376a-a1c1-441a-8b41-af5c86ee39d0/sections\",\"sectionGroupsUrl\":\"https://graph.microsoft.com/v1.0/users/6b4fa8ea-7e6e-486e-a8f4-d00a5b23488c/onenote/notebooks/1-94e4376a-a1c1-441a-8b41-af5c86ee39d0/sectionGroups\",\"createdBy\":{\"user\":{\"id\":\"6b4fa8ea-7e6e-486e-a8f4-d00a5b23488c\",\"displayName\":\"MOD Administrator\"}},\"lastModifiedBy\":{\"user\":{\"id\":\"6b4fa8ea-7e6e-486e-a8f4-d00a5b23488c\",\"displayName\":\"MOD Administrator\"}},\"links\":{\"oneNoteClientUrl\":{\"href\":\"onenote:https://m365x751487-my.sharepoint.com/personal/admin_m365x751487_onmicrosoft_com/Documents/Notebooks/My%20Notebook%20-442293399\"},\"oneNoteWebUrl\":{\"href\":\"https://m365x751487-my.sharepoint.com/personal/admin_m365x751487_onmicrosoft_com/Documents/Notebooks/My%20Notebook%20-442293399\"}}}}]}"; - String requestbody = "{\"requests\":[{\"method\":\"GET\",\"dependsOn\":[],\"id\":\"1\",\"url\":\"me\"},{\"method\":\"GET\",\"dependsOn\":[],\"id\":\"2\",\"url\":\"me\\/drive\"},{\"headers\":{\"content-type\":\"application\\/json\"},\"method\":\"POST\",\"dependsOn\":[],\"id\":\"3\",\"body\":{\"displayName\":\"My Notebook -1263732088\"},\"url\":\"me\\/onenote\\/notebooks\"}]}"; - Response responsedata = TestResponse(responsebody, requestbody); - MSBatchResponseContent batchresponse = new MSBatchResponseContent(responsedata); - assertTrue(batchresponse.getResponses() != null); + BatchResponseContent batchresponse = new DefaultSerializer(mock(ILogger.class)).deserializeObject(responsebody, BatchResponseContent.class); + assertTrue(batchresponse.responses != null); } @Test - public void testInvalidMSBatchResponseContentWithEmptyResponse() { + public void testInvalidBatchResponseContentWithEmptyResponse() { String responsebody = "{\"responses\": [] }"; - String requestbody = "{\"requests\":[]}"; - Response responsedata = TestResponse(responsebody, requestbody); - MSBatchResponseContent batchresponse = new MSBatchResponseContent(responsedata); + BatchResponseContent batchresponse = new DefaultSerializer(mock(ILogger.class)).deserializeObject(responsebody, BatchResponseContent.class); assertTrue(batchresponse.getResponseById("1") == null); } @Test - public void testInvalidMSBatchResponseContentWithNullResponseString() { - assertThrows(NullPointerException.class, () -> { - new MSBatchResponseContent(null); - }, "should throw argument exception"); - } - - @Test - public void testInvalidMSBatchResponseContentWithMalformedResponse() { + public void testInvalidBatchResponseContentWithMalformedResponse() { String invalidResponsebody = "{responses: [] }"; - String requestbody = "{requests:[]}"; - Response invalidResponsedata = TestResponse(invalidResponsebody, requestbody); - MSBatchResponseContent batchresponse = new MSBatchResponseContent(invalidResponsedata); - assertTrue(batchresponse.getResponses().keySet().isEmpty()); + BatchResponseContent batchresponse = new DefaultSerializer(mock(ILogger.class)).deserializeObject(invalidResponsebody, BatchResponseContent.class); + assertTrue(batchresponse.responses.isEmpty()); } @Test - public void testGetMSBatchResponseContentByID() throws IOException { + public void testGetBatchResponseContentByID() throws IOException { String responsebody = "{\"responses\": [{\"id\": \"1\",\"status\":200,\"headers\" : {\"Cache-Control\":\"no-cache\",\"OData-Version\":\"4.0\",\"Content-Type\":\"application/json;odata.metadata=minimal;odata.streaming=true;IEEE754Compatible=false;charset=utf-8\"},\"body\":{\"@odata.context\":\"https://graph.microsoft.com/v1.0/$metadata#users/$entity\",\"businessPhones\":[\"8006427676\"],\"displayName\":\"MOD Administrator\",\"givenName\":\"MOD\",\"jobTitle\":null,\"mail\":\"admin@M365x751487.OnMicrosoft.com\",\"mobilePhone\":\"425-882-1032\",\"officeLocation\":null,\"preferredLanguage\":\"en-US\",\"surname\":\"Administrator\",\"userPrincipalName\":\"admin@M365x751487.onmicrosoft.com\",\"id\":\"6b4fa8ea-7e6e-486e-a8f4-d00a5b23488c\"}},{\"id\": \"2\",\"status\":200,\"headers\" : {\"Cache-Control\":\"no-store, no-cache\",\"OData-Version\":\"4.0\",\"Content-Type\":\"application/json;odata.metadata=minimal;odata.streaming=true;IEEE754Compatible=false;charset=utf-8\"},\"body\":{\"@odata.context\":\"https://graph.microsoft.com/v1.0/$metadata#drives/$entity\",\"createdDateTime\":\"2019-01-12T09:05:38Z\",\"description\":\"\",\"id\":\"b!nlu9o5I9g0y8gsHXfUM_bPTZ0oM_wVNArHM5R4-VkHLlnxx5SpqHRJledwfICP9f\",\"lastModifiedDateTime\":\"2019-03-06T06:59:04Z\",\"name\":\"OneDrive\",\"webUrl\":\"https://m365x751487-my.sharepoint.com/personal/admin_m365x751487_onmicrosoft_com/Documents\",\"driveType\":\"business\",\"createdBy\":{\"user\":{\"displayName\":\"System Account\"}},\"lastModifiedBy\":{\"user\":{\"displayName\":\"System Account\"}},\"owner\":{\"user\":{\"email\":\"admin@M365x751487.OnMicrosoft.com\",\"id\":\"6b4fa8ea-7e6e-486e-a8f4-d00a5b23488c\",\"displayName\":\"MOD Administrator\"}},\"quota\":{\"deleted\":0,\"remaining\":1099509670098,\"state\":\"normal\",\"total\":1099511627776,\"used\":30324}}},{\"id\": \"3\",\"status\":201,\"headers\" : {\"Location\":\"https://graph.microsoft.com/v1.0/users/6b4fa8ea-7e6e-486e-a8f4-d00a5b23488c/onenote/notebooks/1-94e4376a-a1c1-441a-8b41-af5c86ee39d0\",\"Preference-Applied\":\"odata.include-annotations=*\",\"Cache-Control\":\"no-cache\",\"OData-Version\":\"4.0\",\"Content-Type\":\"application/json;odata.metadata=minimal;odata.streaming=true;IEEE754Compatible=false;charset=utf-8\"},\"body\":{\"@odata.context\":\"https://graph.microsoft.com/v1.0/$metadata#users('6b4fa8ea-7e6e-486e-a8f4-d00a5b23488c')/onenote/notebooks/$entity\",\"id\":\"1-94e4376a-a1c1-441a-8b41-af5c86ee39d0\",\"self\":\"https://graph.microsoft.com/v1.0/users/6b4fa8ea-7e6e-486e-a8f4-d00a5b23488c/onenote/notebooks/1-94e4376a-a1c1-441a-8b41-af5c86ee39d0\",\"createdDateTime\":\"2019-03-06T08:08:09Z\",\"displayName\":\"My Notebook -442293399\",\"lastModifiedDateTime\":\"2019-03-06T08:08:09Z\",\"isDefault\":false,\"userRole\":\"Owner\",\"isShared\":false,\"sectionsUrl\":\"https://graph.microsoft.com/v1.0/users/6b4fa8ea-7e6e-486e-a8f4-d00a5b23488c/onenote/notebooks/1-94e4376a-a1c1-441a-8b41-af5c86ee39d0/sections\",\"sectionGroupsUrl\":\"https://graph.microsoft.com/v1.0/users/6b4fa8ea-7e6e-486e-a8f4-d00a5b23488c/onenote/notebooks/1-94e4376a-a1c1-441a-8b41-af5c86ee39d0/sectionGroups\",\"createdBy\":{\"user\":{\"id\":\"6b4fa8ea-7e6e-486e-a8f4-d00a5b23488c\",\"displayName\":\"MOD Administrator\"}},\"lastModifiedBy\":{\"user\":{\"id\":\"6b4fa8ea-7e6e-486e-a8f4-d00a5b23488c\",\"displayName\":\"MOD Administrator\"}},\"links\":{\"oneNoteClientUrl\":{\"href\":\"onenote:https://m365x751487-my.sharepoint.com/personal/admin_m365x751487_onmicrosoft_com/Documents/Notebooks/My%20Notebook%20-442293399\"},\"oneNoteWebUrl\":{\"href\":\"https://m365x751487-my.sharepoint.com/personal/admin_m365x751487_onmicrosoft_com/Documents/Notebooks/My%20Notebook%20-442293399\"}}}}]}"; - String requestbody = "{\"requests\":[{\"method\":\"GET\",\"dependsOn\":[],\"id\":\"1\",\"url\":\"me\"},{\"method\":\"GET\",\"dependsOn\":[],\"id\":\"2\",\"url\":\"me\\/drive\"},{\"headers\":{\"content-type\":\"application\\/json\"},\"method\":\"POST\",\"dependsOn\":[],\"id\":\"3\",\"body\":{\"displayName\":\"My Notebook -1263732088\"},\"url\":\"me\\/onenote\\/notebooks\"}]}"; - Response responsedata = TestResponse(responsebody,requestbody); - MSBatchResponseContent batchresponse = new MSBatchResponseContent(responsedata); - Response response = batchresponse.getResponseById("1"); + BatchResponseContent batchresponse = new DefaultSerializer(mock(ILogger.class)).deserializeObject(responsebody, BatchResponseContent.class); + BatchResponseStep response = batchresponse.getResponseById("1"); assertTrue(response != null); } @Test - public void testGetMSBatchResponseContentIteratorOverResponse() throws IOException { + public void testGetBatchResponseContentIteratorOverResponse() throws IOException { String responsebody = "{\"responses\": [{\"id\": \"1\",\"status\":200,\"headers\" : {\"Cache-Control\":\"no-cache\",\"OData-Version\":\"4.0\",\"Content-Type\":\"application/json;odata.metadata=minimal;odata.streaming=true;IEEE754Compatible=false;charset=utf-8\"},\"body\":{\"@odata.context\":\"https://graph.microsoft.com/v1.0/$metadata#users/$entity\",\"businessPhones\":[\"8006427676\"],\"displayName\":\"MOD Administrator\",\"givenName\":\"MOD\",\"jobTitle\":null,\"mail\":\"admin@M365x751487.OnMicrosoft.com\",\"mobilePhone\":\"425-882-1032\",\"officeLocation\":null,\"preferredLanguage\":\"en-US\",\"surname\":\"Administrator\",\"userPrincipalName\":\"admin@M365x751487.onmicrosoft.com\",\"id\":\"6b4fa8ea-7e6e-486e-a8f4-d00a5b23488c\"}},{\"id\": \"2\",\"status\":200,\"headers\" : {\"Cache-Control\":\"no-store, no-cache\",\"OData-Version\":\"4.0\",\"Content-Type\":\"application/json;odata.metadata=minimal;odata.streaming=true;IEEE754Compatible=false;charset=utf-8\"},\"body\":{\"@odata.context\":\"https://graph.microsoft.com/v1.0/$metadata#drives/$entity\",\"createdDateTime\":\"2019-01-12T09:05:38Z\",\"description\":\"\",\"id\":\"b!nlu9o5I9g0y8gsHXfUM_bPTZ0oM_wVNArHM5R4-VkHLlnxx5SpqHRJledwfICP9f\",\"lastModifiedDateTime\":\"2019-03-06T06:59:04Z\",\"name\":\"OneDrive\",\"webUrl\":\"https://m365x751487-my.sharepoint.com/personal/admin_m365x751487_onmicrosoft_com/Documents\",\"driveType\":\"business\",\"createdBy\":{\"user\":{\"displayName\":\"System Account\"}},\"lastModifiedBy\":{\"user\":{\"displayName\":\"System Account\"}},\"owner\":{\"user\":{\"email\":\"admin@M365x751487.OnMicrosoft.com\",\"id\":\"6b4fa8ea-7e6e-486e-a8f4-d00a5b23488c\",\"displayName\":\"MOD Administrator\"}},\"quota\":{\"deleted\":0,\"remaining\":1099509670098,\"state\":\"normal\",\"total\":1099511627776,\"used\":30324}}},{\"id\": \"3\",\"status\":201,\"headers\" : {\"Location\":\"https://graph.microsoft.com/v1.0/users/6b4fa8ea-7e6e-486e-a8f4-d00a5b23488c/onenote/notebooks/1-94e4376a-a1c1-441a-8b41-af5c86ee39d0\",\"Preference-Applied\":\"odata.include-annotations=*\",\"Cache-Control\":\"no-cache\",\"OData-Version\":\"4.0\",\"Content-Type\":\"application/json;odata.metadata=minimal;odata.streaming=true;IEEE754Compatible=false;charset=utf-8\"},\"body\":{\"@odata.context\":\"https://graph.microsoft.com/v1.0/$metadata#users('6b4fa8ea-7e6e-486e-a8f4-d00a5b23488c')/onenote/notebooks/$entity\",\"id\":\"1-94e4376a-a1c1-441a-8b41-af5c86ee39d0\",\"self\":\"https://graph.microsoft.com/v1.0/users/6b4fa8ea-7e6e-486e-a8f4-d00a5b23488c/onenote/notebooks/1-94e4376a-a1c1-441a-8b41-af5c86ee39d0\",\"createdDateTime\":\"2019-03-06T08:08:09Z\",\"displayName\":\"My Notebook -442293399\",\"lastModifiedDateTime\":\"2019-03-06T08:08:09Z\",\"isDefault\":false,\"userRole\":\"Owner\",\"isShared\":false,\"sectionsUrl\":\"https://graph.microsoft.com/v1.0/users/6b4fa8ea-7e6e-486e-a8f4-d00a5b23488c/onenote/notebooks/1-94e4376a-a1c1-441a-8b41-af5c86ee39d0/sections\",\"sectionGroupsUrl\":\"https://graph.microsoft.com/v1.0/users/6b4fa8ea-7e6e-486e-a8f4-d00a5b23488c/onenote/notebooks/1-94e4376a-a1c1-441a-8b41-af5c86ee39d0/sectionGroups\",\"createdBy\":{\"user\":{\"id\":\"6b4fa8ea-7e6e-486e-a8f4-d00a5b23488c\",\"displayName\":\"MOD Administrator\"}},\"lastModifiedBy\":{\"user\":{\"id\":\"6b4fa8ea-7e6e-486e-a8f4-d00a5b23488c\",\"displayName\":\"MOD Administrator\"}},\"links\":{\"oneNoteClientUrl\":{\"href\":\"onenote:https://m365x751487-my.sharepoint.com/personal/admin_m365x751487_onmicrosoft_com/Documents/Notebooks/My%20Notebook%20-442293399\"},\"oneNoteWebUrl\":{\"href\":\"https://m365x751487-my.sharepoint.com/personal/admin_m365x751487_onmicrosoft_com/Documents/Notebooks/My%20Notebook%20-442293399\"}}}}]}"; - String requestbody = "{\"requests\":[{\"method\":\"GET\",\"dependsOn\":[],\"id\":\"1\",\"url\":\"me\"},{\"method\":\"GET\",\"dependsOn\":[],\"id\":\"2\",\"url\":\"me\\/drive\"},{\"headers\":{\"content-type\":\"application\\/json\"},\"method\":\"POST\",\"dependsOn\":[],\"id\":\"3\",\"body\":{\"displayName\":\"My Notebook -1263732088\"},\"url\":\"me\\/onenote\\/notebooks\"}]}"; - Response responsedata = TestResponse(responsebody,requestbody); - MSBatchResponseContent batchresponse = new MSBatchResponseContent(responsedata); - Iterator> it = batchresponse.getResponsesIterator(); + BatchResponseContent batchresponse = new DefaultSerializer(mock(ILogger.class)).deserializeObject(responsebody, BatchResponseContent.class); + Iterator> it = batchresponse.responses.iterator(); while(it.hasNext()) { - Map.Entry entry = it.next(); - assertTrue(entry.getKey()!=null && entry.getValue()!=null); + BatchResponseStep entry = it.next(); + assertTrue(entry.id != null && entry.body !=null); } } @Test - public void testGetMSBatchResponseContentMapResponse() throws IOException { + public void testGetBatchResponseContentMapResponse() throws IOException { String responsebody = "{\"responses\": [{\"id\": \"1\",\"status\":200,\"headers\" : {\"Cache-Control\":\"no-cache\",\"OData-Version\":\"4.0\",\"Content-Type\":\"application/json;odata.metadata=minimal;odata.streaming=true;IEEE754Compatible=false;charset=utf-8\"},\"body\":{\"@odata.context\":\"https://graph.microsoft.com/v1.0/$metadata#users/$entity\",\"businessPhones\":[\"8006427676\"],\"displayName\":\"MOD Administrator\",\"givenName\":\"MOD\",\"jobTitle\":null,\"mail\":\"admin@M365x751487.OnMicrosoft.com\",\"mobilePhone\":\"425-882-1032\",\"officeLocation\":null,\"preferredLanguage\":\"en-US\",\"surname\":\"Administrator\",\"userPrincipalName\":\"admin@M365x751487.onmicrosoft.com\",\"id\":\"6b4fa8ea-7e6e-486e-a8f4-d00a5b23488c\"}},{\"id\": \"2\",\"status\":200,\"headers\" : {\"Cache-Control\":\"no-store, no-cache\",\"OData-Version\":\"4.0\",\"Content-Type\":\"application/json;odata.metadata=minimal;odata.streaming=true;IEEE754Compatible=false;charset=utf-8\"},\"body\":{\"@odata.context\":\"https://graph.microsoft.com/v1.0/$metadata#drives/$entity\",\"createdDateTime\":\"2019-01-12T09:05:38Z\",\"description\":\"\",\"id\":\"b!nlu9o5I9g0y8gsHXfUM_bPTZ0oM_wVNArHM5R4-VkHLlnxx5SpqHRJledwfICP9f\",\"lastModifiedDateTime\":\"2019-03-06T06:59:04Z\",\"name\":\"OneDrive\",\"webUrl\":\"https://m365x751487-my.sharepoint.com/personal/admin_m365x751487_onmicrosoft_com/Documents\",\"driveType\":\"business\",\"createdBy\":{\"user\":{\"displayName\":\"System Account\"}},\"lastModifiedBy\":{\"user\":{\"displayName\":\"System Account\"}},\"owner\":{\"user\":{\"email\":\"admin@M365x751487.OnMicrosoft.com\",\"id\":\"6b4fa8ea-7e6e-486e-a8f4-d00a5b23488c\",\"displayName\":\"MOD Administrator\"}},\"quota\":{\"deleted\":0,\"remaining\":1099509670098,\"state\":\"normal\",\"total\":1099511627776,\"used\":30324}}},{\"id\": \"3\",\"status\":201,\"headers\" : {\"Location\":\"https://graph.microsoft.com/v1.0/users/6b4fa8ea-7e6e-486e-a8f4-d00a5b23488c/onenote/notebooks/1-94e4376a-a1c1-441a-8b41-af5c86ee39d0\",\"Preference-Applied\":\"odata.include-annotations=*\",\"Cache-Control\":\"no-cache\",\"OData-Version\":\"4.0\",\"Content-Type\":\"application/json;odata.metadata=minimal;odata.streaming=true;IEEE754Compatible=false;charset=utf-8\"},\"body\":{\"@odata.context\":\"https://graph.microsoft.com/v1.0/$metadata#users('6b4fa8ea-7e6e-486e-a8f4-d00a5b23488c')/onenote/notebooks/$entity\",\"id\":\"1-94e4376a-a1c1-441a-8b41-af5c86ee39d0\",\"self\":\"https://graph.microsoft.com/v1.0/users/6b4fa8ea-7e6e-486e-a8f4-d00a5b23488c/onenote/notebooks/1-94e4376a-a1c1-441a-8b41-af5c86ee39d0\",\"createdDateTime\":\"2019-03-06T08:08:09Z\",\"displayName\":\"My Notebook -442293399\",\"lastModifiedDateTime\":\"2019-03-06T08:08:09Z\",\"isDefault\":false,\"userRole\":\"Owner\",\"isShared\":false,\"sectionsUrl\":\"https://graph.microsoft.com/v1.0/users/6b4fa8ea-7e6e-486e-a8f4-d00a5b23488c/onenote/notebooks/1-94e4376a-a1c1-441a-8b41-af5c86ee39d0/sections\",\"sectionGroupsUrl\":\"https://graph.microsoft.com/v1.0/users/6b4fa8ea-7e6e-486e-a8f4-d00a5b23488c/onenote/notebooks/1-94e4376a-a1c1-441a-8b41-af5c86ee39d0/sectionGroups\",\"createdBy\":{\"user\":{\"id\":\"6b4fa8ea-7e6e-486e-a8f4-d00a5b23488c\",\"displayName\":\"MOD Administrator\"}},\"lastModifiedBy\":{\"user\":{\"id\":\"6b4fa8ea-7e6e-486e-a8f4-d00a5b23488c\",\"displayName\":\"MOD Administrator\"}},\"links\":{\"oneNoteClientUrl\":{\"href\":\"onenote:https://m365x751487-my.sharepoint.com/personal/admin_m365x751487_onmicrosoft_com/Documents/Notebooks/My%20Notebook%20-442293399\"},\"oneNoteWebUrl\":{\"href\":\"https://m365x751487-my.sharepoint.com/personal/admin_m365x751487_onmicrosoft_com/Documents/Notebooks/My%20Notebook%20-442293399\"}}}}]}"; - String requestbody = "{\"requests\":[{\"method\":\"GET\",\"dependsOn\":[],\"id\":\"1\",\"url\":\"me\"},{\"method\":\"GET\",\"dependsOn\":[],\"id\":\"2\",\"url\":\"me\\/drive\"},{\"headers\":{\"content-type\":\"application\\/json\"},\"method\":\"POST\",\"dependsOn\":[],\"id\":\"3\",\"body\":{\"displayName\":\"My Notebook -1263732088\"},\"url\":\"me\\/onenote\\/notebooks\"}]}"; - Response responsedata = TestResponse(responsebody,requestbody); - MSBatchResponseContent batchresponse = new MSBatchResponseContent(responsedata); - for(Map.Entry entry: batchresponse.getResponses().entrySet()) { - assertTrue(entry.getKey() != null && entry.getValue() != null); + BatchResponseContent batchresponse = new DefaultSerializer(mock(ILogger.class)).deserializeObject(responsebody, BatchResponseContent.class); + for(BatchResponseStep entry: batchresponse.responses) { + assertTrue(entry.id != null && entry.body != null); } } @Test - public void testGetMSBatchResponseContentUpdate() throws IOException { + public void testGetBatchResponseContentSize() throws IOException { String responsebody = "{\"responses\": [{\"id\": \"1\",\"status\":200,\"headers\" : {\"Cache-Control\":\"no-cache\",\"OData-Version\":\"4.0\",\"Content-Type\":\"application/json;odata.metadata=minimal;odata.streaming=true;IEEE754Compatible=false;charset=utf-8\"},\"body\":{\"@odata.context\":\"https://graph.microsoft.com/v1.0/$metadata#users/$entity\",\"businessPhones\":[\"8006427676\"],\"displayName\":\"MOD Administrator\",\"givenName\":\"MOD\",\"jobTitle\":null,\"mail\":\"admin@M365x751487.OnMicrosoft.com\",\"mobilePhone\":\"425-882-1032\",\"officeLocation\":null,\"preferredLanguage\":\"en-US\",\"surname\":\"Administrator\",\"userPrincipalName\":\"admin@M365x751487.onmicrosoft.com\",\"id\":\"6b4fa8ea-7e6e-486e-a8f4-d00a5b23488c\"}},{\"id\": \"2\",\"status\":200,\"headers\" : {\"Cache-Control\":\"no-store, no-cache\",\"OData-Version\":\"4.0\",\"Content-Type\":\"application/json;odata.metadata=minimal;odata.streaming=true;IEEE754Compatible=false;charset=utf-8\"},\"body\":{\"@odata.context\":\"https://graph.microsoft.com/v1.0/$metadata#drives/$entity\",\"createdDateTime\":\"2019-01-12T09:05:38Z\",\"description\":\"\",\"id\":\"b!nlu9o5I9g0y8gsHXfUM_bPTZ0oM_wVNArHM5R4-VkHLlnxx5SpqHRJledwfICP9f\",\"lastModifiedDateTime\":\"2019-03-06T06:59:04Z\",\"name\":\"OneDrive\",\"webUrl\":\"https://m365x751487-my.sharepoint.com/personal/admin_m365x751487_onmicrosoft_com/Documents\",\"driveType\":\"business\",\"createdBy\":{\"user\":{\"displayName\":\"System Account\"}},\"lastModifiedBy\":{\"user\":{\"displayName\":\"System Account\"}},\"owner\":{\"user\":{\"email\":\"admin@M365x751487.OnMicrosoft.com\",\"id\":\"6b4fa8ea-7e6e-486e-a8f4-d00a5b23488c\",\"displayName\":\"MOD Administrator\"}},\"quota\":{\"deleted\":0,\"remaining\":1099509670098,\"state\":\"normal\",\"total\":1099511627776,\"used\":30324}}},{\"id\": \"3\",\"status\":201,\"headers\" : {\"Location\":\"https://graph.microsoft.com/v1.0/users/6b4fa8ea-7e6e-486e-a8f4-d00a5b23488c/onenote/notebooks/1-94e4376a-a1c1-441a-8b41-af5c86ee39d0\",\"Preference-Applied\":\"odata.include-annotations=*\",\"Cache-Control\":\"no-cache\",\"OData-Version\":\"4.0\",\"Content-Type\":\"application/json;odata.metadata=minimal;odata.streaming=true;IEEE754Compatible=false;charset=utf-8\"},\"body\":{\"@odata.context\":\"https://graph.microsoft.com/v1.0/$metadata#users('6b4fa8ea-7e6e-486e-a8f4-d00a5b23488c')/onenote/notebooks/$entity\",\"id\":\"1-94e4376a-a1c1-441a-8b41-af5c86ee39d0\",\"self\":\"https://graph.microsoft.com/v1.0/users/6b4fa8ea-7e6e-486e-a8f4-d00a5b23488c/onenote/notebooks/1-94e4376a-a1c1-441a-8b41-af5c86ee39d0\",\"createdDateTime\":\"2019-03-06T08:08:09Z\",\"displayName\":\"My Notebook -442293399\",\"lastModifiedDateTime\":\"2019-03-06T08:08:09Z\",\"isDefault\":false,\"userRole\":\"Owner\",\"isShared\":false,\"sectionsUrl\":\"https://graph.microsoft.com/v1.0/users/6b4fa8ea-7e6e-486e-a8f4-d00a5b23488c/onenote/notebooks/1-94e4376a-a1c1-441a-8b41-af5c86ee39d0/sections\",\"sectionGroupsUrl\":\"https://graph.microsoft.com/v1.0/users/6b4fa8ea-7e6e-486e-a8f4-d00a5b23488c/onenote/notebooks/1-94e4376a-a1c1-441a-8b41-af5c86ee39d0/sectionGroups\",\"createdBy\":{\"user\":{\"id\":\"6b4fa8ea-7e6e-486e-a8f4-d00a5b23488c\",\"displayName\":\"MOD Administrator\"}},\"lastModifiedBy\":{\"user\":{\"id\":\"6b4fa8ea-7e6e-486e-a8f4-d00a5b23488c\",\"displayName\":\"MOD Administrator\"}},\"links\":{\"oneNoteClientUrl\":{\"href\":\"onenote:https://m365x751487-my.sharepoint.com/personal/admin_m365x751487_onmicrosoft_com/Documents/Notebooks/My%20Notebook%20-442293399\"},\"oneNoteWebUrl\":{\"href\":\"https://m365x751487-my.sharepoint.com/personal/admin_m365x751487_onmicrosoft_com/Documents/Notebooks/My%20Notebook%20-442293399\"}}}}]}"; - String requestbody = "{\"requests\":[{\"method\":\"GET\",\"dependsOn\":[],\"id\":\"1\",\"url\":\"me\"},{\"method\":\"GET\",\"dependsOn\":[],\"id\":\"2\",\"url\":\"me\\/drive\"},{\"headers\":{\"content-type\":\"application\\/json\"},\"method\":\"POST\",\"dependsOn\":[],\"id\":\"3\",\"body\":{\"displayName\":\"My Notebook -1263732088\"},\"url\":\"me\\/onenote\\/notebooks\"}]}"; - Response responsedata = TestResponse(responsebody,requestbody); - MSBatchResponseContent batchresponse = new MSBatchResponseContent(responsedata); - assertTrue(batchresponse.getResponses().size() == 3); - String responsebody2 = "{\"responses\": [{\"id\": \"4\",\"status\":200,\"headers\" : {\"Cache-Control\":\"no-cache\",\"OData-Version\":\"4.0\",\"Content-Type\":\"application/json;odata.metadata=minimal;odata.streaming=true;IEEE754Compatible=false;charset=utf-8\"},\"body\":{\"@odata.context\":\"https://graph.microsoft.com/v1.0/$metadata#users/$entity\",\"businessPhones\":[\"8006427676\"],\"displayName\":\"MOD Administrator\",\"givenName\":\"MOD\",\"jobTitle\":null,\"mail\":\"admin@M365x751487.OnMicrosoft.com\",\"mobilePhone\":\"425-882-1032\",\"officeLocation\":null,\"preferredLanguage\":\"en-US\",\"surname\":\"Administrator\",\"userPrincipalName\":\"admin@M365x751487.onmicrosoft.com\",\"id\":\"6b4fa8ea-7e6e-486e-a8f4-d00a5b23488c\"}},{\"id\": \"5\",\"status\":200,\"headers\" : {\"Cache-Control\":\"no-store, no-cache\",\"OData-Version\":\"4.0\",\"Content-Type\":\"application/json;odata.metadata=minimal;odata.streaming=true;IEEE754Compatible=false;charset=utf-8\"},\"body\":{\"@odata.context\":\"https://graph.microsoft.com/v1.0/$metadata#drives/$entity\",\"createdDateTime\":\"2019-01-12T09:05:38Z\",\"description\":\"\",\"id\":\"b!nlu9o5I9g0y8gsHXfUM_bPTZ0oM_wVNArHM5R4-VkHLlnxx5SpqHRJledwfICP9f\",\"lastModifiedDateTime\":\"2019-03-06T06:59:04Z\",\"name\":\"OneDrive\",\"webUrl\":\"https://m365x751487-my.sharepoint.com/personal/admin_m365x751487_onmicrosoft_com/Documents\",\"driveType\":\"business\",\"createdBy\":{\"user\":{\"displayName\":\"System Account\"}},\"lastModifiedBy\":{\"user\":{\"displayName\":\"System Account\"}},\"owner\":{\"user\":{\"email\":\"admin@M365x751487.OnMicrosoft.com\",\"id\":\"6b4fa8ea-7e6e-486e-a8f4-d00a5b23488c\",\"displayName\":\"MOD Administrator\"}},\"quota\":{\"deleted\":0,\"remaining\":1099509670098,\"state\":\"normal\",\"total\":1099511627776,\"used\":30324}}},{\"id\": \"6\",\"status\":201,\"headers\" : {\"Location\":\"https://graph.microsoft.com/v1.0/users/6b4fa8ea-7e6e-486e-a8f4-d00a5b23488c/onenote/notebooks/1-94e4376a-a1c1-441a-8b41-af5c86ee39d0\",\"Preference-Applied\":\"odata.include-annotations=*\",\"Cache-Control\":\"no-cache\",\"OData-Version\":\"4.0\",\"Content-Type\":\"application/json;odata.metadata=minimal;odata.streaming=true;IEEE754Compatible=false;charset=utf-8\"},\"body\":{\"@odata.context\":\"https://graph.microsoft.com/v1.0/$metadata#users('6b4fa8ea-7e6e-486e-a8f4-d00a5b23488c')/onenote/notebooks/$entity\",\"id\":\"1-94e4376a-a1c1-441a-8b41-af5c86ee39d0\",\"self\":\"https://graph.microsoft.com/v1.0/users/6b4fa8ea-7e6e-486e-a8f4-d00a5b23488c/onenote/notebooks/1-94e4376a-a1c1-441a-8b41-af5c86ee39d0\",\"createdDateTime\":\"2019-03-06T08:08:09Z\",\"displayName\":\"My Notebook -442293399\",\"lastModifiedDateTime\":\"2019-03-06T08:08:09Z\",\"isDefault\":false,\"userRole\":\"Owner\",\"isShared\":false,\"sectionsUrl\":\"https://graph.microsoft.com/v1.0/users/6b4fa8ea-7e6e-486e-a8f4-d00a5b23488c/onenote/notebooks/1-94e4376a-a1c1-441a-8b41-af5c86ee39d0/sections\",\"sectionGroupsUrl\":\"https://graph.microsoft.com/v1.0/users/6b4fa8ea-7e6e-486e-a8f4-d00a5b23488c/onenote/notebooks/1-94e4376a-a1c1-441a-8b41-af5c86ee39d0/sectionGroups\",\"createdBy\":{\"user\":{\"id\":\"6b4fa8ea-7e6e-486e-a8f4-d00a5b23488c\",\"displayName\":\"MOD Administrator\"}},\"lastModifiedBy\":{\"user\":{\"id\":\"6b4fa8ea-7e6e-486e-a8f4-d00a5b23488c\",\"displayName\":\"MOD Administrator\"}},\"links\":{\"oneNoteClientUrl\":{\"href\":\"onenote:https://m365x751487-my.sharepoint.com/personal/admin_m365x751487_onmicrosoft_com/Documents/Notebooks/My%20Notebook%20-442293399\"},\"oneNoteWebUrl\":{\"href\":\"https://m365x751487-my.sharepoint.com/personal/admin_m365x751487_onmicrosoft_com/Documents/Notebooks/My%20Notebook%20-442293399\"}}}}]}"; - String requestbody2 = "{\"requests\":[{\"method\":\"GET\",\"dependsOn\":[],\"id\":\"4\",\"url\":\"me\"},{\"method\":\"GET\",\"dependsOn\":[],\"id\":\"5\",\"url\":\"me\\/drive\"},{\"headers\":{\"content-type\":\"application\\/json\"},\"method\":\"POST\",\"dependsOn\":[],\"id\":\"6\",\"body\":{\"displayName\":\"My Notebook -1263732088\"},\"url\":\"me\\/onenote\\/notebooks\"}]}"; - Response responsedata2 = TestResponse(responsebody2,requestbody2); - batchresponse.update(responsedata2); - assertTrue(batchresponse.getResponses().size() == 6); + BatchResponseContent batchresponse = new DefaultSerializer(mock(ILogger.class)).deserializeObject(responsebody, BatchResponseContent.class); + assertTrue(batchresponse.responses.size() == 3); } - - private Response TestResponse(String responsebody, String requestbody) { - Response.Builder builder = new Response.Builder(); - builder.body(ResponseBody.create(MediaType.parse("application/json"), responsebody)); - Request request = new Request.Builder().url("https://graph.microsoft.com/").method("POST", RequestBody.create(MediaType.parse("application/json"), requestbody)).build(); - builder.request(request); - builder.protocol(Protocol.HTTP_1_0); - builder.code(200); - builder.message("test message"); - return builder.build(); + @Test + public void responseParsing() { + final BatchResponseContent batchResponse = new DefaultSerializer(mock(ILogger.class)).deserializeObject("{\"responses\": [{\"id\": \"1\",\"status\": 200,\"body\": null}]}", BatchResponseContent.class); + assertEquals(1, batchResponse.responses.size()); + final BatchResponseStep response = batchResponse.getResponseById("1"); + assertNotNull(response); + assertNull(batchResponse.getResponseById("2")); + } + @Test + public void getResponseWithIdReturnsNullOnEmptyResponses() + { + final BatchResponseContent batchResponse = new BatchResponseContent(); + assertNull(batchResponse.getResponseById("id")); + } + @Test + public void deserializesErrorsProperly() { + String responsebody = "{\"responses\":[{\"id\":\"1\",\"status\":400,\"headers\":{\"Cache-Control\":\"no-cache\",\"x-ms-resource-unit\":\"1\",\"Content-Type\":\"application/json\"},\"body\":{\"error\":{\"code\":\"Request_BadRequest\",\"message\":\"Avalueisrequiredforproperty'displayName'ofresource'User'.\",\"innerError\":{\"date\":\"2021-02-02T19:19:38\",\"request-id\":\"408b8e64-4047-4c97-95b6-46e9f212ab48\",\"client-request-id\":\"102910da-260c-3028-0fb3-7d6903a02622\"}}}}]}"; + ISerializer serializer = new DefaultSerializer(mock(ILogger.class)); + BatchResponseContent batchresponse = serializer.deserializeObject(responsebody, BatchResponseContent.class); + if(batchresponse != null && batchresponse.responses != null) // this is done by the batch request in the fluent API + for(final BatchResponseStep step : batchresponse.responses) { + step.serializer = serializer; + } + assertThrows(GraphServiceException.class, () -> { + final Object body = batchresponse.getResponseById("1").getDeserializedBody(BatchRequestContent.class); + }); + try { + final Object body = batchresponse.getResponseById("1").getDeserializedBody(BatchRequestContent.class); + } catch(GraphServiceException ex) { + final GraphErrorResponse response = ex.getError(); + assertNotNull(response); + assertNotNull(response.error); + assertNotNull(response.error.message); + } } } diff --git a/src/test/java/com/microsoft/graph/content/MSBatchRequestContentTest.java b/src/test/java/com/microsoft/graph/content/MSBatchRequestContentTest.java deleted file mode 100644 index ab1fff017..000000000 --- a/src/test/java/com/microsoft/graph/content/MSBatchRequestContentTest.java +++ /dev/null @@ -1,201 +0,0 @@ -package com.microsoft.graph.content; - -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -import java.util.HashSet; -import java.util.concurrent.ThreadLocalRandom; - -import com.google.gson.JsonParser; -import com.microsoft.graph.authentication.IAuthenticationProvider; -import com.microsoft.graph.core.BaseClient; -import com.microsoft.graph.core.IBaseClient; -import com.microsoft.graph.http.CoreHttpProvider; -import com.microsoft.graph.logger.ILogger; -import com.microsoft.graph.serializer.DefaultSerializer; - -import org.junit.jupiter.api.Test; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import okhttp3.Call; -import okhttp3.MediaType; -import okhttp3.OkHttpClient; -import okhttp3.Protocol; -import okhttp3.Request; -import okhttp3.Response; -import okhttp3.ResponseBody; - -public class MSBatchRequestContentTest { - - String testurl = "http://graph.microsoft.com/me"; - - @Test - public void testMSBatchRequestContentCreation() { - MSBatchRequestContent requestContent = new MSBatchRequestContent(); - for (int i = 0; i < 5; i++) { - Request request = new Request.Builder().url(testurl).build(); - MSBatchRequestStep requestStep = new MSBatchRequestStep("" + i, request); - requestContent.addBatchRequestStep(requestStep); - } - assertTrue(requestContent.getBatchRequestContent() != null); - } - - @Test - public void testGetBatchRequestContent() { - Request request = new Request.Builder().url(testurl).build(); - MSBatchRequestStep requestStep = new MSBatchRequestStep("1", request); - MSBatchRequestContent requestContent = new MSBatchRequestContent(); - requestContent.addBatchRequestStep(requestStep); - String content = requestContent.getBatchRequestContent(); - String expectedContent = "{\"requests\":[{\"id\":\"1\",\"url\":\"http://graph.microsoft.com/me\",\"method\":\"GET\",\"dependsOn\":[]}]}"; - assertTrue(content.compareTo(expectedContent) == 0); - } - - @Test - public void testGetBatchRequestContentWithHeader() { - Request request = new Request.Builder().url(testurl).header("testkey", "testvalue").build(); - MSBatchRequestStep requestStep = new MSBatchRequestStep("1", request); - MSBatchRequestContent requestContent = new MSBatchRequestContent(); - requestContent.addBatchRequestStep(requestStep); - String content = requestContent.getBatchRequestContent(); - System.out.println(content); - String expectedContent = "{\"requests\":[{\"id\":\"1\",\"url\":\"http://graph.microsoft.com/me\",\"method\":\"GET\",\"headers\":{\"testkey\":\"testvalue\"},\"dependsOn\":[]}]}"; - assertTrue(content.compareTo(expectedContent) == 0); - } - - @Test - public void testRemoveBatchRequesStepWithId() { - Request request = new Request.Builder().url(testurl).build(); - MSBatchRequestStep requestStep = new MSBatchRequestStep("1", request); - MSBatchRequestContent requestContent = new MSBatchRequestContent(); - requestContent.addBatchRequestStep(requestStep); - requestContent.removeBatchRequestStepWithId("1"); - String content = requestContent.getBatchRequestContent(); - String expectedContent = "{\"requests\":[]}"; - assertTrue(content.compareTo(expectedContent) == 0); - } - - @Test - public void testRemoveBatchRequesStepWithIdByAddingMultipleBatchSteps() { - Request request = new Request.Builder().url(testurl).build(); - MSBatchRequestStep requestStep = new MSBatchRequestStep("1", request); - - Request request1 = new Request.Builder().url(testurl).build(); - MSBatchRequestStep requestStep1 = new MSBatchRequestStep("2", request1, "1"); - - MSBatchRequestContent requestContent = new MSBatchRequestContent(); - requestContent.addBatchRequestStep(requestStep); - requestContent.addBatchRequestStep(requestStep1); - - requestContent.removeBatchRequestStepWithId("1"); - String content = requestContent.getBatchRequestContent(); - String expectedContent = "{\"requests\":[{\"id\":\"2\",\"url\":\"http://graph.microsoft.com/me\",\"method\":\"GET\",\"dependsOn\":[]}]}"; - assertTrue(content.compareTo(expectedContent) == 0); - } - - @Test - public void defensiveProgrammingTests() { - final MSBatchRequestStep mockStep = mock(MSBatchRequestStep.class); - final HashSet reservedIds = new HashSet<>(); - when(mockStep.getRequestId()).thenAnswer(new Answer() { - @Override - public String answer(InvocationOnMock invocation) throws Throwable { - return getNewId(reservedIds); - } - }); - - assertThrows(IllegalArgumentException.class, () -> { - new MSBatchRequestContent(mock(ILogger.class), null, null, null, null, null, null, null, null, null, null, null, null, null, - null, null, null, null, null, null, null, null, null); - }, "the number of steps cannot exceed 20"); - assertThrows(NullPointerException.class, () -> { - new MSBatchRequestContent((ILogger) null, (MSBatchRequestStep)null); - }, "the logger cannot be null"); - - new MSBatchRequestContent(mockStep, null); // addind a null step doesn't throw - assertThrows(NullPointerException.class, () -> { - new MSBatchRequestContent().addBatchRequestStep(null); - }, "should throw argument exception"); - assertThrows(NullPointerException.class, () -> { - new MSBatchRequestContent().addBatchRequestStep((Request) null); - }, "should throw argument exception"); - - assertThrows(IllegalArgumentException.class, () -> { - final MSBatchRequestContent batchContent = new MSBatchRequestContent(); - for (int i = 0; i < MSBatchRequestContent.MAX_NUMBER_OF_REQUESTS; i++) { - assertNotNull(batchContent.addBatchRequestStep(mock(Request.class))); - } - batchContent.addBatchRequestStep(mock(Request.class)); - }, "the number of steps cannot exceed 20"); - { - final MSBatchRequestContent batchContent = new MSBatchRequestContent(); - reservedIds.clear(); - for (int i = 0; i < MSBatchRequestContent.MAX_NUMBER_OF_REQUESTS; i++) { - assertTrue(batchContent.addBatchRequestStep(mockStep), "item number " + i + " should be added successfully"); - } - assertFalse(batchContent.addBatchRequestStep(mockStep)); - } - } - - private String getNewId(final HashSet reserved) { - String requestId; - do { - requestId = Integer.toString(ThreadLocalRandom.current().nextInt(1, Integer.MAX_VALUE)); - } while (reserved.contains(requestId)); - reserved.add(requestId); - return requestId; - } - - @Test - @SuppressWarnings("unchecked") - public void executeBatchTest() throws Throwable { - final MSBatchRequestStep step = new MSBatchRequestStep("1", new Request - .Builder() - .url(testurl) - .method("GET", null) - .build()); - final MSBatchRequestContent content = new MSBatchRequestContent(step); - final OkHttpClient mHttpClient = mock(OkHttpClient.class); - final Call mCall = mock(Call.class); - when(mHttpClient.newCall(any(Request.class))).thenReturn(mCall); - - final CoreHttpProvider mHttpProvider = new CoreHttpProvider(new DefaultSerializer(mock(ILogger.class)), mock(ILogger.class), mHttpClient); - final IBaseClient mClient = BaseClient.builder() - .authenticationProvider(mock(IAuthenticationProvider.class)) - .httpProvider(mHttpProvider) - .buildClient(); - final Response mResponse = new Response - .Builder() - .request(new Request - .Builder() - .url("https://graph.microsoft.com/v1.0/$batch") - .build()) - .code(200) - .protocol(Protocol.HTTP_1_1) - .message("OK") - .addHeader("Content-type", "application/json") - .body(ResponseBody.create("{\"responses\": [{\"id\": \"1\",\"status\": 200,\"body\": null}]}", - MediaType.parse("application/json"))) - .build(); - when(mCall.execute()).thenReturn(mResponse); - final MSBatchResponseContent batchResponse = content.execute(mClient); - final Response response = batchResponse.getResponseById("1"); - assertNotNull(response); - } - @Test - public void responseParsing() { - final MSBatchResponseContent batchResponse = new MSBatchResponseContent(mock(ILogger.class), "https://graph.microsoft.com/v1.0", - JsonParser.parseString("{\"requests\":[{\"id\":\"1\",\"method\":\"GET\",\"url\":\"/me\"}]}") - .getAsJsonObject(), - JsonParser.parseString("{\"responses\": [{\"id\": \"1\",\"status\": 200,\"body\": null}]}") - .getAsJsonObject()); - final Response response = batchResponse.getResponseById("1"); - assertNotNull(response); - } -} diff --git a/src/test/java/com/microsoft/graph/content/MSBatchRequestStepTest.java b/src/test/java/com/microsoft/graph/content/MSBatchRequestStepTest.java deleted file mode 100644 index 1e6d7bbf0..000000000 --- a/src/test/java/com/microsoft/graph/content/MSBatchRequestStepTest.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.microsoft.graph.content; - -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.mockito.Mockito.mock; - -import org.junit.jupiter.api.Test; - -import okhttp3.Request; - -public class MSBatchRequestStepTest { - - @Test - public void testMSBatchRequestStepCreation() { - Request request = new Request.Builder().url("http://graph.microsoft.com").build(); - MSBatchRequestStep requestStep = new MSBatchRequestStep("1", request); - assertTrue(requestStep != null, "Test BatchRequestStep creation"); - assertTrue(requestStep.getRequestId().compareTo("1") == 0, "Test Request id"); - assertTrue(requestStep.getRequest() == request, "Test Request object"); - assertTrue(requestStep.getDependsOnIds() != null, "Test Array of depends on Ids"); - } - - @Test - public void defensiveProgrammingTests() { - assertThrows(NullPointerException.class, () -> { - new MSBatchRequestStep(null, null); - }, "should throw argument exception"); - assertThrows(NullPointerException.class, () -> { - new MSBatchRequestStep("id", null); - }, "should throw argument exception"); - assertThrows(IllegalArgumentException.class, () -> { - new MSBatchRequestStep("", null); - }, "should throw argument exception"); - new MSBatchRequestStep("id", mock(Request.class)); - } - -} diff --git a/src/test/java/com/microsoft/graph/core/BaseClientTests.java b/src/test/java/com/microsoft/graph/core/BaseClientTests.java index a6733a565..a3fbfb52b 100644 --- a/src/test/java/com/microsoft/graph/core/BaseClientTests.java +++ b/src/test/java/com/microsoft/graph/core/BaseClientTests.java @@ -1,13 +1,9 @@ package com.microsoft.graph.core; import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; -import java.io.InputStream; -import java.io.ObjectOutputStream; -import java.io.OutputStream; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; @@ -35,14 +31,14 @@ */ public class BaseClientTests { public static final String DEFAULT_GRAPH_ENDPOINT = "https://graph.microsoft.com/v1.0"; - private BaseClient baseClient; - private IHttpProvider mHttpProvider; + private BaseClient baseClient; + private IHttpProvider mHttpProvider; private ILogger mLogger; private ISerializer mSerializer; @BeforeEach public void setUp() throws Exception { - baseClient = new BaseClient(); + baseClient = new BaseClient<>(); mLogger = mock(ILogger.class); mSerializer = mock(ISerializer.class); mHttpProvider = new CoreHttpProvider(mSerializer, diff --git a/src/test/java/com/microsoft/graph/core/GraphServiceClientTest.java b/src/test/java/com/microsoft/graph/core/GraphServiceClientTest.java index ee1c96772..c9a018374 100644 --- a/src/test/java/com/microsoft/graph/core/GraphServiceClientTest.java +++ b/src/test/java/com/microsoft/graph/core/GraphServiceClientTest.java @@ -35,7 +35,7 @@ private IAuthenticationProvider getAuthProvider() { @Test public void testClientMethodsReturnStuff() { ILogger logger = createLogger(); - IBaseClient client = BaseClient.builder() + IBaseClient client = BaseClient.builder() .logger(logger) .authenticationProvider(getAuthProvider()) .buildClient(); @@ -47,7 +47,7 @@ public void testClientMethodsReturnStuff() { @Test public void testOverrideOfDefaultLogger() { ILogger logger = createLogger(); - IBaseClient client = BaseClient.builder() + IBaseClient client = BaseClient.builder() .logger(logger) .authenticationProvider(getAuthProvider()) .buildClient(); @@ -61,7 +61,7 @@ public void testOverrideOfDefaultLogger() { @Test public void testOverrideOfDefaultAuthenticationProvider() { - IBaseClient client = BaseClient.builder() + IBaseClient client = BaseClient.builder() .authenticationProvider(getAuthProvider()) .buildClient(); assertNotNull(client.getHttpProvider()); @@ -98,7 +98,7 @@ public T deserializeObject(JsonElement jsonElement, Class clazz, return null; } }; - IBaseClient client = BaseClient.builder() + final IBaseClient client = BaseClient.builder() .serializer(serializer) .authenticationProvider(getAuthProvider()) .buildClient(); @@ -110,7 +110,7 @@ public T deserializeObject(JsonElement jsonElement, Class clazz, @Test public void testOverrideOfHttpSerializer() { - IHttpProvider hp = new IHttpProvider() { + IHttpProvider hp = new IHttpProvider() { @Override public ISerializer getSerializer() { @@ -147,7 +147,7 @@ public Request getHttpRequest(IHttpRequest request, Class client = BaseClient .builder() .httpProvider(hp) .buildClient(); diff --git a/src/test/java/com/microsoft/graph/http/BaseCollectionPageTests.java b/src/test/java/com/microsoft/graph/http/BaseCollectionPageTests.java index f1236fa40..91693e427 100644 --- a/src/test/java/com/microsoft/graph/http/BaseCollectionPageTests.java +++ b/src/test/java/com/microsoft/graph/http/BaseCollectionPageTests.java @@ -11,6 +11,8 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import okhttp3.Request; + import com.google.gson.JsonObject; import com.microsoft.graph.core.IBaseClient; import com.microsoft.graph.serializer.ISerializer; @@ -26,14 +28,15 @@ public class BaseCollectionPageTests { private String requestUrl = "https://a.b.c/"; @BeforeEach + @SuppressWarnings("unchecked") public void setUp() throws Exception { list = new ArrayList(); list.add("Object1"); list.add("Object2"); list.add("Object3"); - IBaseClient mBaseClient = mock(IBaseClient.class); - mRequestBuilder = new BaseRequestBuilder(requestUrl, mBaseClient, null) {}; - baseCollectionPage = new BaseCollectionPage>(list, mRequestBuilder) {}; + final IBaseClient mBaseClient = mock(IBaseClient.class); + mRequestBuilder = new BaseRequestBuilder<>(requestUrl, mBaseClient, null) {}; + baseCollectionPage = new BaseCollectionPage<>(list, mRequestBuilder) {}; } @Test diff --git a/src/test/java/com/microsoft/graph/http/BaseCollectionRequestTests.java b/src/test/java/com/microsoft/graph/http/BaseCollectionRequestTests.java index 3b630a7dc..7f01e21b4 100644 --- a/src/test/java/com/microsoft/graph/http/BaseCollectionRequestTests.java +++ b/src/test/java/com/microsoft/graph/http/BaseCollectionRequestTests.java @@ -36,7 +36,7 @@ */ public class BaseCollectionRequestTests { - private IBaseClient mBaseClient; + private IBaseClient mBaseClient; @SuppressWarnings("unchecked") private Class> jsonObjectCollectionResponseMockClass = (Class>)mock(ICollectionResponse.class).getClass(); @SuppressWarnings("unchecked") @@ -56,6 +56,7 @@ public class BaseCollectionRequestTests { private BaseEntityCollectionRequest, BaseCollectionPage>> mRequest; @BeforeEach + @SuppressWarnings("unchecked") public void setUp() throws Exception { mBaseClient = mock(IBaseClient.class); final Response response = new Response.Builder() @@ -71,7 +72,6 @@ public void setUp() throws Exception { final OkHttpClient mockClient = BaseStreamRequestTests.getMockClient(response); final JsonObject resultobj = new JsonObject(); resultobj.add("id", new JsonPrimitive("zzz")); - @SuppressWarnings("unchecked") final ICollectionResponse result = mock(ICollectionResponse.class); when(result.values()).thenReturn(new ArrayList<>(Arrays.asList(resultobj))); final ISerializer mSerializer = mock(ISerializer.class); @@ -81,7 +81,7 @@ public void setUp() throws Exception { mock(ILogger.class), mockClient); when(mBaseClient.getHttpProvider()).thenReturn(mProvider); - mRequest = new BaseEntityCollectionRequest, BaseCollectionPage>>("https://a.b.c/", mBaseClient, null, jsonObjectCollectionResponseMockClass, jsonObjectCollectionPageMockClass, jsonObjectCollectionRequestBuilderMockClass){}; + mRequest = new BaseEntityCollectionRequest<>("https://a.b.c/", mBaseClient, null, jsonObjectCollectionResponseMockClass, jsonObjectCollectionPageMockClass, jsonObjectCollectionRequestBuilderMockClass){}; } @Test @@ -118,7 +118,7 @@ public void testPost() { public void testFunctionParameters() { final Option f1 = new FunctionOption("1", "one"); final Option f2 = new FunctionOption("2", null); - final BaseCollectionRequest, BaseCollectionPage>> request = new BaseCollectionRequest, BaseCollectionPage>>("https://a.b.c/", mock(IBaseClient.class), Arrays.asList(f1, f2), stringCollectionResponseMockClass, stringCollectionPageMockClass, stringCollectionRequestBuilderMockClass){}; + final BaseCollectionRequest, BaseCollectionPage>> request = new BaseCollectionRequest<>("https://a.b.c/", mock(IBaseClient.class), Arrays.asList(f1, f2), stringCollectionResponseMockClass, stringCollectionPageMockClass, stringCollectionRequestBuilderMockClass){}; assertEquals("https://a.b.c/(1='one',2=null)", request.getRequestUrl().toString()); request.addFunctionOption(new FunctionOption("3","two"));; assertEquals("https://a.b.c/(1='one',2=null,3='two')", request.getRequestUrl().toString()); @@ -129,7 +129,7 @@ public void testFunctionParameters() { public void testQueryParameters() { final Option q1 = new QueryOption("q1","option1 "); final Option q2 = new QueryOption("q2","option2"); - final BaseCollectionRequest, BaseCollectionPage>> request = new BaseCollectionRequest, BaseCollectionPage>>("https://a.b.c/", mock(IBaseClient.class), Arrays.asList(q1, q2), stringCollectionResponseMockClass, stringCollectionPageMockClass, stringCollectionRequestBuilderMockClass){}; + final BaseCollectionRequest, BaseCollectionPage>> request = new BaseCollectionRequest<>("https://a.b.c/", mock(IBaseClient.class), Arrays.asList(q1, q2), stringCollectionResponseMockClass, stringCollectionPageMockClass, stringCollectionRequestBuilderMockClass){}; assertEquals("https://a.b.c/?q1=option1%20&q2=option2", request.getRequestUrl().toString()); request.addQueryOption(new QueryOption("q3","option3")); assertEquals("https://a.b.c/?q1=option1%20&q2=option2&q3=option3", request.getRequestUrl().toString()); @@ -142,7 +142,7 @@ public void testFunctionAndQueryParameters() { final Option f2 = new FunctionOption("f2", null); final Option q1 = new QueryOption("q1","option1 "); final Option q2 = new QueryOption("q2","option2"); - final BaseCollectionRequest, BaseCollectionPage>> request = new BaseCollectionRequest, BaseCollectionPage>>("https://a.b.c/", mock(IBaseClient.class), Arrays.asList(f1, f2, q1, q2), stringCollectionResponseMockClass, stringCollectionPageMockClass, stringCollectionRequestBuilderMockClass){}; + final BaseCollectionRequest, BaseCollectionPage>> request = new BaseCollectionRequest<>("https://a.b.c/", mock(IBaseClient.class), Arrays.asList(f1, f2, q1, q2), stringCollectionResponseMockClass, stringCollectionPageMockClass, stringCollectionRequestBuilderMockClass){}; assertEquals("https://a.b.c/(f1='fun1',f2=null)?q1=option1%20&q2=option2", request.getRequestUrl().toString()); assertEquals(4, request.getOptions().size()); } @@ -164,7 +164,7 @@ public void testPostMethod() { public void testHeader() { final String expectedHeader = "header key"; final String expectedValue = "header value"; - final BaseCollectionRequest, BaseCollectionPage>> request = new BaseCollectionRequest, BaseCollectionPage>>("https://a.b.c/", mock(IBaseClient.class), null, stringCollectionResponseMockClass, stringCollectionPageMockClass, stringCollectionRequestBuilderMockClass){}; + final BaseCollectionRequest, BaseCollectionPage>> request = new BaseCollectionRequest<>("https://a.b.c/", mock(IBaseClient.class), null, stringCollectionResponseMockClass, stringCollectionPageMockClass, stringCollectionRequestBuilderMockClass){}; assertEquals(0, request.getHeaders().size()); request.addHeader(expectedHeader,expectedValue); assertEquals(1,request.getHeaders().size()); diff --git a/src/test/java/com/microsoft/graph/http/BaseRequestBuilderTests.java b/src/test/java/com/microsoft/graph/http/BaseRequestBuilderTests.java index 56e00b081..ea1ff68bf 100644 --- a/src/test/java/com/microsoft/graph/http/BaseRequestBuilderTests.java +++ b/src/test/java/com/microsoft/graph/http/BaseRequestBuilderTests.java @@ -6,6 +6,8 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import okhttp3.Request; + /** * Test cases for {@see BaseRequestBuilder} */ @@ -16,7 +18,7 @@ public class BaseRequestBuilderTests { @BeforeEach public void setUp() throws Exception { - baseRequestBuilder = new BaseRequestBuilder(expectedRequestUrl,null,null){}; + baseRequestBuilder = new BaseRequestBuilder<>(expectedRequestUrl,null,null){}; } @Test diff --git a/src/test/java/com/microsoft/graph/http/BaseRequestTests.java b/src/test/java/com/microsoft/graph/http/BaseRequestTests.java index 535986be7..8cf23da47 100644 --- a/src/test/java/com/microsoft/graph/http/BaseRequestTests.java +++ b/src/test/java/com/microsoft/graph/http/BaseRequestTests.java @@ -7,17 +7,13 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import java.util.Arrays; -import java.util.HashMap; -import java.util.Map; import java.util.concurrent.ExecutionException; -import java.util.concurrent.atomic.AtomicBoolean; import static org.mockito.Mockito.mock; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import okhttp3.Call; import okhttp3.MediaType; import okhttp3.OkHttpClient; import okhttp3.Protocol; @@ -27,7 +23,6 @@ import com.google.gson.JsonObject; import com.google.gson.JsonPrimitive; -import com.microsoft.graph.core.ClientException; import com.microsoft.graph.core.IBaseClient; import com.microsoft.graph.options.FunctionOption; import com.microsoft.graph.options.Option; @@ -38,9 +33,8 @@ * Test cases for {@see BaseRequest} */ public class BaseRequestTests { - private IBaseClient mBaseClient; + private IBaseClient mBaseClient; private BaseRequest mRequest; - private JsonObject callbackJsonObject; @BeforeEach public void setUp() throws Exception { diff --git a/src/test/java/com/microsoft/graph/http/BaseStreamRequestTests.java b/src/test/java/com/microsoft/graph/http/BaseStreamRequestTests.java index 68c0a2329..426b8763c 100644 --- a/src/test/java/com/microsoft/graph/http/BaseStreamRequestTests.java +++ b/src/test/java/com/microsoft/graph/http/BaseStreamRequestTests.java @@ -59,7 +59,7 @@ public void testSend() throws IOException { mock(ILogger.class), mockClient); when(mBaseClient.getHttpProvider()).thenReturn(mProvider); - final BaseStreamRequest request = new BaseStreamRequest("https://a.b.c/", mBaseClient,null, null){}; + final BaseStreamRequest request = new BaseStreamRequest<>("https://a.b.c/", mBaseClient,null, null){}; request.send(); } @@ -80,7 +80,7 @@ public void testSendWithCallback() throws IOException, InterruptedException, Exe mock(ILogger.class), mockClient); when(mBaseClient.getHttpProvider()).thenReturn(mProvider); - final BaseStreamRequest request = new BaseStreamRequest("https://a.b.c/", mBaseClient,null, InputStream.class){}; + final BaseStreamRequest request = new BaseStreamRequest<>("https://a.b.c/", mBaseClient,null, InputStream.class){}; final java.util.concurrent.CompletableFuture result = request.sendAsync(); assertNotNull(result.get()); assertTrue(result.isDone()); @@ -104,7 +104,7 @@ public void testSendWithContentAndCallback() throws IOException, InterruptedExce mock(ILogger.class), mockClient); when(mBaseClient.getHttpProvider()).thenReturn(mProvider); - final BaseStreamRequest request = new BaseStreamRequest("https://a.b.c/", mBaseClient,null, InputStream.class){}; + final BaseStreamRequest request = new BaseStreamRequest<>("https://a.b.c/", mBaseClient,null, InputStream.class){}; final java.util.concurrent.CompletableFuture result = request.sendAsync(new byte[]{1, 2, 3, 4}); assertNotNull(result.get()); assertTrue(result.isDone()); @@ -129,13 +129,13 @@ public void testSendWithContent() throws IOException { mock(ILogger.class), mockClient); when(mBaseClient.getHttpProvider()).thenReturn(mProvider); - final BaseStreamRequest request = new BaseStreamRequest("https://a.b.c/", mBaseClient,null, InputStream.class){}; + final BaseStreamRequest request = new BaseStreamRequest<>("https://a.b.c/", mBaseClient,null, InputStream.class){}; request.send(new byte[]{1, 2, 3, 4}); } @Test public void testBaseMethod() { - final BaseStreamRequest request = new BaseStreamRequest("https://a.b.c/", mBaseClient,null, InputStream.class){}; + final BaseStreamRequest request = new BaseStreamRequest<>("https://a.b.c/", mBaseClient,null, InputStream.class){}; assertEquals("https://a.b.c/", request.getRequestUrl().toString()); request.addHeader("header key", "header value"); assertEquals(1,request.getHeaders().size()); diff --git a/src/test/java/com/microsoft/graph/http/DeltaCollectionPageTests.java b/src/test/java/com/microsoft/graph/http/DeltaCollectionPageTests.java index e32829b47..555b575d8 100644 --- a/src/test/java/com/microsoft/graph/http/DeltaCollectionPageTests.java +++ b/src/test/java/com/microsoft/graph/http/DeltaCollectionPageTests.java @@ -7,6 +7,8 @@ import org.junit.jupiter.api.Test; +import okhttp3.Request; + public class DeltaCollectionPageTests { @SuppressWarnings("unchecked") @Test