Skip to content

Commit ecfcc50

Browse files
committed
Kubernetes and Spring cloud gateway added
1 parent 29aa06d commit ecfcc50

File tree

23 files changed

+234
-278
lines changed

23 files changed

+234
-278
lines changed

.idea/compiler.xml

+2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/encodings.xml

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/workspace.xml

+49-189
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docker-compose-base.yml renamed to docker/docker-compose-base.yml

+13-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
services:
22
course:
3-
build: microservices/course-service
3+
build: ../microservices/course-service
44
mem_limit: 512m
55
environment:
66
- SPRING_PROFILES_ACTIVE=docker
@@ -11,7 +11,7 @@ services:
1111
# condition: service_healthy
1212

1313
review:
14-
build: microservices/review-service
14+
build: ../microservices/review-service
1515
mem_limit: 512m
1616
environment:
1717
- SPRING_PROFILES_ACTIVE=docker
@@ -22,7 +22,7 @@ services:
2222
# condition: service_healthy
2323

2424
course-composite:
25-
build: microservices/course-composite-service
25+
build: ../microservices/course-composite-service
2626
mem_limit: 512m
2727
ports:
2828
- "8080:8080"
@@ -31,6 +31,16 @@ services:
3131
networks:
3232
- shared-network
3333

34+
gateway-service:
35+
build: ../spring-cloud/gateway-service
36+
mem_limit: 512m
37+
ports:
38+
- "9000:9000"
39+
environment:
40+
- SPRING_PROFILES_ACTIVE=docker
41+
networks:
42+
- shared-network
43+
3444
networks:
3545
shared-network:
3646
name: shared-network

docker-compose-infra.yml renamed to docker/docker-compose-infra.yml

+2
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ services:
2626
timeout: 5s
2727
retries: 5
2828
start_period: 30s
29+
volumes:
30+
- ./postgresql/init.sql:/docker-entrypoint-initdb.d/init.sql
2931
networks:
3032
- shared-network
3133
networks:

docker/postgresql/init.sql

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
DO $$
2+
BEGIN
3+
IF NOT EXISTS (SELECT FROM pg_database WHERE datname = 'course_db') THEN
4+
CREATE DATABASE course_db;
5+
END IF;
6+
END $$;

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

