New code for article BAEL-2460. Added maven module spring-cloud-kubernetes-project

This commit is contained in:
caroline 2019-02-23 22:49:32 +01:00
parent fe289003fa
commit 928a23494d
17 changed files with 594 additions and 0 deletions

View File

@ -0,0 +1,12 @@
# requires Docker version 17.05.0-ce-rc1, build 2878a85
FROM maven:3.5-jdk-8 as BUILDAGENCY
COPY src /usr/src/myapp/src
COPY pom.xml /usr/src/myapp
RUN mvn -f /usr/src/myapp/pom.xml clean package -DskipTests
FROM openjdk:alpine
COPY --from=BUILDAGENCY /usr/src/myapp/target/*.jar /maven/
CMD java $JAVA_OPTS -jar maven/*.jar

View File

@ -0,0 +1,71 @@
<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>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.6.RELEASE</version>
</parent>
<artifactId>client-service</artifactId>
<groupId>com.baeldung.spring.cloud</groupId>
<version>1.0-SNAPSHOT</version>
<properties>
<java.version>1.8</java.version>
<spring-boot.version>2.0.1.RELEASE</spring-boot.version>
<spring-cloud-dependencies.version>Finchley.SR2</spring-cloud-dependencies.version>
<spring.cloud.k8s.version>0.3.0.RELEASE</spring.cloud.k8s.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud-dependencies.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-kubernetes-dependencies</artifactId>
<version>${spring.cloud.k8s.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-kubernetes-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-kubernetes-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,96 @@
package com.baeldung.spring.cloud.kubernetes.services.department;
import com.baeldung.spring.cloud.kubernetes.services.client.config.ClientConfig;
import com.baeldung.spring.cloud.kubernetes.services.client.service.TravelAgencyClientService;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.web.client.RestTemplate;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.List;
import java.util.Map;
@SpringBootApplication
@EnableDiscoveryClient
@EnableCircuitBreaker
public class ClientApplication implements CommandLineRunner {
private static final Log log = LogFactory.getLog(ClientApplication.class);
private static final String FIND_TRAVEL_DEALS_TASK = "Find new travel deals";
@Autowired
private DiscoveryClient discoveryClient;
@Autowired
private TravelAgencyClientService travelAgencyClient;
@Autowired
private ClientConfig clientConfig;
private String task = FIND_TRAVEL_DEALS_TASK;
@Bean
private RestTemplate restTemplate() {
return new RestTemplate();
}
@Value("${spring.application.name}")
private String appName;
public static void main(String[] args) {
SpringApplication.run(ClientApplication.class, args);
}
@Override
public void run(String... args) {
log.info("Client (" + appName + ":" + clientConfig.getType() + ")Started! ");
}
/*
* Every 10 seconds look for new deals
*/
@Scheduled(fixedRate = 10000)
public void doSomeWork() throws UnknownHostException {
if (task.equals(FIND_TRAVEL_DEALS_TASK)) {
task = findNewDeals();
if (task.equals(FIND_TRAVEL_DEALS_TASK)) {
log.info("NO DEAL FOUND, I will keep looking for one ");
}
}
log.info(">>> Working on " + task);
}
private String findNewDeals() throws UnknownHostException {
List<String> services = this.discoveryClient.getServices();
for (String service : services) {
List<ServiceInstance> instances = this.discoveryClient.getInstances(service);
for (ServiceInstance se : instances) {
Map<String, String> metadata = se.getMetadata();
String type = metadata.get("type");
if ("deal".equals(type)) {
String from = appName + "@" + InetAddress.getLocalHost().getHostName();
String url = "http://" + se.getServiceId();
return travelAgencyClient.requestDeals(url, from);
}
}
}
return FIND_TRAVEL_DEALS_TASK;
}
}

View File

@ -0,0 +1,19 @@
package com.baeldung.spring.cloud.kubernetes.services.client.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
@Configuration
@ConfigurationProperties(prefix = "client")
public class ClientConfig {
private String type = "generic-client";
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}

View File

