JAVA-23235 Split or move spring-cloud-openfeign module (conti-4) (moved-8) (#14450)
Co-authored-by: timis1 <noreplay@yahoo.com>
This commit is contained in:
+16
@@ -0,0 +1,16 @@
|
||||
package com.baeldung.cloud.openfeign.client;
|
||||
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
|
||||
import com.baeldung.cloud.openfeign.model.Album;
|
||||
|
||||
@FeignClient(name = "albumClient", url = "https://jsonplaceholder.typicode.com/albums/")
|
||||
public interface AlbumClient {
|
||||
@GetMapping(value = "/{id}")
|
||||
Album getAlbumById(@PathVariable(value = "id") Integer id);
|
||||
|
||||
@GetMapping(value = "/{id}")
|
||||
Album getAlbumByIdAndDynamicUrl(@PathVariable(name = "id") Integer id);
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
package com.baeldung.cloud.openfeign.client;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
|
||||
import com.baeldung.cloud.openfeign.config.ClientConfiguration;
|
||||
import com.baeldung.cloud.openfeign.hystrix.JSONPlaceHolderFallback;
|
||||
import com.baeldung.cloud.openfeign.model.Post;
|
||||
|
||||
@FeignClient(value = "jplaceholder",
|
||||
url = "https://jsonplaceholder.typicode.com/",
|
||||
configuration = ClientConfiguration.class,
|
||||
fallback = JSONPlaceHolderFallback.class)
|
||||
public interface JSONPlaceHolderClient {
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET, value = "/posts")
|
||||
List<Post> getPosts();
|
||||
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET, value = "/posts/{postId}", produces = "application/json")
|
||||
Post getPostById(@PathVariable("postId") Long postId);
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
package com.baeldung.cloud.openfeign.client;
|
||||
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
|
||||
import com.baeldung.cloud.openfeign.model.Post;
|
||||
|
||||
@FeignClient(name = "postClient", url = "${spring.cloud.openfeign.client.config.postClient.url}")
|
||||
public interface PostClient {
|
||||
@GetMapping(value = "/{id}")
|
||||
Post getPostById(@PathVariable(value = "id") Integer id);
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
package com.baeldung.cloud.openfeign.client;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
|
||||
import com.baeldung.cloud.openfeign.model.Todo;
|
||||
|
||||
import feign.RequestLine;
|
||||
|
||||
@FeignClient(name = "todoClient")
|
||||
public interface TodoClient {
|
||||
@RequestLine(value = "GET")
|
||||
Todo getTodoById(URI uri);
|
||||
}
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
package com.baeldung.cloud.openfeign.config;
|
||||
|
||||
import org.apache.http.entity.ContentType;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
|
||||
import feign.Logger;
|
||||
import feign.RequestInterceptor;
|
||||
import feign.auth.BasicAuthRequestInterceptor;
|
||||
import feign.codec.ErrorDecoder;
|
||||
import feign.okhttp.OkHttpClient;
|
||||
|
||||
public class ClientConfiguration {
|
||||
|
||||
@Bean
|
||||
public Logger.Level feignLoggerLevel() {
|
||||
return Logger.Level.FULL;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ErrorDecoder errorDecoder() {
|
||||
return new CustomErrorDecoder();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public OkHttpClient client() {
|
||||
return new OkHttpClient();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public RequestInterceptor requestInterceptor() {
|
||||
return requestTemplate -> {
|
||||
requestTemplate.header("user", "ajeje");
|
||||
requestTemplate.header("password", "brazof");
|
||||
requestTemplate.header("Accept", ContentType.APPLICATION_JSON.getMimeType());
|
||||
};
|
||||
}
|
||||
|
||||
// @Bean - uncomment to use this interceptor and remove @Bean from the requestInterceptor()
|
||||
public BasicAuthRequestInterceptor basicAuthRequestInterceptor() {
|
||||
return new BasicAuthRequestInterceptor("ajeje", "brazof");
|
||||
}
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
package com.baeldung.cloud.openfeign.config;
|
||||
|
||||
import com.baeldung.cloud.openfeign.exception.BadRequestException;
|
||||
import com.baeldung.cloud.openfeign.exception.NotFoundException;
|
||||
|
||||
import feign.Response;
|
||||
import feign.codec.ErrorDecoder;
|
||||
|
||||
public class CustomErrorDecoder implements ErrorDecoder {
|
||||
@Override
|
||||
public Exception decode(String methodKey, Response response) {
|
||||
|
||||
switch (response.status()){
|
||||
case 400:
|
||||
return new BadRequestException();
|
||||
case 404:
|
||||
return new NotFoundException("Not found !!!");
|
||||
default:
|
||||
return new Exception("Generic error");
|
||||
}
|
||||
}
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
package com.baeldung.cloud.openfeign.config;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import feign.RequestInterceptor;
|
||||
import feign.RequestTemplate;
|
||||
|
||||
public class DynamicUrlInterceptor implements RequestInterceptor {
|
||||
|
||||
private final Supplier<String> urlSupplier;
|
||||
|
||||
public DynamicUrlInterceptor(Supplier<String> urlSupplier) {
|
||||
this.urlSupplier = urlSupplier;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply(RequestTemplate template) {
|
||||
String url = urlSupplier.get();
|
||||
if (url != null) {
|
||||
template.target(url);
|
||||
}
|
||||
}
|
||||
}
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
package com.baeldung.cloud.openfeign.controller;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
import org.springframework.beans.factory.ObjectFactory;
|
||||
import org.springframework.beans.factory.ObjectProvider;
|
||||
import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
|
||||
import org.springframework.cloud.openfeign.FeignClientsConfiguration;
|
||||
import org.springframework.cloud.openfeign.support.HttpMessageConverterCustomizer;
|
||||
import org.springframework.cloud.openfeign.support.SpringDecoder;
|
||||
import org.springframework.cloud.openfeign.support.SpringEncoder;
|
||||
import org.springframework.cloud.openfeign.support.SpringMvcContract;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import com.baeldung.cloud.openfeign.client.AlbumClient;
|
||||
import com.baeldung.cloud.openfeign.client.PostClient;
|
||||
import com.baeldung.cloud.openfeign.client.TodoClient;
|
||||
import com.baeldung.cloud.openfeign.config.DynamicUrlInterceptor;
|
||||
import com.baeldung.cloud.openfeign.model.Album;
|
||||
import com.baeldung.cloud.openfeign.model.Post;
|
||||
import com.baeldung.cloud.openfeign.model.Todo;
|
||||
|
||||
import feign.Feign;
|
||||
import feign.Target;
|
||||
import feign.codec.Decoder;
|
||||
import feign.codec.Encoder;
|
||||
|
||||
@RestController
|
||||
@Import(FeignClientsConfiguration.class)
|
||||
public class ConfigureFeignUrlController {
|
||||
private final AlbumClient albumClient;
|
||||
|
||||
private final PostClient postClient;
|
||||
|
||||
private final TodoClient todoClient;
|
||||
|
||||
private final ObjectFactory<HttpMessageConverters> messageConverters;
|
||||
|
||||
private final ObjectProvider<HttpMessageConverterCustomizer> customizers;
|
||||
|
||||
public ConfigureFeignUrlController(AlbumClient albumClient,
|
||||
PostClient postClient,
|
||||
Decoder decoder,
|
||||
Encoder encoder,
|
||||
ObjectFactory<HttpMessageConverters> messageConverters, ObjectProvider<HttpMessageConverterCustomizer> customizers) {
|
||||
this.albumClient = albumClient;
|
||||
this.postClient = postClient;
|
||||
this.messageConverters = messageConverters;
|
||||
this.customizers = customizers;
|
||||
this.todoClient = Feign.builder().encoder(encoder).decoder(decoder).target(Target.EmptyTarget.create(TodoClient.class));
|
||||
}
|
||||
|
||||
@GetMapping(value = "albums/{id}")
|
||||
public Album getAlbumById(@PathVariable(value = "id") Integer id) {
|
||||
return albumClient.getAlbumById(id);
|
||||
}
|
||||
|
||||
@GetMapping(value = "posts/{id}")
|
||||
public Post getPostById(@PathVariable(value = "id") Integer id) {
|
||||
return postClient.getPostById(id);
|
||||
}
|
||||
|
||||
@GetMapping(value = "todos/{id}")
|
||||
public Todo getTodoById(@PathVariable(value = "id") Integer id) {
|
||||
return todoClient.getTodoById(URI.create("https://jsonplaceholder.typicode.com/todos/" + id));
|
||||
}
|
||||
|
||||
@GetMapping(value = "/dynamicAlbums/{id}")
|
||||
public Album getAlbumByIdAndDynamicUrl(@PathVariable(value = "id") Integer id) {
|
||||
AlbumClient client = Feign.builder()
|
||||
.requestInterceptor(new DynamicUrlInterceptor(() -> "https://jsonplaceholder.typicode.com/albums/"))
|
||||
.contract(new SpringMvcContract())
|
||||
.encoder(new SpringEncoder(messageConverters))
|
||||
.decoder(new SpringDecoder(messageConverters, customizers))
|
||||
.target(Target.EmptyTarget.create(AlbumClient.class));
|
||||
|
||||
return client.getAlbumByIdAndDynamicUrl(id);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
package com.baeldung.cloud.openfeign.exception;
|
||||
|
||||
public class BadRequestException extends Exception {
|
||||
|
||||
public BadRequestException() {
|
||||
}
|
||||
|
||||
public BadRequestException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public BadRequestException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "BadRequestException: "+getMessage();
|
||||
}
|
||||
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
package com.baeldung.cloud.openfeign.exception;
|
||||
|
||||
public class NotFoundException extends Exception {
|
||||
|
||||
public NotFoundException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public NotFoundException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "NotFoundException: " + getMessage();
|
||||
}
|
||||
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
package com.baeldung.cloud.openfeign.hystrix;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.baeldung.cloud.openfeign.client.JSONPlaceHolderClient;
|
||||
import com.baeldung.cloud.openfeign.model.Post;
|
||||
|
||||
@Component
|
||||
public class JSONPlaceHolderFallback implements JSONPlaceHolderClient {
|
||||
|
||||
@Override
|
||||
public List<Post> getPosts() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Post getPostById(Long postId) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
package com.baeldung.cloud.openfeign.model;
|
||||
|
||||
public class Album {
|
||||
|
||||
private Integer id;
|
||||
private Integer userId;
|
||||
private String title;
|
||||
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Integer getUserId() {
|
||||
return userId;
|
||||
}
|
||||
|
||||
public void setUserId(Integer userId) {
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
}
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
package com.baeldung.cloud.openfeign.model;
|
||||
|
||||
public class Post {
|
||||
|
||||
private String userId;
|
||||
private Long id;
|
||||
private String title;
|
||||
private String body;
|
||||
|
||||
public String getUserId() {
|
||||
return userId;
|
||||
}
|
||||
|
||||
public void setUserId(String userId) {
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public String getBody() {
|
||||
return body;
|
||||
}
|
||||
|
||||
public void setBody(String body) {
|
||||
this.body = body;
|
||||
}
|
||||
}
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
package com.baeldung.cloud.openfeign.model;
|
||||
|
||||
public class Todo {
|
||||
private Integer id;
|
||||
private Integer userId;
|
||||
private String title;
|
||||
private Boolean completed;
|
||||
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Integer getUserId() {
|
||||
return userId;
|
||||
}
|
||||
|
||||
public void setUserId(Integer userId) {
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public Boolean getCompleted() {
|
||||
return completed;
|
||||
}
|
||||
|
||||
public void setCompleted(Boolean completed) {
|
||||
this.completed = completed;
|
||||
}
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
package com.baeldung.cloud.openfeign.service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.baeldung.cloud.openfeign.model.Post;
|
||||
|
||||
public interface JSONPlaceHolderService {
|
||||
|
||||
List<Post> getPosts();
|
||||
|
||||
Post getPostById(Long id);
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
package com.baeldung.cloud.openfeign.service.impl;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.baeldung.cloud.openfeign.client.JSONPlaceHolderClient;
|
||||
import com.baeldung.cloud.openfeign.model.Post;
|
||||
import com.baeldung.cloud.openfeign.service.JSONPlaceHolderService;
|
||||
|
||||
@Service
|
||||
public class JSONPlaceHolderServiceImpl implements JSONPlaceHolderService {
|
||||
|
||||
@Autowired
|
||||
private JSONPlaceHolderClient jsonPlaceHolderClient;
|
||||
|
||||
@Override
|
||||
public List<Post> getPosts() {
|
||||
return jsonPlaceHolderClient.getPosts();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Post getPostById(Long id) {
|
||||
return jsonPlaceHolderClient.getPostById(id);
|
||||
}
|
||||
}
|
||||
+8
-1
@@ -1,3 +1,10 @@
|
||||
spring.application.name=openfeign
|
||||
user.api.url=http://localhost:8082/api/user
|
||||
feign.okhttp.enabled=true
|
||||
feign.okhttp.enabled=true
|
||||
|
||||
server.port=8085
|
||||
spring.main.allow-bean-definition-overriding=true
|
||||
logging.level.com.baeldung.cloud.openfeign.client=DEBUG
|
||||
feign.hystrix.enabled=true
|
||||
|
||||
spring.cloud.openfeign.client.config.postClient.url=https://jsonplaceholder.typicode.com/posts/
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
package com.baeldung.cloud.openfeign;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import com.baeldung.cloud.openfeign.model.Post;
|
||||
import com.baeldung.cloud.openfeign.service.JSONPlaceHolderService;
|
||||
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest
|
||||
public class OpenFeignManualTest {
|
||||
|
||||
@Autowired
|
||||
private JSONPlaceHolderService jsonPlaceHolderService;
|
||||
|
||||
@Test
|
||||
public void whenSpringContextIsBootstrapped_thenNoExceptions() {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenGetPosts_thenListPostSizeGreaterThanZero() {
|
||||
|
||||
List<Post> posts = jsonPlaceHolderService.getPosts();
|
||||
|
||||
assertFalse(posts.isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenGetPostWithId_thenPostExist() {
|
||||
|
||||
Post post = jsonPlaceHolderService.getPostById(1L);
|
||||
|
||||
assertNotNull(post);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user