Skip to content

Commit 3d31053

Browse files
committed
student update
1 parent ff3de9d commit 3d31053

File tree

9 files changed

+278
-11
lines changed

9 files changed

+278
-11
lines changed
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package com.prs.services.student.client;
2+
3+
import org.springframework.beans.factory.annotation.Autowired;
4+
import org.springframework.beans.factory.annotation.Qualifier;
5+
import org.springframework.http.HttpHeaders;
6+
import org.springframework.http.MediaType;
7+
import org.springframework.stereotype.Component;
8+
9+
import com.prs.services.student.model.College;
10+
11+
import reactor.core.publisher.Mono;
12+
13+
@Component
14+
public class CollegeReactiveClient {
15+
16+
@Autowired
17+
@Qualifier("collegeExternalClient")
18+
private ExternalClient externalClient;
19+
20+
public Mono<College> findByCollege(Long collegeId) {
21+
return externalClient.getForMono("/get-by/" + collegeId, getDefaultHeaders(), College.class);
22+
}
23+
24+
private HttpHeaders getDefaultHeaders() {
25+
HttpHeaders h = new HttpHeaders();
26+
h.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE);
27+
return h;
28+
}
29+
30+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package com.prs.services.student.client;
2+
3+
import org.springframework.beans.factory.annotation.Autowired;
4+
import org.springframework.beans.factory.annotation.Qualifier;
5+
import org.springframework.http.HttpHeaders;
6+
import org.springframework.http.MediaType;
7+
import org.springframework.stereotype.Component;
8+
9+
import com.prs.services.student.model.Department;
10+
11+
import reactor.core.publisher.Mono;
12+
13+
@Component
14+
public class DepartmentReactiveClient {
15+
16+
@Autowired
17+
@Qualifier("departmentExternalClient")
18+
private ExternalClient externalClient;
19+
20+
public Mono<Department> findByDepartment(Long departmentId) {
21+
return externalClient.getForMono("/get-by/" + departmentId, getDefaultHeaders(), Department.class);
22+
}
23+
24+
private HttpHeaders getDefaultHeaders() {
25+
HttpHeaders h = new HttpHeaders();
26+
h.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE);
27+
return h;
28+
}
29+
30+
31+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package com.prs.services.student.client;
2+
3+
import java.util.Map;
4+
import java.util.function.Consumer;
5+
6+
import org.springframework.http.HttpHeaders;
7+
8+
import reactor.core.publisher.Flux;
9+
import reactor.core.publisher.Mono;
10+
11+
public interface ExternalClient {
12+
public <T> Mono<T> getForMono(String path, HttpHeaders httpHeaders, Class<T> resClazz);
13+
14+
public <T> Flux<T> getForFlux(String path, HttpHeaders httpHeaders, Class<T> resClazz);
15+
16+
public <T, U> Mono<U> postForMono(String path, HttpHeaders httpHeaders, Class<U> resClazz, T reqBody,
17+
Class<T> reqClazz);
18+
19+
public <T, U> Flux<U> postForFlux(String path, HttpHeaders httpHeaders, T reqBody, Class<T> reqClazz,
20+
Class<U> resClazz);
21+
22+
default Consumer<HttpHeaders> headerConsumer(HttpHeaders httpHeaders) {
23+
return h -> h.putAll(httpHeaders);
24+
}
25+
26+
default Consumer<HttpHeaders> headerConsumer(Map<String, String> httpHeaders) {
27+
return h -> httpHeaders.forEach((k, v) -> h.add(k, v));
28+
}
29+
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
package com.prs.services.student.client;
2+
3+
import javax.annotation.PostConstruct;
4+
5+
import org.apache.logging.log4j.LogManager;
6+
import org.apache.logging.log4j.Logger;
7+
import org.springframework.http.HttpHeaders;
8+
import org.springframework.web.reactive.function.client.WebClient;
9+
import org.springframework.web.reactive.function.client.WebClient.RequestHeadersSpec;
10+
11+
import lombok.AllArgsConstructor;
12+
import reactor.core.publisher.Flux;
13+
import reactor.core.publisher.Mono;
14+
15+
//@Component
16+
@AllArgsConstructor
17+
public class ExternalClientImpl implements ExternalClient {
18+
19+
private static final Logger LOGGER = LogManager.getLogger(ExternalClientImpl.class);
20+
21+
private WebClient client;
22+
23+
public <T> Mono<T> getForMono(String path, HttpHeaders httpHeaders, Class<T> resClazz) {
24+
return getClientResponse(path, httpHeaders)
25+
.exchangeToMono(r -> r.bodyToMono(resClazz));
26+
}
27+
28+
public <T> Flux<T> getForFlux(String path, HttpHeaders httpHeaders, Class<T> resClazz) {
29+
return getClientResponse(path, httpHeaders)
30+
.exchangeToFlux(r -> r.bodyToFlux(resClazz));
31+
32+
}
33+
34+
public <T, U> Mono<U> postForMono(String path, HttpHeaders httpHeaders, Class<U> resClazz,
35+
T reqBody, Class<T> reqClazz) {
36+
return postForResponse(path, httpHeaders, reqBody, reqClazz)
37+
.exchangeToMono(r -> r.bodyToMono(resClazz));
38+
}
39+
40+
public <T, U> Flux<U> postForFlux(String path, HttpHeaders httpHeaders, T reqBody, Class<T> reqClazz,
41+
Class<U> resClazz) {
42+
return postForResponse(path, httpHeaders, reqBody, reqClazz)
43+
.exchangeToFlux(r -> r.bodyToFlux(resClazz));
44+
45+
}
46+
47+
private <T> RequestHeadersSpec<?> postForResponse(String path, HttpHeaders httpHeaders, T reqBody,
48+
Class<T> reqClazz) {
49+
return client.post()
50+
.uri(path)
51+
.headers(headerConsumer(httpHeaders))
52+
.body(Mono.just(reqBody), reqClazz);
53+
}
54+
55+
private RequestHeadersSpec<?> getClientResponse(String path, HttpHeaders httpHeaders) {
56+
return client.get()
57+
.uri(path)
58+
.headers(headerConsumer(httpHeaders));
59+
}
60+
61+
@PostConstruct
62+
private void initiated() {
63+
LOGGER.debug("ExternalClientImpl initiated");
64+
}
65+
66+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package com.prs.services.student.client;
2+
3+
import org.springframework.beans.factory.annotation.Qualifier;
4+
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
5+
import org.springframework.context.annotation.Bean;
6+
import org.springframework.context.annotation.Configuration;
7+
import org.springframework.http.HttpHeaders;
8+
import org.springframework.http.MediaType;
9+
import org.springframework.web.reactive.function.client.WebClient;
10+
11+
@Configuration
12+
public class WebClientConfig {
13+
14+
@Bean
15+
@Qualifier("collegeWebClient")
16+
@LoadBalanced
17+
public WebClient getCollegeWebClient() {
18+
WebClient client = WebClient.builder().baseUrl("http://localhost:8060/college")
19+
.defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
20+
.build();
21+
return client;
22+
}
23+
24+
@Bean
25+
@Qualifier("departmentWebClient")
26+
@LoadBalanced
27+
public WebClient getDepartmentWebClient() {
28+
WebClient client = WebClient.builder().baseUrl("http://localhost:8060/department")
29+
.defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
30+
.build();
31+
return client;
32+
}
33+
34+
@Bean
35+
@Qualifier("collegeExternalClient")
36+
public ExternalClientImpl getCollegeExternalClient(@Qualifier("collegeWebClient") WebClient collegeWebClient) {
37+
return new ExternalClientImpl(collegeWebClient);
38+
}
39+
40+
@Bean
41+
@Qualifier("departmentExternalClient")
42+
public ExternalClientImpl getDepartmentExternalClient(@Qualifier("departmentWebClient") WebClient departmentWebClient) {
43+
return new ExternalClientImpl(departmentWebClient);
44+
}
45+
46+
47+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package com.prs.services.student.model;
2+
3+
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
4+
import com.fasterxml.jackson.annotation.JsonInclude;
5+
import com.fasterxml.jackson.annotation.JsonInclude.Include;
6+
7+
import lombok.Data;
8+
import lombok.ToString;
9+
10+
@Data
11+
@ToString
12+
@JsonInclude(Include.NON_NULL)
13+
@JsonIgnoreProperties(ignoreUnknown = true)
14+
public class College {
15+
private Long id;
16+
private String name;
17+
private String address;
18+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package com.prs.services.student.model;
2+
3+
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
4+
import com.fasterxml.jackson.annotation.JsonInclude;
5+
import com.fasterxml.jackson.annotation.JsonInclude.Include;
6+
7+
import lombok.Data;
8+
import lombok.ToString;
9+
10+
@Data
11+
@ToString
12+
@JsonInclude(Include.NON_NULL)
13+
@JsonIgnoreProperties(ignoreUnknown = true)
14+
public class Department {
15+
private Long id;
16+
private String name;
17+
18+
}

reactive-micro-service/student-service/src/main/java/com/prs/services/student/model/Student.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,10 @@
1414
public class Student {
1515

1616
private Long id;
17-
private Long collegeId;
18-
private Long departmentId;
1917
private String name;
2018
private int age;
19+
20+
private College college;
21+
private Department department;
2122

2223
}

reactive-micro-service/student-service/src/main/java/com/prs/services/student/service/StudentServiceImpl.java

Lines changed: 36 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,11 @@
88
import org.springframework.stereotype.Service;
99

1010
import com.prs.services.exceptionHandler.DataException;
11+
import com.prs.services.student.client.CollegeReactiveClient;
12+
import com.prs.services.student.client.DepartmentReactiveClient;
1113
import com.prs.services.student.entity.StudentEntity;
14+
import com.prs.services.student.model.College;
15+
import com.prs.services.student.model.Department;
1216
import com.prs.services.student.model.Student;
1317
import com.prs.services.student.repository.StudentRepository;
1418

@@ -20,11 +24,17 @@ public class StudentServiceImpl implements IStudentService {
2024

2125
@Autowired
2226
private StudentRepository repository;
27+
28+
@Autowired
29+
private DepartmentReactiveClient departmentClient;
30+
@Autowired
31+
private CollegeReactiveClient collegeClient;
32+
2333

2434
@Override
2535
public Mono<Student> save(StudentEntity entity) {
2636
// return repository.save(entity).map(mapper);Issue in SimpleR2dbcRepository save(e); So used saveAll for time being
27-
return repository.saveAll(Arrays.asList(entity)).last().map(mapper);
37+
return repository.saveAll(Arrays.asList(entity)).last().flatMap(mapper);
2838
}
2939

3040
@Override
@@ -37,12 +47,12 @@ public Mono<Student> update(Long id, StudentEntity entity) {
3747

3848
@Override
3949
public Flux<Student> findAll() {
40-
return repository.findAll().map(mapper);
50+
return repository.findAll().map(simpleMapper);
4151
}
4252

4353
@Override
4454
public Mono<Student> findById(Long id) {
45-
return repository.findById(id).map(mapper);
55+
return repository.findById(id).flatMap(mapper);
4656
}
4757

4858
@Override
@@ -52,20 +62,37 @@ public Mono<Void> deleteById(Long id) {
5262

5363
@Override
5464
public Flux<Student> findByCollege(Long collegeId) {
55-
return findAll().filter(a -> a.getCollegeId().equals(collegeId));
65+
return findAll().filter(a -> a.getCollege().getId().equals(collegeId));
5666
// return Flux.fromIterable(repository.findByCollegeId(collegeId)).map(mapper);
5767
}
5868

5969
@Override
6070
public Flux<Student> findByDepartment(Long departmentId) {
61-
return findAll().filter(a -> a.getDepartmentId().equals(departmentId));
71+
return findAll().filter(a -> a.getDepartment().getId().equals(departmentId));
6272
// return Flux.fromIterable(repository.findByDepartmentId(departmentId)).map(mapper);
6373
}
6474

65-
private Function<StudentEntity, Student> mapper = c -> {
66-
Student response = new Student();
67-
BeanUtils.copyProperties(c, response);
68-
return response;
75+
private Function<StudentEntity, Mono<Student>> mapper = c -> {
76+
var student = new Student();
77+
BeanUtils.copyProperties(c, student);
78+
var department = departmentClient.findByDepartment(c.getDepartmentId());
79+
var college = collegeClient.findByCollege(c.getCollegeId());
80+
var tuple = Mono.zip(department, college);
81+
return tuple.map(t-> {
82+
var dept = new Department();
83+
var coll = new College();
84+
BeanUtils.copyProperties(t.getT1(), dept);
85+
BeanUtils.copyProperties(t.getT2(), coll);
86+
student.setCollege(coll);
87+
student.setDepartment(dept);
88+
return student;
89+
});
90+
};
91+
92+
private Function<StudentEntity, Student> simpleMapper = c -> {
93+
var student = new Student();
94+
BeanUtils.copyProperties(c, student);
95+
return student;
6996
};
7097

7198

0 commit comments

Comments
 (0)