Skip to content

Commit 935a827

Browse files
committed
Refactored eureka discovery to run in docker environment
1 parent b064d4d commit 935a827

File tree

9 files changed

+106
-63
lines changed

9 files changed

+106
-63
lines changed

docker/docker-compose.yml

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ services:
44
course:
55
build: ../microservices/course-service
66
image: javatab/course_service:v1
7-
container_name: course_service_v1
87
mem_limit: 512m
98
environment:
109
- SPRING_PROFILES_ACTIVE=docker
@@ -15,7 +14,6 @@ services:
1514
search:
1615
build: ../microservices/search-service
1716
image: javatab/search_service:v1
18-
container_name: search_service_v1
1917
mem_limit: 512m
2018
environment:
2119
- SPRING_PROFILES_ACTIVE=docker
@@ -26,7 +24,6 @@ services:
2624
student:
2725
build: ../microservices/student-service
2826
image: javatab/student_service:v1
29-
container_name: student_service_v1
3027
mem_limit: 512m
3128
environment:
3229
- SPRING_PROFILES_ACTIVE=docker
@@ -37,7 +34,6 @@ services:
3734
vote:
3835
build: ../microservices/vote-service
3936
image: javatab/vote_service:v1
40-
container_name: vote_service_v1
4137
mem_limit: 512m
4238
environment:
4339
- SPRING_PROFILES_ACTIVE=docker
@@ -48,7 +44,6 @@ services:
4844
course-composite:
4945
build: ../microservices/course-composite-service
5046
image: javatab/course_composite_service:v1
51-
container_name: course_composite_service_v1
5247
mem_limit: 512m
5348
ports:
5449
- "8080:8080" # Only this service will be exposed to outside containers so no port binding for above images
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,18 @@
11
package io.javatab.microservices.composite.course;
22

33
import io.javatab.microservices.composite.course.configuration.OpenApiConfigProperties;
4+
import org.slf4j.Logger;
5+
import org.slf4j.LoggerFactory;
46
import org.springframework.boot.SpringApplication;
57
import org.springframework.boot.autoconfigure.SpringBootApplication;
68
import org.springframework.boot.context.properties.EnableConfigurationProperties;
79
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
810
import org.springframework.context.annotation.Bean;
911
import org.springframework.context.annotation.ComponentScan;
1012
import org.springframework.web.client.RestTemplate;
13+
import org.springframework.web.reactive.function.client.ExchangeFilterFunction;
1114
import org.springframework.web.reactive.function.client.WebClient;
15+
import reactor.core.publisher.Mono;
1216

1317
@SpringBootApplication
1418
@ComponentScan("io.javatab")
@@ -19,10 +23,4 @@ public static void main(String[] args) {
1923
SpringApplication.run(CourseCompositeServiceApplication.class, args);
2024
}
2125

22-
@Bean
23-
@LoadBalanced
24-
public WebClient.Builder loadBalancedWebClientBuilder() {
25-
return WebClient.builder();
26-
}
27-
2826
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package io.javatab.microservices.composite.course.configuration;
2+
3+
import io.netty.resolver.DefaultAddressResolverGroup;
4+
import org.slf4j.Logger;
5+
import org.slf4j.LoggerFactory;
6+
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
7+
import org.springframework.context.annotation.Bean;
8+
import org.springframework.context.annotation.Configuration;
9+
import org.springframework.http.client.reactive.ReactorClientHttpConnector;
10+
import org.springframework.web.reactive.function.client.ExchangeFilterFunction;
11+
import org.springframework.web.reactive.function.client.WebClient;
12+
import reactor.core.publisher.Mono;
13+
import reactor.netty.http.client.HttpClient;
14+
15+
@Configuration
16+
public class WebClients {
17+
18+
private static final Logger logger = LoggerFactory.getLogger(WebClients.class);
19+
20+
@Bean
21+
@LoadBalanced
22+
public WebClient.Builder loadBalancedWebClientBuilder() {
23+
//HttpClient httpClient = HttpClient.create().resolver(DefaultAddressResolverGroup.INSTANCE);
24+
return WebClient.builder();
25+
//.filter(logRequest())
26+
//.clientConnector(new ReactorClientHttpConnector(httpClient))
27+
//.build();
28+
}
29+
30+
31+
private static ExchangeFilterFunction logRequest() {
32+
return ExchangeFilterFunction.ofRequestProcessor(clientRequest -> {
33+
logger.info("Request: {} {} {}", clientRequest.method(), clientRequest.url(), clientRequest.body());
34+
clientRequest.headers().forEach((name, values) -> values.forEach(value -> logger.info("{}={}", name, value)));
35+
return Mono.just(clientRequest);
36+
});
37+
}
38+
39+
}