@ -0,0 +1,43 @@
package com.baeldung.spring.cloud.kubernetes.services.client.controller;
import java.io.UnsupportedEncodingException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import com.baeldung.spring.cloud.kubernetes.services.client.config.ClientConfig;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import static org.springframework.web.bind.annotation.RequestMethod.GET;
@RestController
@RefreshScope
public class ClientController {
private static final Log log = LogFactory.getLog(ClientController.class);
private enum ClientTravelType {
BUSINESS,
STUDENT,
COUPLE,
FRIENDS,
SINGLE,
FAMILY;
}
@Autowired
private ClientConfig clientConfig;
@RequestMapping(method = GET)
public String get() throws UnknownHostException, UnsupportedEncodingException {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("Host: ").append(InetAddress.getLocalHost().getHostName()).append("<br/>");
stringBuilder.append("Client Type: ").append(clientConfig.getType()).append("<br/>");
stringBuilder.append("IP: ").append(InetAddress.getLocalHost().getHostAddress()).append("<br/>");
return stringBuilder.toString();
}
}

View File

@ -0,0 +1,45 @@
package com.baeldung.spring.cloud.kubernetes.services.client.service;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
@Service
public class TravelAgencyClientService {
private final RestTemplate restTemplate;
private static final Log log = LogFactory.getLog(TravelAgencyClientService.class);
public static final String FIND_NEW_TRAVEL_DEALS = "find new travel deals";
public TravelAgencyClientService(RestTemplate restTemplate) {
this.restTemplate = restTemplate;
}
@HystrixCommand(fallbackMethod = "getFallbackName", commandProperties = {
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "5000")
})
public String requestDeals(String to,
String from) {
String url = String.format("%s/deals/%s",
to,
from);
log.info("--- Requesting travel deals to travel agency " + url);
return restTemplate.getForObject(url, String.class);
}
private String getFallbackName(String to,
String from) {
log.error("--- This travel agency (" + to + ") not available now, please come back later (Fallback) client:" + from);
return FIND_NEW_TRAVEL_DEALS;
}
}

View File

@ -0,0 +1,6 @@
spring:
application:
name: client-service
cloud:
config:
uri: http://localhost:8088

View File