-5
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,6 @@
1010
@ComponentScan({"io.javatab"})
1111
public class CourseCompositeServiceApplication {
1212

13-
@Bean
14-
RestTemplate restTemplate() {
15-
return new RestTemplate();
16-
}
17-
1813
public static void main(String[] args) {
1914
SpringApplication.run(CourseCompositeServiceApplication.class, args);
2015
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package io.javatab.microservices.composite.course.web;
2+
3+
import lombok.Data;
4+
5+
@Data
6+
public class Course {
7+
private Long id;
8+
private String title;
9+
private String author;
10+
private Double price;
11+
private String publisher;
12+
}
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
package io.javatab.microservices.composite.course.web;
22

33

4+
import lombok.Builder;
5+
import lombok.Data;
6+
47
import java.util.List;
58

9+
@Data
10+
@Builder
611
public class CourseAggregate {
7-
private Long id;
8-
private String title;
9-
private String author;
10-
private Double price;
11-
private String publisher;
12+
private Course course;
1213
private List<Review> reviews;
1314
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package io.javatab.microservices.composite.course.web;
2+
3+
import io.javatab.util.http.NetworkUtility;
4+
import org.slf4j.Logger;
5+
import org.slf4j.LoggerFactory;
6+
import org.springframework.http.ResponseEntity;
7+
import org.springframework.web.bind.annotation.GetMapping;
8+
import org.springframework.web.bind.annotation.PathVariable;
9+
import org.springframework.web.bind.annotation.RequestMapping;
10+
import org.springframework.web.bind.annotation.RestController;
11+
import reactor.core.publisher.Mono;
12+
13+
import java.util.List;
14+
15+
@RestController
16+
@RequestMapping("/api/course-aggregate")
17+
public class CourseAggregateController {
18+
19+
private static final Logger logger = LoggerFactory.getLogger(CourseAggregateController.class);
20+
21+
22+
private final CourseCompositeIntegration integration;
23+
private final NetworkUtility utility;
24+
25+
public CourseAggregateController(CourseCompositeIntegration integration, NetworkUtility utility) {
26+
this.integration = integration;
27+
this.utility = utility;
28+
}
29+
30+
@GetMapping("/{id}/with-details")
31+
public Mono<CourseAggregate> getCourses(@PathVariable Long id) {
32+
logger.info("Fetching course and review details for course id : {}", id);
33+
return integration.getCourseDetails(id);
34+
}
35+
}

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

+26-25
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,10 @@
33
import org.slf4j.Logger;
44
import org.slf4j.LoggerFactory;
55
import org.springframework.beans.factory.annotation.Value;
6-
import org.springframework.core.ParameterizedTypeReference;
7-
import org.springframework.http.HttpMethod;
8-
import org.springframework.http.ResponseEntity;
96
import org.springframework.stereotype.Service;
107
import org.springframework.web.client.RestTemplate;
8+
import org.springframework.web.reactive.function.client.WebClient;
9+
import reactor.core.publisher.Mono;
1110

1211
import java.util.List;
1312

@@ -18,37 +17,39 @@ public class CourseCompositeIntegration {
1817

1918
private final String courseServiceUrl;
2019
private final String reviewServiceUrl;
21-
private final RestTemplate restTemplate;
20+
private final WebClient webClient;
2221

2322
public CourseCompositeIntegration(
2423
@Value("${app.course-service.host}") String courseServiceHost,
2524
@Value("${app.course-service.port}") String courseServicePort,
2625
@Value("${app.review-service.host}") String reviewServiceHost,
27-
@Value("${app.review-service.port}") String reviewServicePort, RestTemplate restTemplate
26+
@Value("${app.review-service.port}") String reviewServicePort,
27+
WebClient.Builder webClient
2828
) {
29-
this.restTemplate = restTemplate;
29+
this.webClient = webClient.build();
3030
courseServiceUrl = "http://" + courseServiceHost + ":" + courseServicePort;
3131
reviewServiceUrl = "http://" + reviewServiceHost + ":" + reviewServicePort;
3232
}
3333

34-
public String getCourse() {
35-
return restTemplate.getForObject(courseServiceUrl, String.class);
36-
}
37-
38-
public String getReview() {
39-
return restTemplate.getForObject(reviewServiceUrl, String.class);
40-
}
41-
42-
public List<Review> getReviewsByCourseId(Long courseId) {
43-
String url = reviewServiceUrl + "/api/reviews?courseId=" + courseId;
44-
45-
ResponseEntity<List<Review>> response = restTemplate.exchange(
46-
url,
47-
HttpMethod.GET,
48-
null,
49-
new ParameterizedTypeReference<>() {} // Helps deserialize JSON List
50-
);
51-
52-
return response.getBody(); // Returns list of reviews
34+
public Mono<CourseAggregate> getCourseDetails(Long id) {
35+
String courseUrl = courseServiceUrl + "/api/courses/" + id;
36+
String reviewUrl = reviewServiceUrl + "/api/reviews?course=" + id;
37+
Mono<Course> courseMono = webClient.get()
38+
.uri(courseUrl)
39+
.retrieve()
40+
.bodyToMono(Course.class);
41+
42+
Mono<List<Review>> reviewsMono = webClient.get()
43+
.uri(reviewUrl)
44+
.retrieve()
45+
.bodyToFlux(Review.class)
46+
.collectList();
47+
48+
return Mono.zip(courseMono, reviewsMono)
49+
.map(tuple -> CourseAggregate
50+
.builder()
51+
.course(tuple.getT1())
52+
.reviews(tuple.getT2())
53+
.build());
5354
}
5455
}

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

-32
This file was deleted.

microservices/course-service/Tiltfile

-12
This file was deleted.

microservices/course-service/pom.xml

+5
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,11 @@
6969
<scope>compile</scope>
7070
</dependency>
7171

72+
<dependency>
73+
<groupId>org.springframework.boot</groupId>
74+
<artifactId>spring-boot-starter-actuator</artifactId>
75+
</dependency>
76+
7277
<dependency>
7378
<groupId>org.springframework.boot</groupId>
7479
<artifactId>spring-boot-starter-test</artifactId>

microservices/course-service/src/main/java/io/javatab/microservices/core/course/domain/CourseRepository.java

+2
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,10 @@
88
public interface CourseRepository extends CrudRepository<Course,Long> {
99

1010
Optional<Course> findByTitle(String title);
11+
Optional<Course> findById(Long id);
1112
boolean existsByTitle(String title);
1213

14+
1315
@Transactional
1416
void deleteById(Long id);
1517

microservices/course-service/src/main/java/io/javatab/microservices/core/course/domain/CourseService.java

+5
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,11 @@ public Course viewCourseDetails(String title) {
2020
.orElseThrow(() -> new CourseNotFoundException(title));
2121
}
2222

23+
public Course viewCourseDetailsById(Long id) {
24+
return courseRepository.findById(id)
25+
.orElseThrow(() -> new CourseNotFoundException(String.valueOf(id)));
26+
}
27+
2328
public Course addCourse(Course course) {
2429
if (courseRepository.existsByTitle(course.getTitle())) {
2530
throw new CourseAlreadyExitsException(course.getTitle());

microservices/course-service/src/main/java/io/javatab/microservices/core/course/web/CourseController.java

+11-1
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,17 @@
44
import io.javatab.microservices.core.course.domain.CourseService;
55
import io.javatab.util.http.NetworkUtility;
66
import jakarta.validation.Valid;
7+
import org.slf4j.Logger;
8+
import org.slf4j.LoggerFactory;
79
import org.springframework.http.HttpStatus;
810
import org.springframework.web.bind.annotation.*;
911

1012
@RestController()
1113
@RequestMapping("/api/courses")
1214
public class CourseController {
1315

16+
private final Logger logger = LoggerFactory.getLogger(CourseController.class);
17+
1418
private final NetworkUtility utility;
1519
private CourseService courseService;
1620

@@ -21,18 +25,24 @@ public CourseController(NetworkUtility utility, CourseService courseService) {
2125

2226
@GetMapping
2327
public Iterable<Course> get() {
28+
logger.info("Fetching courses");
2429
return courseService.viewCourses();
2530
}
2631

2732
/*
2833
* Make sure application is running in localhost mode to test and not in docker
2934
* http GET ':9001/api/courses/Microservices with Spring Boot'
3035
* */
31-
@GetMapping("/{title}")
36+
@GetMapping("/title/{title}")
3237
public Course getByTitle(@PathVariable String title) {
3338
return courseService.viewCourseDetails(title);
3439
}
3540

41+
@GetMapping("/{id}")
42+
public Course getById(@PathVariable Long id) {
43+
return courseService.viewCourseDetailsById(id);
44+
}
45+
3646
/*
3747
* http POST :9001/api/courses title="Microservices with Spring Boot" author="John Doe" price:=29.79 publisher="Manning"
3848
* */

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

+15-5
Original file line numberDiff line numberDiff line change
@@ -19,17 +19,27 @@ spring:
1919
# flyway: # Only in dev env. Never have them in prod
2020
# validate-on-migrate: false
2121
# outOfOrder: true
22+
logging:
23+
level:
24+
org.springframework: INFO
25+
com.javatab: DEBUG
26+
pattern:
27+
console: "%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n"
28+
management:
29+
endpoints:
30+
web:
31+
exposure:
32+
include: "*"
33+
endpoint:
34+
health:
35+
show-details: always
36+
2237
---
2338
spring:
2439
config:
2540
activate:
2641
on-profile: docker
2742
datasource:
28-
username: user
29-
password: pwd
3043
url: jdbc:postgresql://postgres:5432/course_db
31-
hikari:
32-
connection-timeout: 2000
33-
maximum-pool-size: 5 #https://github.com/brettwooldridge/HikariCP/wiki/About-Pool-Sizing
3444
server:
3545
port: 8080

0 commit comments

Comments
 (0)