microservices/course-composite-service/src/main/java/io/javatab/microservices/composite/course/service/CourseCompositeIntegration.java

Lines changed: 43 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,18 @@
77
import io.javatab.microservices.api.core.student.StudentService;
88
import io.javatab.microservices.api.core.vote.Vote;
99
import io.javatab.microservices.api.core.vote.VoteService;
10+
import io.javatab.microservices.api.exceptions.InvalidInputException;
11+
import io.javatab.microservices.api.exceptions.NotFoundException;
12+
import io.javatab.microservices.util.http.HttpErrorInfo;
1013
import org.slf4j.Logger;
1114
import org.slf4j.LoggerFactory;
12-
import org.springframework.beans.factory.annotation.Value;
1315
import org.springframework.stereotype.Component;
14-
import org.springframework.web.client.RestTemplate;
1516
import org.springframework.web.reactive.function.client.WebClient;
1617
import org.springframework.web.reactive.function.client.WebClientResponseException;
1718
import reactor.core.publisher.Mono;
1819

20+
import java.io.IOException;
21+
1922
import static java.util.logging.Level.FINE;
2023

2124
@Component
@@ -31,31 +34,64 @@ public class CourseCompositeIntegration implements CourseService, StudentService
3134
private static final String VOTE_SERVICE_URL = "http://vote";
3235

3336
public CourseCompositeIntegration(
34-
WebClient.Builder webClientBuilder,
37+
WebClient.Builder webClient,
3538
ObjectMapper objectMapper) {
36-
this.webClient = webClientBuilder.build();
39+
this.webClient = webClient.build();
3740
this.objectMapper = objectMapper;
3841
}
3942

43+
private String getErrorMessage(WebClientResponseException ex) {
44+
try {
45+
return objectMapper.readValue(ex.getResponseBodyAsString(), HttpErrorInfo.class).getMessage();
46+
} catch (IOException ioex) {
47+
return ex.getMessage();
48+
}
49+
}
50+
51+
private Throwable handleException(Throwable ex) {
52+
53+
if (!(ex instanceof WebClientResponseException)) {
54+
LOG.warn("Got a unexpected error: {}, will rethrow it", ex.toString());
55+
return ex;
56+
}
57+
58+
WebClientResponseException wcre = (WebClientResponseException)ex;
4059

60+
switch (wcre.getStatusCode()) {
61+
62+
case NOT_FOUND:
63+
return new NotFoundException(getErrorMessage(wcre));
64+
65+
case UNPROCESSABLE_ENTITY :
66+
return new InvalidInputException(getErrorMessage(wcre));
67+
68+
default:
69+
LOG.warn("Got an unexpected HTTP error: {}, will rethrow it", wcre.getStatusCode());
70+
LOG.warn("Error body: {}", wcre.getResponseBodyAsString());
71+
return ex;
72+
}
73+
}
4174
@Override
4275
public Mono<Course> getCourse(int courseId) {
4376
LOG.info("Fetching courses in Integration layer");
4477
var url = COURSE_SERVICE_URL + "/course/" + courseId;
45-
return webClient.get().uri(url).retrieve().bodyToMono(Course.class).log(LOG.getName(), FINE);
78+
return webClient.get().uri(url).retrieve().bodyToMono(Course.class).map(course -> {
79+
System.out.println("Course" + course);
80+
return new Course(1, "d", "f", "r", 2);
81+
}).log(LOG.getName(), FINE).onErrorMap(WebClientResponseException.class, this::handleException);
4682
}
4783

4884
@Override
4985
public Mono<Student> getStudent(String studentId) {
5086
LOG.info("Fetching students in Integration layer");
5187
var url = STUDENT_SERVICE_URL + "/student/" + studentId;
52-
return webClient.get().uri(url).retrieve().bodyToMono(Student.class).log(LOG.getName(), FINE);
88+
return webClient.get().uri(url).retrieve().bodyToMono(Student.class).log(LOG.getName(), FINE).onErrorMap(WebClientResponseException.class, this::handleException);
5389
}
5490

5591
@Override
5692
public Mono<Vote> getVote(int courseId) {
5793
LOG.info("Fetching votes in Integration layer");
5894
var url = VOTE_SERVICE_URL + "/vote/" + courseId;
59-
return webClient.get().uri(url).retrieve().bodyToMono(Vote.class).log(LOG.getName(), FINE);
95+
return webClient.get().uri(url).retrieve().bodyToMono(Vote.class).log(LOG.getName(), FINE).onErrorMap(WebClientResponseException.class, this::handleException);
6096
}
6197
}

