BAEL-4012 Add Netflix Feign (#10110)
* BAEL-4012 Add Netflix Feign * BAEL-4012 Cleanup pom
This commit is contained in:
parent
67981e7cba
commit
b9dbeb6c58
|
@ -0,0 +1,71 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<groupId>com.baeldung.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-netlix-feign</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
<name>spring-cloud-netflix-feign</name>
|
||||||
|
<description>Netflix Feign project for Spring Boot</description>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>com.baeldung</groupId>
|
||||||
|
<artifactId>parent-boot-1</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
<relativePath>../../parent-boot-1</relativePath>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<dependencyManagement>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-dependencies</artifactId>
|
||||||
|
<version>${spring-cloud.version}</version>
|
||||||
|
<type>pom</type>
|
||||||
|
<scope>import</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</dependencyManagement>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-starter-feign</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.netflix.feign</groupId>
|
||||||
|
<artifactId>feign-okhttp</artifactId>
|
||||||
|
<version>${feign-ok.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.httpcomponents</groupId>
|
||||||
|
<artifactId>httpcore</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-test</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<spring-cloud.version>Camden.SR7</spring-cloud.version>
|
||||||
|
<feign-ok.version>8.18.0</feign-ok.version>
|
||||||
|
<!--
|
||||||
|
<spring-cloud.version>Hoxton.SR8</spring-cloud.version>
|
||||||
|
-->
|
||||||
|
<!--
|
||||||
|
<maven.compiler.source>8</maven.compiler.source>
|
||||||
|
<maven.compiler.target>8</maven.compiler.target>
|
||||||
|
-->
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
</project>
|
|
@ -0,0 +1,16 @@
|
||||||
|
package com.baeldung.cloud.netflix.feign;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
import org.springframework.cloud.netflix.feign.EnableFeignClients;
|
||||||
|
|
||||||
|
@SpringBootApplication
|
||||||
|
@EnableFeignClients
|
||||||
|
public class ExampleApplication {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(ExampleApplication.class, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
package com.baeldung.cloud.netflix.feign.client;
|
||||||
|
|
||||||
|
import com.baeldung.cloud.netflix.feign.config.ClientConfiguration;
|
||||||
|
import com.baeldung.cloud.netflix.feign.hystrix.JSONPlaceHolderFallback;
|
||||||
|
import com.baeldung.cloud.netflix.feign.model.Post;
|
||||||
|
import org.springframework.cloud.netflix.feign.FeignClient;
|
||||||
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMethod;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@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);
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
package com.baeldung.cloud.netflix.feign.config;
|
||||||
|
|
||||||
|
import feign.Logger;
|
||||||
|
import feign.RequestInterceptor;
|
||||||
|
import feign.codec.ErrorDecoder;
|
||||||
|
import feign.okhttp.OkHttpClient;
|
||||||
|
|
||||||
|
import org.apache.http.entity.ContentType;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
public class ClientConfiguration {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public Logger.Level feignLoggerLevel() {
|
||||||
|
return Logger.Level.FULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public ErrorDecoder errorDecoder() {
|
||||||
|
return new ErrorDecoder.Default();
|
||||||
|
}
|
||||||
|
|
||||||
|
@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());
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
package com.baeldung.cloud.netflix.feign.config;
|
||||||
|
|
||||||
|
import com.baeldung.cloud.netflix.feign.exception.BadRequestException;
|
||||||
|
import com.baeldung.cloud.netflix.feign.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();
|
||||||
|
default:
|
||||||
|
return new Exception("Generic error");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
package com.baeldung.cloud.netflix.feign.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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
package com.baeldung.cloud.netflix.feign.exception;
|
||||||
|
|
||||||
|
public class NotFoundException extends Exception {
|
||||||
|
|
||||||
|
public NotFoundException() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public NotFoundException(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public NotFoundException(Throwable cause) {
|
||||||
|
super(cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "NotFoundException: "+getMessage();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
package com.baeldung.cloud.netflix.feign.hystrix;
|
||||||
|
|
||||||
|
import com.baeldung.cloud.netflix.feign.client.JSONPlaceHolderClient;
|
||||||
|
import com.baeldung.cloud.netflix.feign.model.Post;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class JSONPlaceHolderFallback implements JSONPlaceHolderClient {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Post> getPosts() {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Post getPostById(Long postId) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
package com.baeldung.cloud.netflix.feign.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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
package com.baeldung.cloud.netflix.feign.service;
|
||||||
|
|
||||||
|
import com.baeldung.cloud.netflix.feign.model.Post;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public interface JSONPlaceHolderService {
|
||||||
|
|
||||||
|
List<Post> getPosts();
|
||||||
|
|
||||||
|
Post getPostById(Long id);
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
package com.baeldung.cloud.netflix.feign.service.impl;
|
||||||
|
|
||||||
|
import com.baeldung.cloud.netflix.feign.client.JSONPlaceHolderClient;
|
||||||
|
import com.baeldung.cloud.netflix.feign.model.Post;
|
||||||
|
import com.baeldung.cloud.netflix.feign.service.JSONPlaceHolderService;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
spring.application.name=netflix-feign
|
||||||
|
logging.level.com.baeldung.cloud.netflix.feign.client=DEBUG
|
||||||
|
feign.hystrix.enabled=true
|
|
@ -0,0 +1,21 @@
|
||||||
|
package com.baeldung.cloud.netflix.feign;
|
||||||
|
|
||||||
|
import com.baeldung.cloud.netflix.feign.config.ClientConfiguration;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
import org.springframework.test.context.ContextConfiguration;
|
||||||
|
import org.springframework.test.context.junit4.SpringRunner;
|
||||||
|
|
||||||
|
@RunWith(SpringRunner.class)
|
||||||
|
@SpringBootTest
|
||||||
|
@EnableAutoConfiguration
|
||||||
|
@ContextConfiguration(classes = { ClientConfiguration.class })
|
||||||
|
public class ExampleTestApplication {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenSpringContextIsBootstrapped_thenNoExceptions() {
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
package com.baeldung.cloud.netflix.feign;
|
||||||
|
|
||||||
|
import com.baeldung.cloud.netflix.feign.model.Post;
|
||||||
|
import com.baeldung.cloud.netflix.feign.service.JSONPlaceHolderService;
|
||||||
|
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 java.util.List;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertNotNull;
|
||||||
|
|
||||||
|
@RunWith(SpringRunner.class)
|
||||||
|
@SpringBootTest
|
||||||
|
public class NetflixFeignUnitTest {
|
||||||
|
|
||||||
|
@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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue