From 0c608ee9da69afb22a57e8e7f7689830a9f5acdd Mon Sep 17 00:00:00 2001 From: ramsessanchez <63934382+ramsessanchez@users.noreply.github.com> Date: Fri, 16 Feb 2024 15:40:40 -0800 Subject: [PATCH 01/13] Fix File Upload by setting ContentLength property File uploading was failing due to contentLength property not being set on RequestBody object, add method to override. Make the value available as part of RequestInformation object. --- CHANGELOG.md | 6 +++++ .../microsoft/kiota/RequestInformation.java | 12 ++++++++-- .../kiota/http/OkHttpRequestAdapter.java | 24 +++++++++++++------ .../options/UserAgentHandlerOption.java | 2 +- gradle.properties | 2 +- 5 files changed, 35 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f8c529e4c..b71ad24b2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed +## [1.0.3] - 2023-02-19 + +### Changed + +- Added contentLength property to RequestInformation to facilitate in setting the content length of the Okhttp3 RequestBody object within the OkhttpRequestAdapter. + ## [1.0.2] - 2024-02-13 ### Changed diff --git a/components/abstractions/src/main/java/com/microsoft/kiota/RequestInformation.java b/components/abstractions/src/main/java/com/microsoft/kiota/RequestInformation.java index a131389b9..311d04e62 100644 --- a/components/abstractions/src/main/java/com/microsoft/kiota/RequestInformation.java +++ b/components/abstractions/src/main/java/com/microsoft/kiota/RequestInformation.java @@ -219,6 +219,9 @@ public void removeQueryParameter(@Nonnull final String name) { /** The Request Body. */ @Nullable public InputStream content; + /** The Request Body length. */ + @Nullable public Long contentLength; + @Nonnull private final HashMap requestOptions = new HashMap<>(); /** @@ -268,10 +271,11 @@ public void setResponseHandler(@Nonnull ResponseHandler responseHandler) { /** * Sets the request body to be a binary stream. * @param value the binary stream + * @throws IOException when the stream cannot be read. * @deprecated use {@link #setStreamContent(InputStream, String)} instead. */ @Deprecated - public void setStreamContent(@Nonnull final InputStream value) { + public void setStreamContent(@Nonnull final InputStream value) throws IOException { setStreamContent(value, BINARY_CONTENT_TYPE); } @@ -279,15 +283,19 @@ public void setStreamContent(@Nonnull final InputStream value) { * Sets the request body to be a binary stream. * @param value the binary stream * @param contentType the content type of the stream. + * @throws IOException when the stream cannot be read. */ public void setStreamContent( - @Nonnull final InputStream value, @Nonnull final String contentType) { + @Nonnull final InputStream value, @Nonnull final String contentType) + throws IOException { Objects.requireNonNull(value); Objects.requireNonNull(contentType); if (contentType.isEmpty()) { throw new IllegalArgumentException("contentType cannot be empty"); } this.content = value; + this.contentLength = (long) value.available(); + headers.tryAdd(CONTENT_TYPE_HEADER, contentType); } diff --git a/components/http/okHttp/src/main/java/com/microsoft/kiota/http/OkHttpRequestAdapter.java b/components/http/okHttp/src/main/java/com/microsoft/kiota/http/OkHttpRequestAdapter.java index 8b8069297..2c10baabe 100644 --- a/components/http/okHttp/src/main/java/com/microsoft/kiota/http/OkHttpRequestAdapter.java +++ b/components/http/okHttp/src/main/java/com/microsoft/kiota/http/OkHttpRequestAdapter.java @@ -188,7 +188,7 @@ public void enableBackingStore(@Nullable final BackingStoreFactory backingStoreF Objects.requireNonNull(requestInfo, nullRequestInfoParameter); Objects.requireNonNull(factory, nullFactoryParameter); - final Span span = startSpan(requestInfo, "sendCollectionAsync"); + final Span span = startSpan(requestInfo, "sendCollection"); try (final Scope scope = span.makeCurrent()) { Response response = this.getHttpResponseMessage(requestInfo, span, span, null); final ResponseHandler responseHandler = getResponseHandler(requestInfo); @@ -269,7 +269,7 @@ private Span startSpan( Objects.requireNonNull(requestInfo, nullRequestInfoParameter); Objects.requireNonNull(factory, nullFactoryParameter); - final Span span = startSpan(requestInfo, "sendAsync"); + final Span span = startSpan(requestInfo, "send"); try (final Scope scope = span.makeCurrent()) { Response response = this.getHttpResponseMessage(requestInfo, span, span, null); final ResponseHandler responseHandler = getResponseHandler(requestInfo); @@ -331,7 +331,7 @@ private void closeResponse(boolean closeResponse, Response response) { @Nonnull final Class targetClass) { Objects.requireNonNull(requestInfo, nullRequestInfoParameter); Objects.requireNonNull(targetClass, "parameter targetClass cannot be null"); - final Span span = startSpan(requestInfo, "sendPrimitiveAsync"); + final Span span = startSpan(requestInfo, "sendPrimitive"); try (final Scope scope = span.makeCurrent()) { Response response = this.getHttpResponseMessage(requestInfo, span, span, null); final ResponseHandler responseHandler = getResponseHandler(requestInfo); @@ -425,7 +425,7 @@ private void closeResponse(boolean closeResponse, Response response) { @Nonnull final ValuedEnumParser enumParser) { Objects.requireNonNull(requestInfo, nullRequestInfoParameter); Objects.requireNonNull(enumParser, nullEnumParserParameter); - final Span span = startSpan(requestInfo, "sendEnumAsync"); + final Span span = startSpan(requestInfo, "sendEnum"); try (final Scope scope = span.makeCurrent()) { Response response = this.getHttpResponseMessage(requestInfo, span, span, null); final ResponseHandler responseHandler = getResponseHandler(requestInfo); @@ -471,7 +471,7 @@ private void closeResponse(boolean closeResponse, Response response) { @Nonnull final ValuedEnumParser enumParser) { Objects.requireNonNull(requestInfo, nullRequestInfoParameter); Objects.requireNonNull(enumParser, nullEnumParserParameter); - final Span span = startSpan(requestInfo, "sendEnumCollectionAsync"); + final Span span = startSpan(requestInfo, "sendEnumCollection"); try (final Scope scope = span.makeCurrent()) { Response response = this.getHttpResponseMessage(requestInfo, span, span, null); final ResponseHandler responseHandler = getResponseHandler(requestInfo); @@ -518,7 +518,7 @@ private void closeResponse(boolean closeResponse, Response response) { @Nonnull final Class targetClass) { Objects.requireNonNull(requestInfo, nullRequestInfoParameter); - final Span span = startSpan(requestInfo, "sendPrimitiveCollectionAsync"); + final Span span = startSpan(requestInfo, "sendPrimitiveCollection"); try (final Scope scope = span.makeCurrent()) { Response response = getHttpResponseMessage(requestInfo, span, span, null); final ResponseHandler responseHandler = getResponseHandler(requestInfo); @@ -835,7 +835,7 @@ private void setBaseUrlForRequestInformation(@Nonnull final RequestInformation r @SuppressWarnings("unchecked") @Nonnull public T convertToNativeRequest(@Nonnull final RequestInformation requestInfo) { Objects.requireNonNull(requestInfo, nullRequestInfoParameter); - final Span span = startSpan(requestInfo, "convertToNativeRequestAsync"); + final Span span = startSpan(requestInfo, "convertToNativeRequest"); try (final Scope scope = span.makeCurrent()) { this.authProvider.authenticateRequest(requestInfo, null); return (T) getRequestFromRequestInformation(requestInfo, span, span); @@ -882,6 +882,16 @@ private void setBaseUrlForRequestInformation(@Nonnull final RequestInformation r requestInfo.content == null ? null : new RequestBody() { + @Override + public long contentLength() { + if (requestInfo.contentLength != null) { + spanForAttributes.setAttribute( + "http.request_content_length", + requestInfo.contentLength); + return requestInfo.contentLength; + } else return 0; + } + @Override public MediaType contentType() { final Set contentTypes = diff --git a/components/http/okHttp/src/main/java/com/microsoft/kiota/http/middleware/options/UserAgentHandlerOption.java b/components/http/okHttp/src/main/java/com/microsoft/kiota/http/middleware/options/UserAgentHandlerOption.java index 8fbc162af..82df508a2 100644 --- a/components/http/okHttp/src/main/java/com/microsoft/kiota/http/middleware/options/UserAgentHandlerOption.java +++ b/components/http/okHttp/src/main/java/com/microsoft/kiota/http/middleware/options/UserAgentHandlerOption.java @@ -13,7 +13,7 @@ public UserAgentHandlerOption() {} private boolean enabled = true; @Nonnull private String productName = "kiota-java"; - @Nonnull private String productVersion = "1.0.0"; + @Nonnull private String productVersion = "1.0.3"; /** * Gets the product name to be used in the user agent header diff --git a/gradle.properties b/gradle.properties index 405e9078b..2ca01d7eb 100644 --- a/gradle.properties +++ b/gradle.properties @@ -26,7 +26,7 @@ org.gradle.caching=true mavenGroupId = com.microsoft.kiota mavenMajorVersion = 1 mavenMinorVersion = 0 -mavenPatchVersion = 2 +mavenPatchVersion = 3 mavenArtifactSuffix = #These values are used to run functional tests From 13ae40465225894fd7b693fe96ceaaf2653959af Mon Sep 17 00:00:00 2001 From: ramsessanchez <63934382+ramsessanchez@users.noreply.github.com> Date: Wed, 21 Feb 2024 15:49:19 -0800 Subject: [PATCH 02/13] Refactor to utilize okhttp class RequestBody.create() rather than implementing our own. --- .../microsoft/kiota/RequestInformation.java | 12 +--- .../kiota/http/OkHttpRequestAdapter.java | 55 +++++++------------ 2 files changed, 21 insertions(+), 46 deletions(-) diff --git a/components/abstractions/src/main/java/com/microsoft/kiota/RequestInformation.java b/components/abstractions/src/main/java/com/microsoft/kiota/RequestInformation.java index 311d04e62..a131389b9 100644 --- a/components/abstractions/src/main/java/com/microsoft/kiota/RequestInformation.java +++ b/components/abstractions/src/main/java/com/microsoft/kiota/RequestInformation.java @@ -219,9 +219,6 @@ public void removeQueryParameter(@Nonnull final String name) { /** The Request Body. */ @Nullable public InputStream content; - /** The Request Body length. */ - @Nullable public Long contentLength; - @Nonnull private final HashMap requestOptions = new HashMap<>(); /** @@ -271,11 +268,10 @@ public void setResponseHandler(@Nonnull ResponseHandler responseHandler) { /** * Sets the request body to be a binary stream. * @param value the binary stream - * @throws IOException when the stream cannot be read. * @deprecated use {@link #setStreamContent(InputStream, String)} instead. */ @Deprecated - public void setStreamContent(@Nonnull final InputStream value) throws IOException { + public void setStreamContent(@Nonnull final InputStream value) { setStreamContent(value, BINARY_CONTENT_TYPE); } @@ -283,19 +279,15 @@ public void setStreamContent(@Nonnull final InputStream value) throws IOExceptio * Sets the request body to be a binary stream. * @param value the binary stream * @param contentType the content type of the stream. - * @throws IOException when the stream cannot be read. */ public void setStreamContent( - @Nonnull final InputStream value, @Nonnull final String contentType) - throws IOException { + @Nonnull final InputStream value, @Nonnull final String contentType) { Objects.requireNonNull(value); Objects.requireNonNull(contentType); if (contentType.isEmpty()) { throw new IllegalArgumentException("contentType cannot be empty"); } this.content = value; - this.contentLength = (long) value.available(); - headers.tryAdd(CONTENT_TYPE_HEADER, contentType); } diff --git a/components/http/okHttp/src/main/java/com/microsoft/kiota/http/OkHttpRequestAdapter.java b/components/http/okHttp/src/main/java/com/microsoft/kiota/http/OkHttpRequestAdapter.java index 2c10baabe..0600eef01 100644 --- a/components/http/okHttp/src/main/java/com/microsoft/kiota/http/OkHttpRequestAdapter.java +++ b/components/http/okHttp/src/main/java/com/microsoft/kiota/http/OkHttpRequestAdapter.java @@ -878,42 +878,23 @@ private void setBaseUrlForRequestInformation(@Nonnull final RequestInformation r spanForAttributes.setAttribute(SemanticAttributes.SERVER_ADDRESS, requestURL.getHost()); spanForAttributes.setAttribute(SemanticAttributes.URL_SCHEME, requestURL.getProtocol()); - RequestBody body = - requestInfo.content == null - ? null - : new RequestBody() { - @Override - public long contentLength() { - if (requestInfo.contentLength != null) { - spanForAttributes.setAttribute( - "http.request_content_length", - requestInfo.contentLength); - return requestInfo.contentLength; - } else return 0; - } - - @Override - public MediaType contentType() { - final Set contentTypes = - requestInfo.headers.containsKey(contentTypeHeaderKey) - ? requestInfo.headers.get(contentTypeHeaderKey) - : new HashSet<>(); - if (contentTypes.isEmpty()) { - return null; - } else { - final String contentType = - contentTypes.toArray(new String[] {})[0]; - spanForAttributes.setAttribute( - "http.request_content_type", contentType); - return MediaType.parse(contentType); - } - } - - @Override - public void writeTo(@Nonnull BufferedSink sink) throws IOException { - sink.writeAll(Okio.source(requestInfo.content)); - } - }; + + RequestBody body = null; + if (requestInfo.content != null) { + final Set contentTypes = + requestInfo.headers.containsKey(contentTypeHeaderKey) + ? requestInfo.headers.get(contentTypeHeaderKey) + : new HashSet<>(); + final String contentType = + contentTypes.toArray(new String[] {})[0]; + spanForAttributes.setAttribute("http.request_content_type", contentType); + final MediaType mediaType = contentTypes.isEmpty() ? null : MediaType.parse(contentType); + byte[] bytes = Compatibility.readAllBytes(requestInfo.content); + spanForAttributes.setAttribute( + "http.request_content_length", + bytes.length); + body = RequestBody.create(bytes, mediaType); + } // https://stackoverflow.com/a/35743536 if (body == null @@ -954,6 +935,8 @@ public void writeTo(@Nonnull BufferedSink sink) throws IOException { } } return request; + } catch (IOException e) { + throw new RuntimeException(e); } finally { span.end(); } From 72af825c98c34365bb518bf96b4e0759eda28689 Mon Sep 17 00:00:00 2001 From: ramsessanchez <63934382+ramsessanchez@users.noreply.github.com> Date: Wed, 21 Feb 2024 15:51:33 -0800 Subject: [PATCH 03/13] spotless apply --- .../microsoft/kiota/http/OkHttpRequestAdapter.java | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/components/http/okHttp/src/main/java/com/microsoft/kiota/http/OkHttpRequestAdapter.java b/components/http/okHttp/src/main/java/com/microsoft/kiota/http/OkHttpRequestAdapter.java index 0600eef01..399f6bee6 100644 --- a/components/http/okHttp/src/main/java/com/microsoft/kiota/http/OkHttpRequestAdapter.java +++ b/components/http/okHttp/src/main/java/com/microsoft/kiota/http/OkHttpRequestAdapter.java @@ -26,9 +26,6 @@ import okhttp3.*; -import okio.BufferedSink; -import okio.Okio; - import java.io.IOException; import java.io.InputStream; import java.math.BigDecimal; @@ -878,21 +875,18 @@ private void setBaseUrlForRequestInformation(@Nonnull final RequestInformation r spanForAttributes.setAttribute(SemanticAttributes.SERVER_ADDRESS, requestURL.getHost()); spanForAttributes.setAttribute(SemanticAttributes.URL_SCHEME, requestURL.getProtocol()); - RequestBody body = null; if (requestInfo.content != null) { final Set contentTypes = requestInfo.headers.containsKey(contentTypeHeaderKey) ? requestInfo.headers.get(contentTypeHeaderKey) : new HashSet<>(); - final String contentType = - contentTypes.toArray(new String[] {})[0]; + final String contentType = contentTypes.toArray(new String[] {})[0]; spanForAttributes.setAttribute("http.request_content_type", contentType); - final MediaType mediaType = contentTypes.isEmpty() ? null : MediaType.parse(contentType); + final MediaType mediaType = + contentTypes.isEmpty() ? null : MediaType.parse(contentType); byte[] bytes = Compatibility.readAllBytes(requestInfo.content); - spanForAttributes.setAttribute( - "http.request_content_length", - bytes.length); + spanForAttributes.setAttribute("http.request_content_length", bytes.length); body = RequestBody.create(bytes, mediaType); } From dd0591248230bd7f226034bf89d2c802b951934e Mon Sep 17 00:00:00 2001 From: ramsessanchez <63934382+ramsessanchez@users.noreply.github.com> Date: Wed, 21 Feb 2024 15:52:53 -0800 Subject: [PATCH 04/13] agent handler version --- .../kiota/http/middleware/options/UserAgentHandlerOption.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/http/okHttp/src/main/java/com/microsoft/kiota/http/middleware/options/UserAgentHandlerOption.java b/components/http/okHttp/src/main/java/com/microsoft/kiota/http/middleware/options/UserAgentHandlerOption.java index 82df508a2..a8bd13b40 100644 --- a/components/http/okHttp/src/main/java/com/microsoft/kiota/http/middleware/options/UserAgentHandlerOption.java +++ b/components/http/okHttp/src/main/java/com/microsoft/kiota/http/middleware/options/UserAgentHandlerOption.java @@ -13,7 +13,7 @@ public UserAgentHandlerOption() {} private boolean enabled = true; @Nonnull private String productName = "kiota-java"; - @Nonnull private String productVersion = "1.0.3"; + @Nonnull private String productVersion = "1.0.4"; /** * Gets the product name to be used in the user agent header From c8c3b668e1f793c484ce8be13808b4871655ecf9 Mon Sep 17 00:00:00 2001 From: ramsessanchez <63934382+ramsessanchez@users.noreply.github.com> Date: Wed, 21 Feb 2024 16:04:21 -0800 Subject: [PATCH 05/13] refactor logic --- .../microsoft/kiota/http/OkHttpRequestAdapter.java | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/components/http/okHttp/src/main/java/com/microsoft/kiota/http/OkHttpRequestAdapter.java b/components/http/okHttp/src/main/java/com/microsoft/kiota/http/OkHttpRequestAdapter.java index 399f6bee6..14b88ea53 100644 --- a/components/http/okHttp/src/main/java/com/microsoft/kiota/http/OkHttpRequestAdapter.java +++ b/components/http/okHttp/src/main/java/com/microsoft/kiota/http/OkHttpRequestAdapter.java @@ -881,10 +881,14 @@ private void setBaseUrlForRequestInformation(@Nonnull final RequestInformation r requestInfo.headers.containsKey(contentTypeHeaderKey) ? requestInfo.headers.get(contentTypeHeaderKey) : new HashSet<>(); - final String contentType = contentTypes.toArray(new String[] {})[0]; - spanForAttributes.setAttribute("http.request_content_type", contentType); - final MediaType mediaType = - contentTypes.isEmpty() ? null : MediaType.parse(contentType); + final MediaType mediaType; + if (!contentTypes.isEmpty()) { + String contentType = contentTypes.toArray(new String[] {})[0]; + spanForAttributes.setAttribute("http.request_content_type", contentType); + mediaType = MediaType.parse(contentType); + } else { + mediaType = null; + } byte[] bytes = Compatibility.readAllBytes(requestInfo.content); spanForAttributes.setAttribute("http.request_content_length", bytes.length); body = RequestBody.create(bytes, mediaType); From b7110494fe279e9d9c376f7b5b4fdf0724b398fa Mon Sep 17 00:00:00 2001 From: ramsessanchez <63934382+ramsessanchez@users.noreply.github.com> Date: Thu, 22 Feb 2024 14:33:00 -0800 Subject: [PATCH 06/13] Refactor contentLength() method --- .../kiota/http/OkHttpRequestAdapter.java | 81 ++++++++++++------- 1 file changed, 50 insertions(+), 31 deletions(-) diff --git a/components/http/okHttp/src/main/java/com/microsoft/kiota/http/OkHttpRequestAdapter.java b/components/http/okHttp/src/main/java/com/microsoft/kiota/http/OkHttpRequestAdapter.java index 14b88ea53..4cd3329e7 100644 --- a/components/http/okHttp/src/main/java/com/microsoft/kiota/http/OkHttpRequestAdapter.java +++ b/components/http/okHttp/src/main/java/com/microsoft/kiota/http/OkHttpRequestAdapter.java @@ -25,7 +25,10 @@ import jakarta.annotation.Nullable; import okhttp3.*; +import okio.BufferedSink; +import okio.Okio; +import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.math.BigDecimal; @@ -50,6 +53,7 @@ /** RequestAdapter implementation for OkHttp */ public class OkHttpRequestAdapter implements com.microsoft.kiota.RequestAdapter { private static final String contentTypeHeaderKey = "Content-Type"; + private static final String contentLengthHeaderKey = "Content-Length"; @Nonnull private final Call.Factory client; @Nonnull private final AuthenticationProvider authProvider; @Nonnull private final ObservabilityOptions obsOptions; @@ -875,24 +879,51 @@ private void setBaseUrlForRequestInformation(@Nonnull final RequestInformation r spanForAttributes.setAttribute(SemanticAttributes.SERVER_ADDRESS, requestURL.getHost()); spanForAttributes.setAttribute(SemanticAttributes.URL_SCHEME, requestURL.getProtocol()); - RequestBody body = null; - if (requestInfo.content != null) { - final Set contentTypes = - requestInfo.headers.containsKey(contentTypeHeaderKey) - ? requestInfo.headers.get(contentTypeHeaderKey) - : new HashSet<>(); - final MediaType mediaType; - if (!contentTypes.isEmpty()) { - String contentType = contentTypes.toArray(new String[] {})[0]; - spanForAttributes.setAttribute("http.request_content_type", contentType); - mediaType = MediaType.parse(contentType); - } else { - mediaType = null; - } - byte[] bytes = Compatibility.readAllBytes(requestInfo.content); - spanForAttributes.setAttribute("http.request_content_length", bytes.length); - body = RequestBody.create(bytes, mediaType); - } + RequestBody body = + requestInfo.content == null + ? null + : new RequestBody() { + @Override + public MediaType contentType() { + final Set contentTypes = + requestInfo.headers.getOrDefault(contentTypeHeaderKey, new HashSet<>()); + if (contentTypes.isEmpty()) { + return null; + } else { + final String contentType = + contentTypes.toArray(new String[] {})[0]; + spanForAttributes.setAttribute( + "http.request_content_type", contentType); + return MediaType.parse(contentType); + } + } + + @Override + public long contentLength() { + long length; + final Set contentLength = requestInfo.headers.getOrDefault(contentLengthHeaderKey, new HashSet<>()); + if (contentLength.isEmpty()) { + try(final ByteArrayInputStream contentStream = (ByteArrayInputStream) requestInfo.content) { + length = contentStream.available(); + } catch (IOException ex) { + length = -1L; + } + } + else { + length = Long.parseLong(contentLength.toArray(new String[]{})[0]); + } + if(length != -1L) { + spanForAttributes.setAttribute( + SemanticAttributes.HTTP_REQUEST_BODY_SIZE, length); + } + return length; + } + + @Override + public void writeTo(@Nonnull BufferedSink sink) throws IOException { + sink.writeAll(Okio.source(requestInfo.content)); + } + }; // https://stackoverflow.com/a/35743536 if (body == null @@ -922,19 +953,7 @@ private void setBaseUrlForRequestInformation(@Nonnull final RequestInformation r requestBuilder.tag(obsOptions.getType(), obsOptions); } requestBuilder.tag(Span.class, parentSpan); - final Request request = requestBuilder.build(); - final List contentLengthHeader = request.headers().values("Content-Length"); - if (contentLengthHeader != null && !contentLengthHeader.isEmpty()) { - final String firstEntryValue = contentLengthHeader.get(0); - if (firstEntryValue != null && !firstEntryValue.isEmpty()) { - spanForAttributes.setAttribute( - SemanticAttributes.HTTP_REQUEST_BODY_SIZE, - Long.parseLong(firstEntryValue)); - } - } - return request; - } catch (IOException e) { - throw new RuntimeException(e); + return requestBuilder.build(); } finally { span.end(); } From d5a22ed3ed8f2b44f72cff758b9e91322738f1d9 Mon Sep 17 00:00:00 2001 From: ramsessanchez <63934382+ramsessanchez@users.noreply.github.com> Date: Thu, 22 Feb 2024 14:41:16 -0800 Subject: [PATCH 07/13] spotless apply --- .../kiota/http/OkHttpRequestAdapter.java | 82 ++++++++++--------- 1 file changed, 44 insertions(+), 38 deletions(-) diff --git a/components/http/okHttp/src/main/java/com/microsoft/kiota/http/OkHttpRequestAdapter.java b/components/http/okHttp/src/main/java/com/microsoft/kiota/http/OkHttpRequestAdapter.java index 4cd3329e7..150cb5b00 100644 --- a/components/http/okHttp/src/main/java/com/microsoft/kiota/http/OkHttpRequestAdapter.java +++ b/components/http/okHttp/src/main/java/com/microsoft/kiota/http/OkHttpRequestAdapter.java @@ -25,6 +25,7 @@ import jakarta.annotation.Nullable; import okhttp3.*; + import okio.BufferedSink; import okio.Okio; @@ -883,47 +884,52 @@ private void setBaseUrlForRequestInformation(@Nonnull final RequestInformation r requestInfo.content == null ? null : new RequestBody() { - @Override - public MediaType contentType() { - final Set contentTypes = - requestInfo.headers.getOrDefault(contentTypeHeaderKey, new HashSet<>()); - if (contentTypes.isEmpty()) { - return null; - } else { - final String contentType = - contentTypes.toArray(new String[] {})[0]; - spanForAttributes.setAttribute( - "http.request_content_type", contentType); - return MediaType.parse(contentType); - } - } + @Override + public MediaType contentType() { + final Set contentTypes = + requestInfo.headers.getOrDefault( + contentTypeHeaderKey, new HashSet<>()); + if (contentTypes.isEmpty()) { + return null; + } else { + final String contentType = + contentTypes.toArray(new String[] {})[0]; + spanForAttributes.setAttribute( + "http.request_content_type", contentType); + return MediaType.parse(contentType); + } + } - @Override - public long contentLength() { - long length; - final Set contentLength = requestInfo.headers.getOrDefault(contentLengthHeaderKey, new HashSet<>()); - if (contentLength.isEmpty()) { - try(final ByteArrayInputStream contentStream = (ByteArrayInputStream) requestInfo.content) { - length = contentStream.available(); - } catch (IOException ex) { - length = -1L; + @Override + public long contentLength() { + long length; + final Set contentLength = + requestInfo.headers.getOrDefault( + contentLengthHeaderKey, new HashSet<>()); + if (contentLength.isEmpty()) { + try (final ByteArrayInputStream contentStream = + (ByteArrayInputStream) requestInfo.content) { + length = contentStream.available(); + } catch (IOException ex) { + length = -1L; + } + } else { + length = + Long.parseLong( + contentLength.toArray(new String[] {})[0]); + } + if (length != -1L) { + spanForAttributes.setAttribute( + SemanticAttributes.HTTP_REQUEST_BODY_SIZE, length); + } + return length; } - } - else { - length = Long.parseLong(contentLength.toArray(new String[]{})[0]); - } - if(length != -1L) { - spanForAttributes.setAttribute( - SemanticAttributes.HTTP_REQUEST_BODY_SIZE, length); - } - return length; - } - @Override - public void writeTo(@Nonnull BufferedSink sink) throws IOException { - sink.writeAll(Okio.source(requestInfo.content)); - } - }; + @Override + public void writeTo(@Nonnull BufferedSink sink) throws IOException { + sink.writeAll(Okio.source(requestInfo.content)); + } + }; // https://stackoverflow.com/a/35743536 if (body == null From 3894fcfc5d2555d7382b04768a3017b0b58dad1f Mon Sep 17 00:00:00 2001 From: Ramses Sanchez-Hernandez <63934382+ramsessanchez@users.noreply.github.com> Date: Fri, 23 Feb 2024 10:43:47 -0800 Subject: [PATCH 08/13] Update components/http/okHttp/src/main/java/com/microsoft/kiota/http/OkHttpRequestAdapter.java Co-authored-by: Vincent Biret --- .../java/com/microsoft/kiota/http/OkHttpRequestAdapter.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/components/http/okHttp/src/main/java/com/microsoft/kiota/http/OkHttpRequestAdapter.java b/components/http/okHttp/src/main/java/com/microsoft/kiota/http/OkHttpRequestAdapter.java index 150cb5b00..e826b8038 100644 --- a/components/http/okHttp/src/main/java/com/microsoft/kiota/http/OkHttpRequestAdapter.java +++ b/components/http/okHttp/src/main/java/com/microsoft/kiota/http/OkHttpRequestAdapter.java @@ -906,9 +906,9 @@ public long contentLength() { final Set contentLength = requestInfo.headers.getOrDefault( contentLengthHeaderKey, new HashSet<>()); - if (contentLength.isEmpty()) { - try (final ByteArrayInputStream contentStream = - (ByteArrayInputStream) requestInfo.content) { + if (contentLength.isEmpty() && requestInfo.content instanceof ByteArrayInputStream) { + final ByteArrayInputStream contentStream = (ByteArrayInputStream) requestInfo.content; + try { length = contentStream.available(); } catch (IOException ex) { length = -1L; From 7ba31e1fce15461742f9e12326ce1c4f946a9422 Mon Sep 17 00:00:00 2001 From: Vincent Biret Date: Mon, 26 Feb 2024 10:43:51 -0500 Subject: [PATCH 09/13] - bumps patch version --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 012f9d320..a7fa44604 100644 --- a/gradle.properties +++ b/gradle.properties @@ -26,7 +26,7 @@ org.gradle.caching=true mavenGroupId = com.microsoft.kiota mavenMajorVersion = 1 mavenMinorVersion = 0 -mavenPatchVersion = 4 +mavenPatchVersion = 5 mavenArtifactSuffix = #These values are used to run functional tests From b243088050e2a4b92703300722cdcf2ea7b9e229 Mon Sep 17 00:00:00 2001 From: ramsessanchez <63934382+ramsessanchez@users.noreply.github.com> Date: Wed, 28 Feb 2024 10:44:06 -0800 Subject: [PATCH 10/13] json and file payload tests --- .../kiota/http/OkHttpRequestAdapter.java | 15 +++-- .../kiota/http/OkHttpRequestAdapterTest.java | 58 ++++++++++++++++++- .../okHttp/src/test/resources/helloWorld.txt | 25 ++++++++ 3 files changed, 87 insertions(+), 11 deletions(-) create mode 100644 components/http/okHttp/src/test/resources/helloWorld.txt diff --git a/components/http/okHttp/src/main/java/com/microsoft/kiota/http/OkHttpRequestAdapter.java b/components/http/okHttp/src/main/java/com/microsoft/kiota/http/OkHttpRequestAdapter.java index e826b8038..7f931252d 100644 --- a/components/http/okHttp/src/main/java/com/microsoft/kiota/http/OkHttpRequestAdapter.java +++ b/components/http/okHttp/src/main/java/com/microsoft/kiota/http/OkHttpRequestAdapter.java @@ -906,19 +906,18 @@ public long contentLength() { final Set contentLength = requestInfo.headers.getOrDefault( contentLengthHeaderKey, new HashSet<>()); - if (contentLength.isEmpty() && requestInfo.content instanceof ByteArrayInputStream) { - final ByteArrayInputStream contentStream = (ByteArrayInputStream) requestInfo.content; - try { - length = contentStream.available(); - } catch (IOException ex) { - length = -1L; - } + if (contentLength.isEmpty() + && requestInfo.content + instanceof ByteArrayInputStream) { + final ByteArrayInputStream contentStream = + (ByteArrayInputStream) requestInfo.content; + length = contentStream.available(); } else { length = Long.parseLong( contentLength.toArray(new String[] {})[0]); } - if (length != -1L) { + if (length > 0) { spanForAttributes.setAttribute( SemanticAttributes.HTTP_REQUEST_BODY_SIZE, length); } diff --git a/components/http/okHttp/src/test/java/com/microsoft/kiota/http/OkHttpRequestAdapterTest.java b/components/http/okHttp/src/test/java/com/microsoft/kiota/http/OkHttpRequestAdapterTest.java index 227ff07c1..77f66c6d9 100644 --- a/components/http/okHttp/src/test/java/com/microsoft/kiota/http/OkHttpRequestAdapterTest.java +++ b/components/http/okHttp/src/test/java/com/microsoft/kiota/http/OkHttpRequestAdapterTest.java @@ -28,6 +28,7 @@ import okio.Okio; +import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.EnumSource; @@ -35,9 +36,7 @@ import org.junit.jupiter.params.provider.ValueSource; import org.mockito.stubbing.Answer; -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; +import java.io.*; import java.net.URI; import java.nio.charset.StandardCharsets; import java.util.Arrays; @@ -293,6 +292,59 @@ void throwsAPIException( assertTrue(exception.getResponseHeaders().containsKey("request-id")); } + @Test + void getRequestFromRequestInformationHasCorrectContentLength_JsonPayload() throws Exception { + final var authenticationProviderMock = mock(AuthenticationProvider.class); + final var requestInformation = new RequestInformation(); + requestInformation.setUri(new URI("https://localhost")); + ByteArrayInputStream content = + new ByteArrayInputStream( + "{\"name\":\"value\",\"array\":[\"1\",\"2\",\"3\"]}".getBytes()); + requestInformation.setStreamContent(content, "application/octet-stream"); + requestInformation.httpMethod = HttpMethod.PUT; + requestInformation.headers.tryAdd("Content-Length", String.valueOf(content.available())); + + final var adapter = new OkHttpRequestAdapter(authenticationProviderMock); + final var request = + adapter.getRequestFromRequestInformation( + requestInformation, mock(Span.class), mock(Span.class)); + + assertEquals( + String.valueOf(requestInformation.content.available()), + request.headers().get("Content-Length")); + assertEquals("application/octet-stream", request.headers().get("Content-Type")); + assertNotNull(request.body()); + assertEquals(request.body().contentLength(), requestInformation.content.available()); + assertEquals(request.body().contentType(), MediaType.parse("application/octet-stream")); + } + + @Test + void getRequestFromRequestInformationIncludesContentLength_FilePayload() throws Exception { + final var authenticationProviderMock = mock(AuthenticationProvider.class); + final var testFile = new File(".\\src\\test\\resources\\helloWorld.txt"); + System.out.println(testFile.getCanonicalPath()); + final var requestInformation = new RequestInformation(); + + requestInformation.setUri(new URI("https://localhost")); + requestInformation.httpMethod = HttpMethod.PUT; + requestInformation.headers.add("Content-Length", String.valueOf(testFile.length())); + requestInformation.setStreamContent( + new FileInputStream(testFile), "application/octet-stream"); + + final var adapter = new OkHttpRequestAdapter(authenticationProviderMock); + final var request = + adapter.getRequestFromRequestInformation( + requestInformation, mock(Span.class), mock(Span.class)); + + assertEquals( + String.valueOf(requestInformation.content.available()), + request.headers().get("Content-Length")); + assertEquals("application/octet-stream", request.headers().get("Content-Type")); + assertNotNull(request.body()); + assertEquals(request.body().contentLength(), requestInformation.content.available()); + assertEquals(request.body().contentType(), MediaType.parse("application/octet-stream")); + } + public static OkHttpClient getMockClient(final Response response) throws IOException { final OkHttpClient mockClient = mock(OkHttpClient.class); final Call remoteCall = mock(Call.class); diff --git a/components/http/okHttp/src/test/resources/helloWorld.txt b/components/http/okHttp/src/test/resources/helloWorld.txt new file mode 100644 index 000000000..2f92df713 --- /dev/null +++ b/components/http/okHttp/src/test/resources/helloWorld.txt @@ -0,0 +1,25 @@ +HelloWorld! +HelloWorld! +HelloWorld! +HelloWorld! +HelloWorld! +HelloWorld! +HelloWorld! +HelloWorld! +HelloWorld! +HelloWorld! +HelloWorld! +HelloWorld! +HelloWorld! +HelloWorld! +HelloWorld! +HelloWorld! +HelloWorld! +HelloWorld! +HelloWorld! +HelloWorld! +HelloWorld! +HelloWorld! +HelloWorld! +HelloWorld! +HelloWorld! \ No newline at end of file From 6c621fae79d17d3c6e03a84df903bc7bcd0880c7 Mon Sep 17 00:00:00 2001 From: ramsessanchez <63934382+ramsessanchez@users.noreply.github.com> Date: Wed, 28 Feb 2024 10:47:36 -0800 Subject: [PATCH 11/13] v1.0.5 --- CHANGELOG.md | 2 +- .../kiota/http/middleware/options/UserAgentHandlerOption.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7e23ced9c..de3be6817 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,7 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed -## [1.0.5] - 2023-02-27 +## [1.0.5] - 2023-02-28 ### Changed diff --git a/components/http/okHttp/src/main/java/com/microsoft/kiota/http/middleware/options/UserAgentHandlerOption.java b/components/http/okHttp/src/main/java/com/microsoft/kiota/http/middleware/options/UserAgentHandlerOption.java index a8bd13b40..85f8d297e 100644 --- a/components/http/okHttp/src/main/java/com/microsoft/kiota/http/middleware/options/UserAgentHandlerOption.java +++ b/components/http/okHttp/src/main/java/com/microsoft/kiota/http/middleware/options/UserAgentHandlerOption.java @@ -13,7 +13,7 @@ public UserAgentHandlerOption() {} private boolean enabled = true; @Nonnull private String productName = "kiota-java"; - @Nonnull private String productVersion = "1.0.4"; + @Nonnull private String productVersion = "1.0.5"; /** * Gets the product name to be used in the user agent header From 8f0b05e8890513cd88be73ac260434ed3c6218f0 Mon Sep 17 00:00:00 2001 From: ramsessanchez <63934382+ramsessanchez@users.noreply.github.com> Date: Wed, 28 Feb 2024 13:26:41 -0800 Subject: [PATCH 12/13] fix failing spotbugs tests --- .../kiota/http/OkHttpRequestAdapterTest.java | 30 ++++++++++--------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/components/http/okHttp/src/test/java/com/microsoft/kiota/http/OkHttpRequestAdapterTest.java b/components/http/okHttp/src/test/java/com/microsoft/kiota/http/OkHttpRequestAdapterTest.java index 77f66c6d9..da5c4ce22 100644 --- a/components/http/okHttp/src/test/java/com/microsoft/kiota/http/OkHttpRequestAdapterTest.java +++ b/components/http/okHttp/src/test/java/com/microsoft/kiota/http/OkHttpRequestAdapterTest.java @@ -299,7 +299,8 @@ void getRequestFromRequestInformationHasCorrectContentLength_JsonPayload() throw requestInformation.setUri(new URI("https://localhost")); ByteArrayInputStream content = new ByteArrayInputStream( - "{\"name\":\"value\",\"array\":[\"1\",\"2\",\"3\"]}".getBytes()); + "{\"name\":\"value\",\"array\":[\"1\",\"2\",\"3\"]}" + .getBytes(StandardCharsets.UTF_8)); requestInformation.setStreamContent(content, "application/octet-stream"); requestInformation.httpMethod = HttpMethod.PUT; requestInformation.headers.tryAdd("Content-Length", String.valueOf(content.available())); @@ -328,21 +329,22 @@ void getRequestFromRequestInformationIncludesContentLength_FilePayload() throws requestInformation.setUri(new URI("https://localhost")); requestInformation.httpMethod = HttpMethod.PUT; requestInformation.headers.add("Content-Length", String.valueOf(testFile.length())); - requestInformation.setStreamContent( - new FileInputStream(testFile), "application/octet-stream"); + try (FileInputStream content = new FileInputStream(testFile)) { + requestInformation.setStreamContent(content, "application/octet-stream"); - final var adapter = new OkHttpRequestAdapter(authenticationProviderMock); - final var request = - adapter.getRequestFromRequestInformation( - requestInformation, mock(Span.class), mock(Span.class)); + final var adapter = new OkHttpRequestAdapter(authenticationProviderMock); + final var request = + adapter.getRequestFromRequestInformation( + requestInformation, mock(Span.class), mock(Span.class)); - assertEquals( - String.valueOf(requestInformation.content.available()), - request.headers().get("Content-Length")); - assertEquals("application/octet-stream", request.headers().get("Content-Type")); - assertNotNull(request.body()); - assertEquals(request.body().contentLength(), requestInformation.content.available()); - assertEquals(request.body().contentType(), MediaType.parse("application/octet-stream")); + assertEquals( + String.valueOf(requestInformation.content.available()), + request.headers().get("Content-Length")); + assertEquals("application/octet-stream", request.headers().get("Content-Type")); + assertNotNull(request.body()); + assertEquals(request.body().contentLength(), requestInformation.content.available()); + assertEquals(request.body().contentType(), MediaType.parse("application/octet-stream")); + } } public static OkHttpClient getMockClient(final Response response) throws IOException { From 826ad00c4bbdafdc797f163267fefe9a5b1689f2 Mon Sep 17 00:00:00 2001 From: ramsessanchez <63934382+ramsessanchez@users.noreply.github.com> Date: Wed, 28 Feb 2024 14:50:29 -0800 Subject: [PATCH 13/13] fix file path --- .../com/microsoft/kiota/http/OkHttpRequestAdapterTest.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/components/http/okHttp/src/test/java/com/microsoft/kiota/http/OkHttpRequestAdapterTest.java b/components/http/okHttp/src/test/java/com/microsoft/kiota/http/OkHttpRequestAdapterTest.java index da5c4ce22..5905e2bcf 100644 --- a/components/http/okHttp/src/test/java/com/microsoft/kiota/http/OkHttpRequestAdapterTest.java +++ b/components/http/okHttp/src/test/java/com/microsoft/kiota/http/OkHttpRequestAdapterTest.java @@ -322,8 +322,7 @@ void getRequestFromRequestInformationHasCorrectContentLength_JsonPayload() throw @Test void getRequestFromRequestInformationIncludesContentLength_FilePayload() throws Exception { final var authenticationProviderMock = mock(AuthenticationProvider.class); - final var testFile = new File(".\\src\\test\\resources\\helloWorld.txt"); - System.out.println(testFile.getCanonicalPath()); + final var testFile = new File("./src/test/resources/helloWorld.txt"); final var requestInformation = new RequestInformation(); requestInformation.setUri(new URI("https://localhost"));