microservices/course-composite-service/src/main/java/io/javatab/microservices/composite/course/service/CourseCompositeServiceImpl.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,9 @@ public CourseCompositeServiceImpl(final CourseCompositeIntegration integration,
2323
@Override
2424
public Mono<CourseAggregate> getCourse(int courseId) {
2525
// Call integration apis
26-
integration.getCourse(1);
27-
integration.getStudent("name");
28-
integration.getVote(1);
26+
integration.getCourse(1).subscribe(course -> System.out.println("Course " + course));
27+
integration.getStudent("name").subscribe(course -> System.out.println("student " + course));
28+
integration.getVote(1).subscribe(course -> System.out.println("vote " + course));
2929
return Mono.just(new CourseAggregate(1, 1, 3, 3,
3030
List.of(new Student(1, "Student Name", "email", "password"))));
3131
}

microservices/course-composite-service/src/main/resources/application.yml

Lines changed: 7 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,11 @@
11
server.port: 8016
22
spring.application.name: course-composite
3-
app:
4-
course-service:
5-
host: localhost
6-
port: 8012
7-
student-service:
8-
host: localhost
9-
port: 8013
10-
vote-service:
11-
host: localhost
12-
port: 8014
3+
4+
springdoc:
5+
swagger-ui.path: /openapi/swagger-ui.html
6+
api-docs.path: /openapi/v3/api-docs
7+
packagesToScan: io.javatab.microservices.composite.course
8+
pathsToMatch: /**
139

1410
open-api:
1511
version: 1.0.0
@@ -58,13 +54,6 @@ open-api:
5854
422 - An **Unprocessable Entity** error will be returned
5955
6056
61-
62-
springdoc:
63-
swagger-ui.path: /openapi/swagger-ui.html
64-
api-docs.path: /openapi/v3/api-docs
65-
packagesToScan: io.javatab.microservices.composite.course
66-
pathsToMatch: /**
67-
6857
app.eureka-server: localhost
6958

7059
eureka:
@@ -78,18 +67,5 @@ eureka:
7867
leaseExpirationDurationInSeconds: 5
7968
---
8069
spring.config.activate.on-profile: docker
81-
8270
server.port: 8080
83-
84-
eureka.client.serviceUrl.defaultZone: http://eureka:8761/eureka/
85-
86-
app:
87-
course-service:
88-
host: course
89-
port: 8080
90-
student-service:
91-
host: student
92-
port: 8080
93-
vote-service:
94-
host: vote
95-
port: 8080
71+
app.eureka-server: eureka

microservices/course-service/src/main/resources/application.yml

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
server.port: 8012
2+
spring.application.name: course
23
logging:
34
level:
45
root: INFO
@@ -15,11 +16,9 @@ eureka:
1516
instance:
1617
leaseRenewalIntervalInSeconds: 5
1718
leaseExpirationDurationInSeconds: 5
18-
spring:
19-
application:
20-
name: course
19+
2120
---
2221
spring.config.activate.on-profile: docker
2322
server.port: 8080
24-
eureka.client.serviceUrl.defaultZone: http://eureka:8761/eureka/
23+
app.eureka-server: eureka
2524
spring.data.mongodb.host: mongodb
Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
server.port: 8015
2+
spring.application.name: search
23
app.eureka-server: localhost
34

45
eureka:
@@ -10,12 +11,10 @@ eureka:
1011
instance:
1112
leaseRenewalIntervalInSeconds: 5
1213
leaseExpirationDurationInSeconds: 5
13-
spring:
14-
application:
15-
name: search
14+
1615
---
1716
spring.config.activate.on-profile: docker
1817
server.port: 8080
19-
eureka.client.serviceUrl.defaultZone: http://eureka:8761/eureka/
18+
app.eureka-server: eureka
2019
spring.elasticsearch:
2120
uris: http://elasticsearch:9200

microservices/student-service/src/main/resources/application.yml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
server.port: 8013
22
spring:
3+
application:
4+
name: student
35
datasource:
46
driver-class-name: org.postgresql.Driver
57
username: user
@@ -9,8 +11,7 @@ spring:
911
database-platform: org.hibernate.dialect.PostgreSQLDialect
1012
hibernate:
1113
ddl-auto: update
12-
application:
13-
name: student
14+
1415

1516
app.eureka-server: localhost
1617

@@ -27,5 +28,5 @@ eureka:
2728
---
2829
spring.config.activate.on-profile: docker
2930
server.port: 8080
30-
eureka.client.serviceUrl.defaultZone: http://eureka:8761/eureka/
31+
app.eureka-server: eureka
3132
spring.datasource.url: jdbc:postgresql://postgres:5432/test

0 commit comments

Comments
 (0)