diff --git a/spring-cloud/pom.xml b/spring-cloud/pom.xml index 2349613def..455a5b876b 100644 --- a/spring-cloud/pom.xml +++ b/spring-cloud/pom.xml @@ -11,6 +11,7 @@ spring-cloud-eureka spring-cloud-hystrix spring-cloud-bootstrap + spring-cloud-ribbon-client pom diff --git a/spring-cloud/spring-cloud-ribbon-client/pom.xml b/spring-cloud/spring-cloud-ribbon-client/pom.xml new file mode 100644 index 0000000000..c597c5ab8e --- /dev/null +++ b/spring-cloud/spring-cloud-ribbon-client/pom.xml @@ -0,0 +1,79 @@ + + 4.0.0 + com.baeldung + spring-cloud-ribbon + 0.0.1-SNAPSHOT + jar + spring-cloud-ribbon-client + Introduction to Spring Cloud Rest Client with Netflix Ribbon + + + org.springframework.boot + spring-boot-starter-parent + 1.4.1.RELEASE + + + + + UTF-8 + 1.8 + + + + + org.springframework.cloud + spring-cloud-starter-ribbon + + + org.springframework.boot + spring-boot-starter-web + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + + org.springframework.cloud + spring-cloud-dependencies + Camden.SR1 + pom + import + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + + + spring-snapshots + Spring Snapshots + https://repo.spring.io/snapshot + + true + + + + spring-milestones + Spring Milestones + https://repo.spring.io/milestone + + false + + + + \ No newline at end of file diff --git a/spring-cloud/spring-cloud-ribbon-client/src/main/java/com/baeldung/spring/cloud/ribbon/client/RibbonConfiguration.java b/spring-cloud/spring-cloud-ribbon-client/src/main/java/com/baeldung/spring/cloud/ribbon/client/RibbonConfiguration.java new file mode 100644 index 0000000000..59998432ad --- /dev/null +++ b/spring-cloud/spring-cloud-ribbon-client/src/main/java/com/baeldung/spring/cloud/ribbon/client/RibbonConfiguration.java @@ -0,0 +1,28 @@ +package com.baeldung.spring.cloud.ribbon.client; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; + +import com.netflix.client.config.IClientConfig; +import com.netflix.loadbalancer.IPing; +import com.netflix.loadbalancer.IRule; +import com.netflix.loadbalancer.PingUrl; +import com.netflix.loadbalancer.WeightedResponseTimeRule; +import com.netflix.loadbalancer.AvailabilityFilteringRule; + +public class RibbonConfiguration { + + @Autowired + IClientConfig ribbonClientConfig; + + @Bean + public IPing ribbonPing(IClientConfig config) { + return new PingUrl(); + } + + @Bean + public IRule ribbonRule(IClientConfig config) { + return new WeightedResponseTimeRule(); + } + +} diff --git a/spring-cloud/spring-cloud-ribbon-client/src/main/java/com/baeldung/spring/cloud/ribbon/client/ServerLocationApp.java b/spring-cloud/spring-cloud-ribbon-client/src/main/java/com/baeldung/spring/cloud/ribbon/client/ServerLocationApp.java new file mode 100644 index 0000000000..6105e2c489 --- /dev/null +++ b/spring-cloud/spring-cloud-ribbon-client/src/main/java/com/baeldung/spring/cloud/ribbon/client/ServerLocationApp.java @@ -0,0 +1,36 @@ +package com.baeldung.spring.cloud.ribbon.client; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.client.loadbalancer.LoadBalanced; +import org.springframework.cloud.netflix.ribbon.RibbonClient; +import org.springframework.context.annotation.Bean; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.client.RestTemplate; + +@SpringBootApplication +@RestController +@RibbonClient(name = "ping-a-server", configuration = RibbonConfiguration.class) +public class ServerLocationApp { + + @LoadBalanced + @Bean + RestTemplate getRestTemplate() { + return new RestTemplate(); + } + + @Autowired + RestTemplate restTemplate; + + @RequestMapping("/server-location") + public String serverLocation() { + String servLoc = this.restTemplate.getForObject("http://ping-server/locaus", String.class); + return servLoc; + } + + public static void main(String[] args) { + SpringApplication.run(ServerLocationApp.class, args); + } +} diff --git a/spring-cloud/spring-cloud-ribbon-client/src/main/resources/application.yml b/spring-cloud/spring-cloud-ribbon-client/src/main/resources/application.yml new file mode 100644 index 0000000000..189a923c6c --- /dev/null +++ b/spring-cloud/spring-cloud-ribbon-client/src/main/resources/application.yml @@ -0,0 +1,13 @@ +spring: + application: + name: spring-cloud-ribbon + +server: + port: 8888 + +ping-server: + ribbon: + eureka: + enabled: false + listOfServers: localhost:9092,localhost:9999 + ServerListRefreshInterval: 15000 \ No newline at end of file diff --git a/spring-cloud/spring-cloud-ribbon-client/src/test/java/com/baeldung/spring/cloud/ribbon/client/ServerLocationAppTests.java b/spring-cloud/spring-cloud-ribbon-client/src/test/java/com/baeldung/spring/cloud/ribbon/client/ServerLocationAppTests.java new file mode 100644 index 0000000000..b3606537a2 --- /dev/null +++ b/spring-cloud/spring-cloud-ribbon-client/src/test/java/com/baeldung/spring/cloud/ribbon/client/ServerLocationAppTests.java @@ -0,0 +1,54 @@ +package com.baeldung.spring.cloud.ribbon.client; + +import static org.assertj.core.api.BDDAssertions.then; +import static org.junit.Assert.assertEquals; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.context.embedded.LocalServerPort; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.test.context.junit4.SpringRunner; + +@SuppressWarnings("unused") +@RunWith(SpringRunner.class) +@SpringBootTest(classes = ServerLocationApp.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +public class ServerLocationAppTests { + ConfigurableApplicationContext application2; + ConfigurableApplicationContext application3; + + @Before + public void startApps() { + this.application2 = startApp(9092); + this.application3 = startApp(9999); + } + + @After + public void closeApps() { + this.application2.close(); + this.application3.close(); + } + + @LocalServerPort + private int port; + + @Autowired + private TestRestTemplate testRestTemplate; + + @Test + public void loadBalancingServersTest() throws InterruptedException { + ResponseEntity response = this.testRestTemplate.getForEntity("http://localhost:" + this.port + "/server-location", String.class); + assertEquals(response.getBody(), "Australia"); + } + + private ConfigurableApplicationContext startApp(int port) { + return SpringApplication.run(TestConfig.class, "--server.port=" + port, "--spring.jmx.enabled=false"); + } +} diff --git a/spring-cloud/spring-cloud-ribbon-client/src/test/java/com/baeldung/spring/cloud/ribbon/client/TestConfig.java b/spring-cloud/spring-cloud-ribbon-client/src/test/java/com/baeldung/spring/cloud/ribbon/client/TestConfig.java new file mode 100644 index 0000000000..886b28a32e --- /dev/null +++ b/spring-cloud/spring-cloud-ribbon-client/src/test/java/com/baeldung/spring/cloud/ribbon/client/TestConfig.java @@ -0,0 +1,17 @@ +package com.baeldung.spring.cloud.ribbon.client; + +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@Configuration +@EnableAutoConfiguration +@RestController +public class TestConfig { + + @RequestMapping(value = "/locaus") + public String locationAUSDetails() { + return "Australia"; + } +}