diff --git a/CHANGELOG.md b/CHANGELOG.md index af8670de9..89be4722a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed -Changed OkHttpRequestAdapter dependency from OkHttpClient to Call.Factory (parent interface implemented by OkHttpClient). +## [1.0.0] - 2023-11-10 + +### Changed + +- Kiota-Java has moved away from Async/Completable futures, thus Async components are no longer utilized and have been removed. Furthermore, requestAdapter methods no longer use the async suffix. [#175](https://github.com/microsoft/kiota-java/issues/175) +- ApiException class now extends RuntimeException instead of Exception. +- Changed OkHttpRequestAdapter dependency from OkHttpClient to Call.Factory (parent interface implemented by OkHttpClient). ## [0.8.0] - 2023-10-31 diff --git a/components/abstractions/src/main/java/com/microsoft/kiota/ApiException.java b/components/abstractions/src/main/java/com/microsoft/kiota/ApiException.java index 153247055..987b06e7c 100644 --- a/components/abstractions/src/main/java/com/microsoft/kiota/ApiException.java +++ b/components/abstractions/src/main/java/com/microsoft/kiota/ApiException.java @@ -5,7 +5,7 @@ import jakarta.annotation.Nonnull; /** Parent type for exceptions thrown by the client when receiving failed responses to its requests. */ -public class ApiException extends Exception { +public class ApiException extends RuntimeException { /** {@inheritDoc} */ public ApiException() { super(); diff --git a/components/abstractions/src/main/java/com/microsoft/kiota/ApiExceptionBuilder.java b/components/abstractions/src/main/java/com/microsoft/kiota/ApiExceptionBuilder.java index 3b61d8f13..24c9d2305 100644 --- a/components/abstractions/src/main/java/com/microsoft/kiota/ApiExceptionBuilder.java +++ b/components/abstractions/src/main/java/com/microsoft/kiota/ApiExceptionBuilder.java @@ -28,7 +28,7 @@ public ApiExceptionBuilder(@Nonnull final Supplier builder) { value = (ApiException) error; } else { value = new ApiExceptionBuilder() - .withMessage("\"unexpected error type \" + error.getClass().getName()") + .withMessage("\"unexpected error type \"" + error.getClass().getName()) .build(); } } diff --git a/components/abstractions/src/main/java/com/microsoft/kiota/BaseRequestConfiguration.java b/components/abstractions/src/main/java/com/microsoft/kiota/BaseRequestConfiguration.java index 2a9bf403f..a93859219 100644 --- a/components/abstractions/src/main/java/com/microsoft/kiota/BaseRequestConfiguration.java +++ b/components/abstractions/src/main/java/com/microsoft/kiota/BaseRequestConfiguration.java @@ -6,6 +6,12 @@ /** Base class for request configuration */ public abstract class BaseRequestConfiguration { + /** + * Default constructor + */ + public BaseRequestConfiguration() { + // default empty constructor + } /** Request headers */ @Nullable public RequestHeaders headers = new RequestHeaders(); diff --git a/components/abstractions/src/main/java/com/microsoft/kiota/CaseInsensitiveMap.java b/components/abstractions/src/main/java/com/microsoft/kiota/CaseInsensitiveMap.java index 03cc40f27..8fe0a09a1 100644 --- a/components/abstractions/src/main/java/com/microsoft/kiota/CaseInsensitiveMap.java +++ b/components/abstractions/src/main/java/com/microsoft/kiota/CaseInsensitiveMap.java @@ -17,6 +17,9 @@ * A map that is case-insensitive on the keys */ public class CaseInsensitiveMap implements Map>{ + /** + * Default constructor + */ public CaseInsensitiveMap() { // default constructor } diff --git a/components/abstractions/src/main/java/com/microsoft/kiota/MultipartBody.java b/components/abstractions/src/main/java/com/microsoft/kiota/MultipartBody.java index 95c7ef0d0..ea8fee239 100644 --- a/components/abstractions/src/main/java/com/microsoft/kiota/MultipartBody.java +++ b/components/abstractions/src/main/java/com/microsoft/kiota/MultipartBody.java @@ -17,6 +17,12 @@ * Represents a multipart body for a request or a response. */ public class MultipartBody implements Parsable { + /** + * Creates a new instance of the MultipartBody class. + */ + public MultipartBody() { + // default empty constructor + } @Nonnull private final String boundary = UUID.randomUUID().toString().replace("-", ""); /** diff --git a/components/abstractions/src/main/java/com/microsoft/kiota/NativeResponseHandler.java b/components/abstractions/src/main/java/com/microsoft/kiota/NativeResponseHandler.java index 8b203dff9..3145eb0c1 100644 --- a/components/abstractions/src/main/java/com/microsoft/kiota/NativeResponseHandler.java +++ b/components/abstractions/src/main/java/com/microsoft/kiota/NativeResponseHandler.java @@ -13,6 +13,12 @@ * The {@code ResponseHandler} implementation to handle native response objects */ public class NativeResponseHandler implements ResponseHandler { + /** + * Default constructor + */ + public NativeResponseHandler() { + // default empty constructor + } private Object value; private HashMap> errorMappings; @Override diff --git a/components/abstractions/src/main/java/com/microsoft/kiota/ResponseHandler.java b/components/abstractions/src/main/java/com/microsoft/kiota/ResponseHandler.java index ce88ecedd..64ed54e9f 100644 --- a/components/abstractions/src/main/java/com/microsoft/kiota/ResponseHandler.java +++ b/components/abstractions/src/main/java/com/microsoft/kiota/ResponseHandler.java @@ -17,6 +17,7 @@ public interface ResponseHandler { * @param errorMappings the error mappings for the response to use when deserializing failed responses bodies. Where an error code like 401 applies specifically to that status code, a class code like 4XX applies to all status codes within the range if an the specific error code is not present. * @param The type of the native response object. * @param The type of the response model object. + * @return The deserialized response model object. */ @Nullable ModelType handleResponse(@Nonnull final NativeResponseType response, @Nullable final HashMap> errorMappings); diff --git a/components/http/okHttp/src/main/java/com/microsoft/kiota/http/HeadersCompatibility.java b/components/http/okHttp/src/main/java/com/microsoft/kiota/http/HeadersCompatibility.java index 2bfd2a6d7..d2c19cb9b 100644 --- a/components/http/okHttp/src/main/java/com/microsoft/kiota/http/HeadersCompatibility.java +++ b/components/http/okHttp/src/main/java/com/microsoft/kiota/http/HeadersCompatibility.java @@ -20,6 +20,7 @@ private HeadersCompatibility() { * @param headers the okhttp3 headers * @return the ResponseHeaders object */ + @Nonnull public static ResponseHeaders getResponseHeaders(@Nonnull final okhttp3.Headers headers) { Objects.requireNonNull(headers); final ResponseHeaders responseHeaders = new ResponseHeaders(); @@ -29,13 +30,13 @@ public static ResponseHeaders getResponseHeaders(@Nonnull final okhttp3.Headers }); return responseHeaders; } - /** * INTERNAL METHOD, DO NOT USE DIRECTLY * Get the request headers from the okhttp3 headers and convert them to a RequestHeaders object * @param headers the okhttp3 headers * @return the RequestHeaders object */ + @Nonnull public static RequestHeaders getRequestHeaders(@Nonnull final okhttp3.Headers headers) { Objects.requireNonNull(headers); final RequestHeaders requestHeaders = new RequestHeaders(); 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 cb8f8407a..7ea0369d6 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 @@ -21,19 +21,10 @@ import java.util.Set; import java.util.UUID; -import com.microsoft.kiota.ApiExceptionBuilder; +import com.microsoft.kiota.*; import jakarta.annotation.Nonnull; import jakarta.annotation.Nullable; -import com.microsoft.kiota.ApiClientBuilder; -import com.microsoft.kiota.ApiException; -import com.microsoft.kiota.HttpMethod; -import com.microsoft.kiota.RequestInformation; -import com.microsoft.kiota.RequestOption; -import com.microsoft.kiota.ResponseHandlerOption; -import com.microsoft.kiota.ResponseHeaders; -import com.microsoft.kiota.ResponseHandler; -import com.microsoft.kiota.PeriodAndDuration; import com.microsoft.kiota.authentication.AuthenticationProvider; import com.microsoft.kiota.http.middleware.ParametersNameDecodingHandler; import com.microsoft.kiota.serialization.ParseNodeFactoryRegistry; @@ -201,10 +192,6 @@ public List sendCollection(@Nonnull fina span.addEvent(eventResponseHandlerInvokedKey); return responseHandler.handleResponse(response, errorMappings); } - } catch(ApiException ex) { - throw new RuntimeException(ex); - } catch(IOException ex) { - throw new RuntimeException("failed to read the response body", ex); } finally { span.end(); } @@ -268,10 +255,6 @@ public ModelType send(@Nonnull final RequestInforma span.addEvent(eventResponseHandlerInvokedKey); return responseHandler.handleResponse(response, errorMappings); } - } catch(ApiException ex) { - throw new RuntimeException(ex); - } catch(IOException ex) { - throw new RuntimeException("failed to read the response body", ex); } finally { span.end(); } @@ -371,11 +354,6 @@ public ModelType sendPrimitive(@Nonnull final RequestInformation req span.addEvent(eventResponseHandlerInvokedKey); return responseHandler.handleResponse(response, errorMappings); } - - } catch(ApiException ex) { - throw new RuntimeException(ex); - } catch(IOException ex) { - throw new RuntimeException("failed to read the response body", ex); } finally { span.end(); } @@ -415,10 +393,6 @@ public > ModelType sendEnum(@Nonnull final Req span.addEvent(eventResponseHandlerInvokedKey); return responseHandler.handleResponse(response, errorMappings); } - } catch(ApiException ex) { - throw new RuntimeException(ex); - } catch(IOException ex) { - throw new RuntimeException("failed to read the response body", ex); } finally { span.end(); } @@ -458,12 +432,6 @@ public > List sendEnumCollection(@N span.addEvent(eventResponseHandlerInvokedKey); return responseHandler.handleResponse(response, errorMappings); } - - - } catch(ApiException ex) { - throw new RuntimeException(ex); - } catch(IOException ex) { - throw new RuntimeException("failed to read the response body", ex); } finally { span.end(); } @@ -503,16 +471,12 @@ public List sendPrimitiveCollection(@Nonnull final Reques span.addEvent(eventResponseHandlerInvokedKey); return responseHandler.handleResponse(response, errorMappings); } - } catch(ApiException ex) { - throw new RuntimeException(ex); - } catch(IOException ex) { - throw new RuntimeException("failed to read the response body", ex); } finally { span.end(); } } @Nullable - private ParseNode getRootParseNode(final Response response, final Span parentSpan, final Span spanForAttributes) throws IOException { + private ParseNode getRootParseNode(final Response response, final Span parentSpan, final Span spanForAttributes) { final Span span = GlobalOpenTelemetry.getTracer(obsOptions.getTracerInstrumentationName()).spanBuilder("getRootParseNode").setParent(Context.current().with(parentSpan)).startSpan(); try(final Scope scope = span.makeCurrent()) { final ResponseBody body = response.body(); // closing the response closes the body and stream https://square.github.io/okhttp/4.x/okhttp/okhttp3/-response-body/ @@ -539,14 +503,14 @@ private boolean shouldReturnNull(final Response response) { /** Key used for the attribute when an error response body is found */ @Nonnull public static final String errorBodyFoundAttributeName = "com.microsoft.kiota.error_body_found"; - private Response throwIfFailedResponse(@Nonnull final Response response, @Nonnull final Span spanForAttributes, @Nullable final HashMap> errorMappings) throws IOException, ApiException { + private Response throwIfFailedResponse(@Nonnull final Response response, @Nonnull final Span spanForAttributes, @Nullable final HashMap> errorMappings) { final Span span = GlobalOpenTelemetry.getTracer(obsOptions.getTracerInstrumentationName()).spanBuilder("throwIfFailedResponse").setParent(Context.current().with(spanForAttributes)).startSpan(); try(final Scope scope = span.makeCurrent()) { if (response.isSuccessful()) return response; spanForAttributes.setStatus(StatusCode.ERROR); final String statusCodeAsString = Integer.toString(response.code()); - final Integer statusCode = response.code(); + final int statusCode = response.code(); final ResponseHeaders responseHeaders = HeadersCompatibility.getResponseHeaders(response.headers()); if (errorMappings == null || !errorMappings.containsKey(statusCodeAsString) && @@ -679,7 +643,7 @@ String getClaimsFromResponse(@Nonnull final Response response, @Nonnull final Re (claims == null || claims.isEmpty()) && // we avoid infinite loops and retry only once (requestInfo.content == null || requestInfo.content.markSupported())) { final List authenticateHeader = response.headers("WWW-Authenticate"); - if(authenticateHeader != null && !authenticateHeader.isEmpty()) { + if(!authenticateHeader.isEmpty()) { String rawHeaderValue = null; for(final String authenticateEntry: authenticateHeader) { final Matcher matcher = bearerPattern.matcher(authenticateEntry); 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 f9732934b..c6a59d1ca 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 @@ -18,7 +18,6 @@ import java.io.ByteArrayInputStream; import java.nio.charset.StandardCharsets; -import java.util.concurrent.ExecutionException; import java.io.InputStream; import java.io.IOException; import java.net.URI; @@ -184,11 +183,10 @@ public void throwsAPIException() throws Exception { when(mockFactory.getParseNode(any(String.class), any(InputStream.class))).thenReturn(mockParseNode); when(mockFactory.getValidContentType()).thenReturn("application/json"); final var requestAdapter = new OkHttpRequestAdapter(authenticationProviderMock, mockFactory, null, client); - final var exception = assertThrows(RuntimeException.class, ()->requestAdapter.send(requestInformation, (node) -> mockEntity, null)) ; - final var cause = exception.getCause(); - assertTrue(cause instanceof ApiException); - assertEquals(404, ((ApiException)cause).getResponseStatusCode()); - assertTrue(((ApiException)cause).getResponseHeaders().containsKey("request-id")); + final var exception = assertThrows(ApiException.class, ()->requestAdapter.send(requestInformation, (node) -> mockEntity, null)) ; + assertNotNull(exception); + assertEquals(404, exception.getResponseStatusCode()); + assertTrue(exception.getResponseHeaders().containsKey("request-id")); } public static OkHttpClient getMockClient(final Response response) throws IOException { final OkHttpClient mockClient = mock(OkHttpClient.class); diff --git a/gradle.properties b/gradle.properties index e3b9cf6a5..d0d1ae918 100644 --- a/gradle.properties +++ b/gradle.properties @@ -24,8 +24,8 @@ org.gradle.parallel=true org.gradle.caching=true mavenGroupId = com.microsoft.kiota -mavenMajorVersion = 0 -mavenMinorVersion = 8 +mavenMajorVersion = 1 +mavenMinorVersion = 0 mavenPatchVersion = 0 mavenArtifactSuffix =