From 4b36bbf0b776f83227225034048d1dbfa2108acb Mon Sep 17 00:00:00 2001 From: Saikat Chakraborty <40471715+saikatcse03@users.noreply.github.com> Date: Fri, 27 May 2022 13:58:56 +0530 Subject: [PATCH] Bael 5296: Added Http Request Header using the Feign Client (#12201) * Implemented cassandra batch query * Added netty version param * Reformatted correctly * Reformatted correctly * Reformatted correctly * Formatting fix resolved * Formatting fix resolved * Removed unused method * Refactored method for better readability * tab spaces corrected * Added http headers in feign * Updated code * Updated code * Removed unused code * Removed unused logger code * Implemented Interceptor and logging related code review * Added AuthService Code * Removed toString method * Removed unnecessary declaration * Removed new line * Added feign headers log as well * Moved to Authorisation package for better naming * spaces removed * @Override included Co-authored-by: saikat chakraborty --- .../builder/BookFeignClientBuilder.java | 34 ++++++++++++ .../header/dynamicheader/BookClient.java | 17 ++++++ .../header/staticheader/BookClient.java | 18 +++++++ .../parameterized/BookClient.java | 16 ++++++ .../ApiAuthorisationService.java | 11 ++++ .../authorisation/AuthorisationService.java | 7 +++ .../interceptor/AuthRequestInterceptor.java | 22 ++++++++ feign/src/main/resources/logback.xml | 3 +- .../dynamicheader/BookClientLiveTest.java | 38 ++++++++++++++ .../interceptor/BookClientLiveTest.java | 52 +++++++++++++++++++ .../staticheader/BookClientLiveTest.java | 45 ++++++++++++++++ .../parameterized/BookClientLiveTest.java | 31 +++++++++++ 12 files changed, 293 insertions(+), 1 deletion(-) create mode 100644 feign/src/main/java/com/baeldung/feign/clients/builder/BookFeignClientBuilder.java create mode 100644 feign/src/main/java/com/baeldung/feign/clients/header/dynamicheader/BookClient.java create mode 100644 feign/src/main/java/com/baeldung/feign/clients/header/staticheader/BookClient.java create mode 100644 feign/src/main/java/com/baeldung/feign/clients/header/staticheader/parameterized/BookClient.java create mode 100644 feign/src/main/java/com/baeldung/feign/header/authorisation/ApiAuthorisationService.java create mode 100644 feign/src/main/java/com/baeldung/feign/header/authorisation/AuthorisationService.java create mode 100644 feign/src/main/java/com/baeldung/feign/header/interceptor/AuthRequestInterceptor.java create mode 100644 feign/src/test/java/com/baeldung/feign/clients/header/dynamicheader/BookClientLiveTest.java create mode 100644 feign/src/test/java/com/baeldung/feign/clients/header/interceptor/BookClientLiveTest.java create mode 100644 feign/src/test/java/com/baeldung/feign/clients/header/staticheader/BookClientLiveTest.java create mode 100644 feign/src/test/java/com/baeldung/feign/clients/header/staticheader/parameterized/BookClientLiveTest.java diff --git a/feign/src/main/java/com/baeldung/feign/clients/builder/BookFeignClientBuilder.java b/feign/src/main/java/com/baeldung/feign/clients/builder/BookFeignClientBuilder.java new file mode 100644 index 0000000000..70a574ed81 --- /dev/null +++ b/feign/src/main/java/com/baeldung/feign/clients/builder/BookFeignClientBuilder.java @@ -0,0 +1,34 @@ +package com.baeldung.feign.clients.builder; + +import com.baeldung.feign.header.authorisation.ApiAuthorisationService; +import com.baeldung.feign.header.interceptor.AuthRequestInterceptor; + + +import feign.Feign; +import feign.Logger; +import feign.gson.GsonDecoder; +import feign.gson.GsonEncoder; +import feign.slf4j.Slf4jLogger; + + +public class BookFeignClientBuilder { + + public static T createClient(Class type, String uri) { + return Feign.builder() + .encoder(new GsonEncoder()) + .decoder(new GsonDecoder()) + .logger(new Slf4jLogger(type)) + .logLevel(Logger.Level.HEADERS) + .target(type, uri); + } + + public static T createClientWithInterceptor(Class type, String uri) { + return Feign.builder() + .requestInterceptor(new AuthRequestInterceptor(new ApiAuthorisationService())) + .encoder(new GsonEncoder()) + .decoder(new GsonDecoder()) + .logger(new Slf4jLogger(type)) + .logLevel(Logger.Level.HEADERS) + .target(type, uri); + } +} diff --git a/feign/src/main/java/com/baeldung/feign/clients/header/dynamicheader/BookClient.java b/feign/src/main/java/com/baeldung/feign/clients/header/dynamicheader/BookClient.java new file mode 100644 index 0000000000..2148a90120 --- /dev/null +++ b/feign/src/main/java/com/baeldung/feign/clients/header/dynamicheader/BookClient.java @@ -0,0 +1,17 @@ +package com.baeldung.feign.clients.header.dynamicheader; + +import com.baeldung.feign.models.Book; + +import feign.HeaderMap; +import feign.Headers; +import feign.RequestLine; + +import java.util.Map; + +@Headers("Content-Type: application/json") +public interface BookClient { + + @RequestLine("POST") + void create(@HeaderMap Map headers, Book book); + +} diff --git a/feign/src/main/java/com/baeldung/feign/clients/header/staticheader/BookClient.java b/feign/src/main/java/com/baeldung/feign/clients/header/staticheader/BookClient.java new file mode 100644 index 0000000000..cbd2622f9b --- /dev/null +++ b/feign/src/main/java/com/baeldung/feign/clients/header/staticheader/BookClient.java @@ -0,0 +1,18 @@ +package com.baeldung.feign.clients.header.staticheader; + +import com.baeldung.feign.models.Book; +import com.baeldung.feign.models.BookResource; +import feign.Headers; +import feign.Param; +import feign.RequestLine; + +@Headers("Accept-Language: en-US") +public interface BookClient { + + @RequestLine("GET /{isbn}") + BookResource findByIsbn(@Param("isbn") String isbn); + + @RequestLine("POST") + @Headers("Content-Type: application/json") + void create(Book book); +} diff --git a/feign/src/main/java/com/baeldung/feign/clients/header/staticheader/parameterized/BookClient.java b/feign/src/main/java/com/baeldung/feign/clients/header/staticheader/parameterized/BookClient.java new file mode 100644 index 0000000000..83a273893c --- /dev/null +++ b/feign/src/main/java/com/baeldung/feign/clients/header/staticheader/parameterized/BookClient.java @@ -0,0 +1,16 @@ +package com.baeldung.feign.clients.header.staticheader.parameterized; + +import com.baeldung.feign.models.BookResource; + +import feign.Headers; +import feign.Param; +import feign.RequestLine; + + +@Headers("x-requester-id: {requester}") +public interface BookClient { + + @RequestLine("GET /{isbn}") + BookResource findByIsbn(@Param("requester") String requestorId, @Param("isbn") String isbn); + +} diff --git a/feign/src/main/java/com/baeldung/feign/header/authorisation/ApiAuthorisationService.java b/feign/src/main/java/com/baeldung/feign/header/authorisation/ApiAuthorisationService.java new file mode 100644 index 0000000000..1a23f968ac --- /dev/null +++ b/feign/src/main/java/com/baeldung/feign/header/authorisation/ApiAuthorisationService.java @@ -0,0 +1,11 @@ +package com.baeldung.feign.header.authorisation; + +import java.util.UUID; + +public class ApiAuthorisationService implements AuthorisationService { + + @Override + public String getAuthToken() { + return "Bearer " + UUID.randomUUID(); + } +} diff --git a/feign/src/main/java/com/baeldung/feign/header/authorisation/AuthorisationService.java b/feign/src/main/java/com/baeldung/feign/header/authorisation/AuthorisationService.java new file mode 100644 index 0000000000..12e6d59bcc --- /dev/null +++ b/feign/src/main/java/com/baeldung/feign/header/authorisation/AuthorisationService.java @@ -0,0 +1,7 @@ +package com.baeldung.feign.header.authorisation; + +public interface AuthorisationService { + + String getAuthToken(); + +} diff --git a/feign/src/main/java/com/baeldung/feign/header/interceptor/AuthRequestInterceptor.java b/feign/src/main/java/com/baeldung/feign/header/interceptor/AuthRequestInterceptor.java new file mode 100644 index 0000000000..eda428de1a --- /dev/null +++ b/feign/src/main/java/com/baeldung/feign/header/interceptor/AuthRequestInterceptor.java @@ -0,0 +1,22 @@ +package com.baeldung.feign.header.interceptor; + +import com.baeldung.feign.header.authorisation.AuthorisationService; +import feign.RequestInterceptor; +import feign.RequestTemplate; + + +public class AuthRequestInterceptor implements RequestInterceptor { + + private AuthorisationService authTokenService; + + public AuthRequestInterceptor(AuthorisationService authTokenService) { + this.authTokenService = authTokenService; + } + + @Override + public void apply(RequestTemplate template) { + template.header("Authorisation", authTokenService.getAuthToken()); + } +} + + \ No newline at end of file diff --git a/feign/src/main/resources/logback.xml b/feign/src/main/resources/logback.xml index 7d900d8ea8..e5e962c8e0 100644 --- a/feign/src/main/resources/logback.xml +++ b/feign/src/main/resources/logback.xml @@ -5,9 +5,10 @@ %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + - + \ No newline at end of file diff --git a/feign/src/test/java/com/baeldung/feign/clients/header/dynamicheader/BookClientLiveTest.java b/feign/src/test/java/com/baeldung/feign/clients/header/dynamicheader/BookClientLiveTest.java new file mode 100644 index 0000000000..6e78ba03a6 --- /dev/null +++ b/feign/src/test/java/com/baeldung/feign/clients/header/dynamicheader/BookClientLiveTest.java @@ -0,0 +1,38 @@ +package com.baeldung.feign.clients.header.dynamicheader; + +import com.baeldung.feign.clients.builder.BookFeignClientBuilder; +import com.baeldung.feign.models.Book; +import org.junit.Before; +import org.junit.Test; + +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +/** + * Consumes https://github.com/Baeldung/spring-hypermedia-api + */ +public class BookClientLiveTest { + + private BookClient bookClient; + + @Before + public void setup() { + bookClient = BookFeignClientBuilder.createClient(BookClient.class, "http://localhost:8081/api/books"); + } + + @Test + public void givenBookClient_shouldPostBook() throws Exception { + String isbn = UUID.randomUUID() + .toString(); + + Book book = new Book(isbn, "Me", "It's me!", null, null); + + Map headerMap = new HashMap<>(); + + headerMap.put("metadata-key1", "metadata-value1"); + headerMap.put("metadata-key2", "metadata-value2"); + + bookClient.create(headerMap, book); + } +} diff --git a/feign/src/test/java/com/baeldung/feign/clients/header/interceptor/BookClientLiveTest.java b/feign/src/test/java/com/baeldung/feign/clients/header/interceptor/BookClientLiveTest.java new file mode 100644 index 0000000000..2062b86791 --- /dev/null +++ b/feign/src/test/java/com/baeldung/feign/clients/header/interceptor/BookClientLiveTest.java @@ -0,0 +1,52 @@ +package com.baeldung.feign.clients.header.interceptor; + +import com.baeldung.feign.clients.builder.BookFeignClientBuilder; +import com.baeldung.feign.clients.header.staticheader.BookClient; +import com.baeldung.feign.models.Book; +import org.junit.Before; +import org.junit.Test; + +import java.util.UUID; + +import static org.hamcrest.CoreMatchers.containsString; +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +/** + * Consumes https://github.com/Baeldung/spring-hypermedia-api + */ +public class BookClientLiveTest { + + private BookClient bookClient; + + @Before + public void setup() { + bookClient = BookFeignClientBuilder.createClientWithInterceptor(BookClient.class, "http://localhost:8081/api/books"); + } + + @Test + public void givenBookClient_shouldFindOneBook() throws Exception { + Book book = bookClient.findByIsbn("0151072558") + .getBook(); + assertThat(book.getAuthor(), containsString("Orwell")); + } + + @Test + public void givenBookClient2_shouldFindOneBook() throws Exception { + Book book = bookClient.findByIsbn("0151072558") + .getBook(); + assertThat(book.getAuthor(), containsString("Orwell")); + } + + @Test + public void givenBookClient_shouldPostBook() throws Exception { + String isbn = UUID.randomUUID() + .toString(); + Book book = new Book(isbn, "Me", "It's me!", null, null); + bookClient.create(book); + + book = bookClient.findByIsbn(isbn) + .getBook(); + assertThat(book.getAuthor(), is("Me")); + } +} diff --git a/feign/src/test/java/com/baeldung/feign/clients/header/staticheader/BookClientLiveTest.java b/feign/src/test/java/com/baeldung/feign/clients/header/staticheader/BookClientLiveTest.java new file mode 100644 index 0000000000..08b8461fb5 --- /dev/null +++ b/feign/src/test/java/com/baeldung/feign/clients/header/staticheader/BookClientLiveTest.java @@ -0,0 +1,45 @@ +package com.baeldung.feign.clients.header.staticheader; + +import com.baeldung.feign.clients.builder.BookFeignClientBuilder; +import com.baeldung.feign.models.Book; +import org.junit.Before; +import org.junit.Test; + +import java.util.UUID; + +import static org.hamcrest.CoreMatchers.containsString; +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +/** + * Consumes https://github.com/Baeldung/spring-hypermedia-api + */ +public class BookClientLiveTest { + + private BookClient bookClient; + + @Before + public void setup() { + bookClient = BookFeignClientBuilder.createClient(BookClient.class, "http://localhost:8081/api/books"); + } + + @Test + public void givenBookClient_shouldFindOneBook() throws Exception { + Book book = bookClient.findByIsbn("0151072558") + .getBook(); + assertThat(book.getAuthor(), containsString("Orwell")); + } + + @Test + public void givenBookClient_shouldPostBook() throws Exception { + String isbn = UUID.randomUUID() + .toString(); + Book book = new Book(isbn, "Me", "It's me!", null, null); + + bookClient.create(book); + + book = bookClient.findByIsbn(isbn) + .getBook(); + assertThat(book.getAuthor(), is("Me")); + } +} diff --git a/feign/src/test/java/com/baeldung/feign/clients/header/staticheader/parameterized/BookClientLiveTest.java b/feign/src/test/java/com/baeldung/feign/clients/header/staticheader/parameterized/BookClientLiveTest.java new file mode 100644 index 0000000000..94e91b539c --- /dev/null +++ b/feign/src/test/java/com/baeldung/feign/clients/header/staticheader/parameterized/BookClientLiveTest.java @@ -0,0 +1,31 @@ +package com.baeldung.feign.clients.header.staticheader.parameterized; + +import com.baeldung.feign.clients.builder.BookFeignClientBuilder; +import com.baeldung.feign.models.Book; +import org.junit.Before; +import org.junit.Test; + +import static org.hamcrest.CoreMatchers.containsString; +import static org.junit.Assert.assertThat; + +/** + * Consumes https://github.com/Baeldung/spring-hypermedia-api + */ +public class BookClientLiveTest { + + private BookClient bookClient; + + private String requester = "test"; + + @Before + public void setup() { + bookClient = BookFeignClientBuilder.createClient(BookClient.class, "http://localhost:8081/api/books"); + } + + @Test + public void givenBookClient_shouldFindOneBook() throws Exception { + Book book = bookClient.findByIsbn(requester, "0151072558") + .getBook(); + assertThat(book.getAuthor(), containsString("Orwell")); + } +}