@ -0,0 +1,12 @@
# requires Docker version 17.05.0-ce-rc1, build 2878a85
FROM maven:3.5-jdk-8 as BUILDAGENCY
COPY src /usr/src/myapp/src
COPY pom.xml /usr/src/myapp
RUN mvn -f /usr/src/myapp/pom.xml clean package -DskipTests
FROM openjdk:alpine
COPY --from=BUILDAGENCY /usr/src/myapp/target/*.jar /maven/
CMD java $JAVA_OPTS -jar maven/*.jar

View File

@ -0,0 +1,76 @@
<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>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.6.RELEASE</version>
</parent>
<artifactId>gateway-service</artifactId>
<groupId>com.baeldung.spring.cloud</groupId>
<version>1.0-SNAPSHOT</version>
<properties>
<java.version>1.8</java.version>
<spring-boot.version>2.0.1.RELEASE</spring-boot.version>
<spring-cloud-dependencies.version>Finchley.SR2</spring-cloud-dependencies.version>
<spring.cloud.k8s.version>0.3.0.RELEASE</spring.cloud.k8s.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud-dependencies.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-kubernetes-dependencies</artifactId>
<version>${spring.cloud.k8s.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-kubernetes-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-kubernetes-ribbon</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,44 @@
package com.baeldung.spring.cloud.kubernetes.services.gateway;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.gateway.discovery.DiscoveryClientRouteDefinitionLocator;
import org.springframework.cloud.gateway.discovery.DiscoveryLocatorProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.web.client.RestTemplate;
@EnableScheduling
@EnableDiscoveryClient
@SpringBootApplication
public class GatewayApplication {
private static final Log log = LogFactory.getLog(GatewayApplication.class);
@Autowired
private DiscoveryClient discoveryClient;
@Bean
public DiscoveryClientRouteDefinitionLocator discoveryClientRouteLocator(DiscoveryClient discoveryClient,
DiscoveryLocatorProperties properties) {
return new DiscoveryClientRouteDefinitionLocator(discoveryClient,
properties);
}
public static void main(String[] args) {
SpringApplication.run(GatewayApplication.class,
args);
}
@LoadBalanced
@Bean
RestTemplate restTemplate() {
return new RestTemplate();
}
}

View File

@ -0,0 +1,6 @@
spring:
application:
name: gateway-service
cloud:
config:
uri: http://localhost:8088

View File

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
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.spring.cloud</groupId>
<artifactId>spring-cloud-kubernetes-project</artifactId>
<version>1.0.0-SNAPSHOT</version>
<name>spring-cloud-kubernetes-project</name>
<description>Spring Cloud Kubernetes</description>
<packaging>pom</packaging>
<modules>
<module>travel-agency-service</module>
<module>client-service</module>
<module>gateway-service</module>
</modules>
<parent>
<groupId>com.baeldung.spring.cloud</groupId>
<artifactId>spring-cloud</artifactId>
<version>1.0.0-SNAPSHOT</version>
<relativePath>..</relativePath>
</parent>
</project>

View File

@ -0,0 +1,12 @@
# requires Docker version 17.05.0-ce-rc1, build 2878a85
FROM maven:3.5-jdk-8 as BUILDAGENCY
COPY src /usr/src/myapp/src
COPY pom.xml /usr/src/myapp
RUN mvn -f /usr/src/myapp/pom.xml clean package -DskipTests
FROM openjdk:alpine
COPY --from=BUILDAGENCY /usr/src/myapp/target/*.jar /maven/
CMD java $JAVA_OPTS -jar maven/*.jar

View File

@ -0,0 +1,59 @@
<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>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.6.RELEASE</version>
</parent>
<artifactId>travel-agency-service</artifactId>
<groupId>com.baeldung.spring.cloud</groupId>
<version>1.0-SNAPSHOT</version>
<properties>
<java.version>1.8</java.version>
<spring-boot.version>2.0.1.RELEASE</spring-boot.version>
<spring-cloud-dependencies.version>Finchley.SR2</spring-cloud-dependencies.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud-dependencies.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-actuator-autoconfigure</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,24 @@
package com.baeldung.spring.cloud.kubernetes.services.department;
import com.baeldung.spring.cloud.kubernetes.services.travelagency.controller.TravelAgencyController;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class TravelAgencyApplication implements CommandLineRunner {
private static final Log log = LogFactory.getLog(TravelAgencyController.class);
public static void main(String[] args) {
SpringApplication.run(TravelAgencyApplication.class, args);
}
@Override
public void run(String... args) throws Exception {
log.info("Travel Agency Started! ");
}
}

View File

@ -0,0 +1,36 @@
package com.baeldung.spring.cloud.kubernetes.services.travelagency.controller;
import org.springframework.web.bind.annotation.*;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Random;
import static org.springframework.web.bind.annotation.RequestMethod.GET;
import static org.springframework.web.bind.annotation.RequestMethod.POST;
@RestController
public class TravelAgencyController {
private String[] deals = {"London - Paris : 25 Euro", "London - Frankfurt : 25 Euro"};
private static final Log log = LogFactory.getLog(TravelAgencyController.class);
@RequestMapping(method = POST, path = "/deals/{client}")
public String deals(@PathVariable("client") String client) {
log.info("Client: " + client + " is requesting new deals!");
int randomDeal = new Random().nextInt(deals.length);
return deals[randomDeal];
}
@RequestMapping(method = GET, path = "/")
@ResponseBody
public String get() throws UnknownHostException {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("Host: ").append(InetAddress.getLocalHost().getHostName()).append("<br/>");
stringBuilder.append("IP: ").append(InetAddress.getLocalHost().getHostAddress()).append("<br/>");
stringBuilder.append("Type: ").append("Travel Agency").append("<br/>");
return stringBuilder.toString();
}
}

View File

@ -0,0 +1,6 @@
spring:
application:
name: travelagency-service
cloud:
config:
uri: http://localhost:8088