From 06cd20ccd0134b79adbabc03ddb94a97cee60e89 Mon Sep 17 00:00:00 2001 From: Sashir Estela Date: Sun, 11 Feb 2024 22:37:34 +0000 Subject: [PATCH 1/2] Reformat code --- .../metadata/InterfaceMetadataStoreTest.java | 39 +++++++++---------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/src/test/java/io/github/sashirestela/cleverclient/metadata/InterfaceMetadataStoreTest.java b/src/test/java/io/github/sashirestela/cleverclient/metadata/InterfaceMetadataStoreTest.java index 78bb6b6..f347665 100644 --- a/src/test/java/io/github/sashirestela/cleverclient/metadata/InterfaceMetadataStoreTest.java +++ b/src/test/java/io/github/sashirestela/cleverclient/metadata/InterfaceMetadataStoreTest.java @@ -1,5 +1,6 @@ package io.github.sashirestela.cleverclient.metadata; +import static io.github.sashirestela.cleverclient.util.CommonUtil.createMapString; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; @@ -13,8 +14,7 @@ import io.github.sashirestela.cleverclient.metadata.InterfaceMetadata.MethodMetadata; import io.github.sashirestela.cleverclient.metadata.InterfaceMetadata.ParameterMetadata; import io.github.sashirestela.cleverclient.support.CleverClientException; -import io.github.sashirestela.cleverclient.support.ReturnType; -import io.github.sashirestela.cleverclient.util.CommonUtil; +import io.github.sashirestela.cleverclient.support.ReturnType;; public class InterfaceMetadataStoreTest { @@ -33,18 +33,17 @@ void shouldSaveInterfaceMetadataWhenAccomplishValidtion() { AnnotationMetadata.builder() .name("POST") .isHttpMethod(true) - .valueByField(CommonUtil.createMapString("value", "/demos/{demoId}")) + .valueByField(createMapString("value", "/demos/{demoId}")) .build(), AnnotationMetadata.builder() .name("Multipart") .isHttpMethod(false) - .valueByField(CommonUtil.createMapString()) + .valueByField(createMapString()) .build(), AnnotationMetadata.builder() .name("Header") .isHttpMethod(false) - .valueByField( - CommonUtil.createMapString("name", "ThirdKey", "value", "ThirdVal")) + .valueByField(createMapString("name", "ThirdKey", "value", "ThirdVal")) .build())) .parameters(Arrays.asList( ParameterMetadata.builder() @@ -52,7 +51,7 @@ void shouldSaveInterfaceMetadataWhenAccomplishValidtion() { .annotation(AnnotationMetadata.builder() .name("Body") .isHttpMethod(false) - .valueByField(CommonUtil.createMapString()) + .valueByField(createMapString()) .build()) .build(), ParameterMetadata.builder() @@ -60,7 +59,7 @@ void shouldSaveInterfaceMetadataWhenAccomplishValidtion() { .annotation(AnnotationMetadata.builder() .name("Path") .isHttpMethod(false) - .valueByField(CommonUtil.createMapString("value", "demoId")) + .valueByField(createMapString("value", "demoId")) .build()) .build())) .build()); @@ -75,8 +74,7 @@ void shouldSaveInterfaceMetadataWhenAccomplishValidtion() { AnnotationMetadata.builder() .name("GET") .isHttpMethod(true) - .valueByField( - CommonUtil.createMapString("value", "/demos/{demoId}/subdemos")) + .valueByField(createMapString("value", "/demos/{demoId}/subdemos")) .build())) .parameters(Arrays.asList( ParameterMetadata.builder() @@ -84,7 +82,7 @@ void shouldSaveInterfaceMetadataWhenAccomplishValidtion() { .annotation(AnnotationMetadata.builder() .name("Path") .isHttpMethod(false) - .valueByField(CommonUtil.createMapString("value", "demoId")) + .valueByField(createMapString("value", "demoId")) .build()) .build(), ParameterMetadata.builder() @@ -92,7 +90,7 @@ void shouldSaveInterfaceMetadataWhenAccomplishValidtion() { .annotation(AnnotationMetadata.builder() .name("Query") .isHttpMethod(false) - .valueByField(CommonUtil.createMapString("value", "size")) + .valueByField(createMapString("value", "size")) .build()) .build(), ParameterMetadata.builder() @@ -100,7 +98,7 @@ void shouldSaveInterfaceMetadataWhenAccomplishValidtion() { .annotation(AnnotationMetadata.builder() .name("Query") .isHttpMethod(false) - .valueByField(CommonUtil.createMapString("value", "page")) + .valueByField(createMapString("value", "page")) .build()) .build())) .build()); @@ -110,17 +108,17 @@ void shouldSaveInterfaceMetadataWhenAccomplishValidtion() { AnnotationMetadata.builder() .name("Resource") .isHttpMethod(false) - .valueByField(CommonUtil.createMapString("value", "/api")) + .valueByField(createMapString("value", "/api")) .build(), AnnotationMetadata.builder() .name("Header") .isHttpMethod(false) - .valueByField(CommonUtil.createMapString("name", "FirstKey", "value", "FirstVal")) + .valueByField(createMapString("name", "FirstKey", "value", "FirstVal")) .build(), AnnotationMetadata.builder() .name("Header") .isHttpMethod(false) - .valueByField(CommonUtil.createMapString("name", "SecondKey", "value", "SecondVal")) + .valueByField(createMapString("name", "SecondKey", "value", "SecondVal")) .build())) .methodBySignature(methodBySignature) .build(); @@ -142,14 +140,15 @@ void shouldThrownExceptionWhenMethodHasNotHttpAnnotation() { Exception exception = assertThrows(CleverClientException.class, () -> store.save(ITest.NotAnnotatedService.class)); assertEquals("Missing HTTP annotation for the method unannotatedMethod.", - exception.getMessage()); + exception.getMessage()); } @Test void shouldThrownExceptionWhenUrlPathParamAtMethodUnmatchesAnnotatedArguments() { Exception exception = assertThrows(CleverClientException.class, - () -> store.save(ITest.BadPathParamService.class)); - assertEquals("Path param demoId in the url cannot find an annotated argument in the method unmatchedPathParamMethod.", - exception.getMessage()); + () -> store.save(ITest.BadPathParamService.class)); + assertEquals( + "Path param demoId in the url cannot find an annotated argument in the method unmatchedPathParamMethod.", + exception.getMessage()); } } From 3b177bb0a6aad309a11ffbeecdfcd893e91020fa Mon Sep 17 00:00:00 2001 From: Sashir Estela Date: Sun, 11 Feb 2024 22:47:58 +0000 Subject: [PATCH 2/2] Change headers from list to map --- README.md | 5 +++-- .../cleverclient/example/StreamExample.java | 2 +- .../cleverclient/CleverClient.java | 21 ++++++++---------- .../cleverclient/util/CommonUtil.java | 10 +++++++++ .../cleverclient/CleverClientTest.java | 22 ++++--------------- .../cleverclient/util/CommonUtilTest.java | 20 +++++++++++++++++ 6 files changed, 47 insertions(+), 33 deletions(-) diff --git a/README.md b/README.md index 934e9ea..bcea490 100644 --- a/README.md +++ b/README.md @@ -98,7 +98,8 @@ We have the following attributes to create a CleverClient object: | Attribute | Description | Required | | -------------- |------------------------------------------|-----------| | baseUrl | Api's url | mandatory | -| headers | Pairs of headers name/value | optional | +| headers | Map of headers (name/value) | optional | +| header | Single header (alternative to headers) | optional | | httpClient | Java HttpClient object | optional | | urlInterceptor | Function to modify the url once is built | optional | | endOfStream | Text used to mark the final of streams | optional | @@ -123,7 +124,7 @@ var httpClient = HttpClient.newBuilder() var cleverClient = CleverClient.builder() .baseUrl(BASE_URL) - .headers(Arrays.asList(HEADER_NAME, HEADER_VALUE)) + .header(HEADER_NAME, HEADER_VALUE) .httpClient(httpClient) .urlInterceptor(url -> url + (url.contains("?") ? "&" : "?") + "env=testing") .endOfStream(END_OF_STREAM) diff --git a/src/example/java/io/github/sashirestela/cleverclient/example/StreamExample.java b/src/example/java/io/github/sashirestela/cleverclient/example/StreamExample.java index 594a62c..cedf30c 100644 --- a/src/example/java/io/github/sashirestela/cleverclient/example/StreamExample.java +++ b/src/example/java/io/github/sashirestela/cleverclient/example/StreamExample.java @@ -24,7 +24,7 @@ public static void main(String[] args) { var cleverClient = CleverClient.builder() .baseUrl(BASE_URL) - .headers(Arrays.asList(AUTHORIZATION_HEADER, BEARER_AUTHORIZATION)) + .header(AUTHORIZATION_HEADER, BEARER_AUTHORIZATION) .endOfStream(END_OF_STREAM) .build(); var chatService = cleverClient.create(ChatService.class); diff --git a/src/main/java/io/github/sashirestela/cleverclient/CleverClient.java b/src/main/java/io/github/sashirestela/cleverclient/CleverClient.java index 484d8be..77e1fd2 100644 --- a/src/main/java/io/github/sashirestela/cleverclient/CleverClient.java +++ b/src/main/java/io/github/sashirestela/cleverclient/CleverClient.java @@ -1,7 +1,7 @@ package io.github.sashirestela.cleverclient; import java.net.http.HttpClient; -import java.util.List; +import java.util.Map; import java.util.Optional; import java.util.function.Function; @@ -9,8 +9,8 @@ import org.slf4j.LoggerFactory; import io.github.sashirestela.cleverclient.http.HttpProcessor; -import io.github.sashirestela.cleverclient.support.CleverClientException; import io.github.sashirestela.cleverclient.support.CleverClientSSE; +import io.github.sashirestela.cleverclient.util.CommonUtil; import lombok.Builder; import lombok.Getter; import lombok.NonNull; @@ -25,8 +25,9 @@ public class CleverClient { private static final Logger logger = LoggerFactory.getLogger(CleverClient.class); - @NonNull private final String baseUrl; - private final List headers; + @NonNull + private final String baseUrl; + private final Map headers; private final HttpClient httpClient; private final Function urlInterceptor; private final HttpProcessor httpProcessor; @@ -35,8 +36,7 @@ public class CleverClient { * Constructor to create an instance of CleverClient. * * @param baseUrl Root of the url of the API service to call. Mandatory. - * @param headers Http headers for all the API service. Header's name and - * value must be individual entries in the list. Optional. + * @param headers Http headers for all the API service. Optional. * @param httpClient Custom Java's HttpClient component. One is created by * default if none is passed. Optional. * @param urlInterceptor Function to modify the url once it has been built. @@ -44,19 +44,16 @@ public class CleverClient { * server sent events (SSE). Optional. */ @Builder - public CleverClient(@NonNull String baseUrl, @Singular List headers, HttpClient httpClient, + public CleverClient(@NonNull String baseUrl, @Singular Map headers, HttpClient httpClient, Function urlInterceptor, String endOfStream) { this.baseUrl = baseUrl; - this.headers = Optional.ofNullable(headers).orElse(List.of()); - if (this.headers.size() % 2 > 0) { - throw new CleverClientException("Headers must be entered as pair of values in the list.", null, null); - } + this.headers = Optional.ofNullable(headers).orElse(Map.of()); this.httpClient = Optional.ofNullable(httpClient).orElse(HttpClient.newHttpClient()); this.urlInterceptor = urlInterceptor; CleverClientSSE.setEndOfStream(endOfStream); this.httpProcessor = HttpProcessor.builder() .baseUrl(this.baseUrl) - .headers(this.headers) + .headers(CommonUtil.mapToListOfString(this.headers)) .httpClient(this.httpClient) .urlInterceptor(this.urlInterceptor) .build(); diff --git a/src/main/java/io/github/sashirestela/cleverclient/util/CommonUtil.java b/src/main/java/io/github/sashirestela/cleverclient/util/CommonUtil.java index a55586e..79d7641 100644 --- a/src/main/java/io/github/sashirestela/cleverclient/util/CommonUtil.java +++ b/src/main/java/io/github/sashirestela/cleverclient/util/CommonUtil.java @@ -1,6 +1,7 @@ package io.github.sashirestela.cleverclient.util; import java.lang.reflect.Array; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.HashMap; @@ -58,4 +59,13 @@ public static Map createMapString(String... keyValPairs) { } return map; } + + public static List mapToListOfString(Map map) { + List list = new ArrayList<>(); + map.entrySet().stream().peek(e -> { + list.add(e.getKey()); + list.add(e.getValue()); + }).collect(Collectors.counting()); + return list; + } } \ No newline at end of file diff --git a/src/test/java/io/github/sashirestela/cleverclient/CleverClientTest.java b/src/test/java/io/github/sashirestela/cleverclient/CleverClientTest.java index 154d944..e4f6342 100644 --- a/src/test/java/io/github/sashirestela/cleverclient/CleverClientTest.java +++ b/src/test/java/io/github/sashirestela/cleverclient/CleverClientTest.java @@ -13,7 +13,7 @@ import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpResponse; -import java.util.List; +import java.util.Map; import java.util.concurrent.CompletableFuture; import java.util.function.Function; @@ -23,7 +23,6 @@ import io.github.sashirestela.cleverclient.annotation.GET; import io.github.sashirestela.cleverclient.annotation.Query; import io.github.sashirestela.cleverclient.annotation.Resource; -import io.github.sashirestela.cleverclient.support.CleverClientException; class CleverClientTest { @@ -32,7 +31,7 @@ void shouldSetPropertiesToDefaultValuesWhenBuilderIsCalledWithoutThoseProperties var cleverClient = CleverClient.builder() .baseUrl("https://test") .build(); - assertEquals(List.of(), cleverClient.getHeaders()); + assertEquals(Map.of(), cleverClient.getHeaders()); assertEquals(HttpClient.Version.HTTP_2, cleverClient.getHttpClient().version()); assertNotNull(cleverClient.getBaseUrl()); assertNotNull(cleverClient.getHttpProcessor()); @@ -43,8 +42,7 @@ void shouldSetPropertiesToDefaultValuesWhenBuilderIsCalledWithoutThoseProperties void shouldImplementInterfaceWhenCallingCreate() { var cleverClient = CleverClient.builder() .baseUrl("https://test") - .header("headerName") - .header("headerValue") + .header("headerName", "headerValue") .httpClient(HttpClient.newHttpClient()) .endOfStream("[DONE]") .build(); @@ -55,25 +53,13 @@ void shouldImplementInterfaceWhenCallingCreate() { @Test void shouldThrownExceptionWhenTryingToPassAnEmptyBaseUrl() { var cleverClientBuilder = CleverClient.builder() - .header("headerName") - .header("headerValue") + .header("headerName", "headerValue") .httpClient(HttpClient.newHttpClient()) .endOfStream("[DONE]"); assertThrows(NullPointerException.class, cleverClientBuilder::build); } - @Test - void shouldThrownExceptionWhenTryingToPassAnOddNumbersOfHeaders() { - var cleverClientBuilder = CleverClient.builder() - .baseUrl("http://test") - .header("oneHeader"); - Exception exception = assertThrows(CleverClientException.class, - cleverClientBuilder::build); - assertEquals("Headers must be entered as pair of values in the list.", - exception.getMessage()); - } - @SuppressWarnings("unchecked") @Test void shouldModifyUrlWhenPassingUrlInterceptorFunction() { diff --git a/src/test/java/io/github/sashirestela/cleverclient/util/CommonUtilTest.java b/src/test/java/io/github/sashirestela/cleverclient/util/CommonUtilTest.java index 5e4665a..b2052e1 100644 --- a/src/test/java/io/github/sashirestela/cleverclient/util/CommonUtilTest.java +++ b/src/test/java/io/github/sashirestela/cleverclient/util/CommonUtilTest.java @@ -3,6 +3,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -11,6 +12,7 @@ import static org.junit.jupiter.api.Assertions.assertArrayEquals; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertLinesMatch; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -124,4 +126,22 @@ void shouldThrownExceptionWhenCreatingMapStringAndExistsWrongCondition() { assertThrows(IllegalArgumentException.class, () -> CommonUtil.createMapString(data)); } } + + @Test + void shouldConvertMapToListOfStringWhenAMapIsPassed() { + Map map = new LinkedHashMap<>(); + map.put("key1", "val1"); + map.put("key2", "val2"); + List expectedList = List.of("key1", "val1", "key2", "val2"); + List actualList = CommonUtil.mapToListOfString(map); + assertLinesMatch(expectedList, actualList); + } + + @Test + void shouldReturnAnEmptyListWhenCallingMapToListAnEmptyMapIsPassed() { + Map map = Map.of(); + List expectedList = List.of(); + List actualList = CommonUtil.mapToListOfString(map); + assertLinesMatch(expectedList, actualList); + } } \ No newline at end of file