Skip to content

Commit 290222a

Browse files
committed
use retrieve instead of exchange
1 parent 9ad8af1 commit 290222a

File tree

4 files changed

+123
-71
lines changed

4 files changed

+123
-71
lines changed

src/main/kotlin/org/learning/by/example/reactive/kotlin/microservices/KotlinReactiveMS/services/GeoLocationServiceImpl.kt

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,11 @@ import org.learning.by.example.reactive.kotlin.microservices.KotlinReactiveMS.ex
55
import org.learning.by.example.reactive.kotlin.microservices.KotlinReactiveMS.exceptions.InvalidParametersException
66
import org.learning.by.example.reactive.kotlin.microservices.KotlinReactiveMS.model.GeoLocationResponse
77
import org.learning.by.example.reactive.kotlin.microservices.KotlinReactiveMS.model.GeographicCoordinates
8+
import org.springframework.http.HttpStatus
89
import org.springframework.http.MediaType
10+
import org.springframework.http.ResponseEntity
911
import org.springframework.web.reactive.function.client.WebClient
12+
import org.springframework.web.reactive.function.client.toEntity
1013
import reactor.core.publisher.Mono
1114
import reactor.core.publisher.toMono
1215

@@ -18,6 +21,7 @@ open internal class GeoLocationServiceImpl(val endPoint: String, var webClient:
1821
const val OK_STATUS = "OK"
1922
const val ZERO_RESULTS = "ZERO_RESULTS"
2023
const val ERROR_GETTING_LOCATION = "error getting location"
24+
const val ERROR_NOT_200 = "response was not 200"
2125
const val ADDRESS_NOT_FOUND = "address not found"
2226
}
2327

@@ -39,13 +43,15 @@ open internal class GeoLocationServiceImpl(val endPoint: String, var webClient:
3943
webClient.get()
4044
.uri(it)
4145
.accept(MediaType.APPLICATION_JSON)
42-
.exchange()
43-
.flatMap { it.bodyToMono(GeoLocationResponse::class.java) }
46+
.retrieve()
47+
.toEntity<GeoLocationResponse>()
4448
}
4549

46-
open internal fun geometryLocation(geoLocationResponseMono: Mono<GeoLocationResponse>) =
47-
geoLocationResponseMono.flatMap {
48-
with(it) {
50+
open internal fun geometryLocation(responseMono: Mono<ResponseEntity<GeoLocationResponse>>) =
51+
responseMono.flatMap {
52+
if (it.statusCode != HttpStatus.OK)
53+
GetGeoLocationException(ERROR_NOT_200).toMono()
54+
else with(it.body) {
4955
when (status) {
5056
OK_STATUS -> with(results[0].geometry.location) { GeographicCoordinates(lat, lng).toMono() }
5157
ZERO_RESULTS -> GeoLocationNotFoundException(ADDRESS_NOT_FOUND).toMono()

src/main/kotlin/org/learning/by/example/reactive/kotlin/microservices/KotlinReactiveMS/services/SunriseSunsetServiceImpl.kt

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,11 @@ import org.learning.by.example.reactive.kotlin.microservices.KotlinReactiveMS.ex
44
import org.learning.by.example.reactive.kotlin.microservices.KotlinReactiveMS.model.GeoTimesResponse
55
import org.learning.by.example.reactive.kotlin.microservices.KotlinReactiveMS.model.GeographicCoordinates
66
import org.learning.by.example.reactive.kotlin.microservices.KotlinReactiveMS.model.SunriseSunset
7+
import org.springframework.http.HttpStatus
78
import org.springframework.http.MediaType
9+
import org.springframework.http.ResponseEntity
810
import org.springframework.web.reactive.function.client.WebClient
11+
import org.springframework.web.reactive.function.client.toEntity
912
import reactor.core.publisher.Mono
1013
import reactor.core.publisher.toMono
1114

@@ -17,6 +20,7 @@ open internal class SunriseSunsetServiceImpl(val endPoint: String, var webClient
1720
const val NOT_FORMATTED = "0"
1821
const val ERROR_GETTING_DATA = "error getting sunrise and sunset"
1922
const val SUNRISE_RESULT_NOT_OK = "sunrise and sunset result was not OK"
23+
const val ERROR_NOT_200 = "response was not 200"
2024
const val STATUS_OK = "OK"
2125
}
2226

@@ -37,13 +41,15 @@ open internal class SunriseSunsetServiceImpl(val endPoint: String, var webClient
3741
webClient.get()
3842
.uri(it)
3943
.accept(MediaType.APPLICATION_JSON)
40-
.exchange()
41-
.flatMap { it.bodyToMono(GeoTimesResponse::class.java) }
42-
}!!
44+
.retrieve()
45+
.toEntity<GeoTimesResponse>()
46+
}
4347

44-
open internal fun createResult(geoTimesResponseMono: Mono<GeoTimesResponse>) =
45-
geoTimesResponseMono.flatMap {
46-
with(it){
48+
open internal fun createResult(responseMono: Mono<ResponseEntity<GeoTimesResponse>>) =
49+
responseMono.flatMap {
50+
if (it.statusCode != HttpStatus.OK)
51+
GetSunriseSunsetException(ERROR_NOT_200).toMono()
52+
else with(it.body) {
4753
if (status == STATUS_OK) with(results) { SunriseSunset(sunrise, sunset).toMono() }
4854
else GetSunriseSunsetException(SUNRISE_RESULT_NOT_OK).toMono()
4955
}

src/test/kotlin/org/learning/by/example/reactive/kotlin/microservices/KotlinReactiveMS/services/GeoLocationServiceImplTest.kt

Lines changed: 52 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ import org.learning.by.example.reactive.kotlin.microservices.KotlinReactiveMS.mo
1414
import org.learning.by.example.reactive.kotlin.microservices.KotlinReactiveMS.test.*
1515
import org.learning.by.example.reactive.kotlin.microservices.KotlinReactiveMS.test.tags.UnitTest
1616
import org.springframework.boot.test.mock.mockito.SpyBean
17+
import org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR
18+
import org.springframework.http.HttpStatus.OK
1719
import reactor.core.publisher.Mono
1820
import reactor.core.publisher.toMono
1921

@@ -33,127 +35,146 @@ private class GeoLocationServiceImplTest {
3335
const val JSON_NOT_FOUND = "/json/GeoLocationResponse_NOT_FOUND.json"
3436
const val JSON_EMPTY = "/json/GeoLocationResponse_EMPTY.json"
3537
const val JSON_WRONG_STATUS = "/json/GeoLocationResponse_WRONG_STATUS.json"
36-
val LOCATION_OK = getMonoFromJsonPath(JSON_OK, GeoLocationResponse::class)
37-
val LOCATION_NOT_FOUND = getMonoFromJsonPath(JSON_NOT_FOUND, GeoLocationResponse::class)
38-
val LOCATION_EMPTY = getMonoFromJsonPath(JSON_EMPTY, GeoLocationResponse::class)
39-
val LOCATION_WRONG_STATUS = getMonoFromJsonPath(JSON_WRONG_STATUS, GeoLocationResponse::class)
38+
val LOCATION_OK = getEntityFromJsonPath(JSON_OK, GeoLocationResponse::class)
39+
val LOCATION_NOT_FOUND = getEntityFromJsonPath(JSON_NOT_FOUND, GeoLocationResponse::class)
40+
val LOCATION_EMPTY = getEntityFromJsonPath(JSON_EMPTY, GeoLocationResponse::class)
41+
val LOCATION_ERROR = getEntityFromJsonPath(JSON_EMPTY, GeoLocationResponse::class, INTERNAL_SERVER_ERROR)
42+
val LOCATION_WRONG_STATUS = getEntityFromJsonPath(JSON_WRONG_STATUS, GeoLocationResponse::class)
4043
val LOCATION_EXCEPTION: Mono<GeoLocationResponse> = GetGeoLocationException(BAD_EXCEPTION).toMono()
4144
val BIG_EXCEPTION: Mono<GeoLocationResponse> = RuntimeException(BAD_EXCEPTION).toMono()
4245
}
4346

4447
@SpyBean(GeoLocationService::class)
45-
lateinit var geoLocationServiceImpl: GeoLocationServiceImpl
48+
lateinit var serviceImpl: GeoLocationServiceImpl
4649

4750

4851
@Test
4952
fun getMockingWebClientTest() {
50-
geoLocationServiceImpl.webClient = geoLocationServiceImpl.webClient `with mock response` LOCATION_OK
53+
serviceImpl.webClient = serviceImpl.webClient mocking LOCATION_OK
5154

5255
val geoLocationResponse = GOOGLE_ADDRESS_MONO
53-
.transform(geoLocationServiceImpl::buildUrl)
54-
.transform(geoLocationServiceImpl::get).block()
55-
geoLocationResponse.status `should equal` OK_STATUS
56+
.transform(serviceImpl::buildUrl)
57+
.transform(serviceImpl::get).block()
5658

57-
geoLocationServiceImpl.webClient reset `mock responses`
59+
geoLocationResponse.statusCode `should equal` OK
60+
61+
geoLocationResponse.body.status `should equal` OK_STATUS
62+
63+
serviceImpl.webClient reset `mock responses`
64+
}
65+
66+
@Test
67+
fun getMockingWebClientErrorTest() {
68+
serviceImpl.webClient = serviceImpl.webClient mocking LOCATION_ERROR
69+
70+
val geoLocationResponse = GOOGLE_ADDRESS_MONO
71+
.transform(serviceImpl::buildUrl)
72+
.transform(serviceImpl::get)
73+
.block()
74+
75+
geoLocationResponse.statusCode `should be` INTERNAL_SERVER_ERROR
76+
77+
serviceImpl.webClient reset `mock responses`
5878
}
5979

6080
@Test
6181
fun fromAddressTest() {
62-
(geoLocationServiceImpl `will return` LOCATION_OK).get(any())
6382

64-
val geographicCoordinates = geoLocationServiceImpl.fromAddress(GOOGLE_ADDRESS_MONO).block()
83+
(serviceImpl `will return` LOCATION_OK).get(any())
84+
85+
val geographicCoordinates = serviceImpl.fromAddress(GOOGLE_ADDRESS_MONO).block()
6586
geographicCoordinates `should equal` GeographicCoordinates(GOOGLE_LAT, GOOGLE_LNG)
6687

67-
geoLocationServiceImpl reset `mock responses`
88+
serviceImpl reset `mock responses`
6889
}
6990

7091
@Test
7192
fun fromAddressNotFoundTest() {
7293

73-
(geoLocationServiceImpl `will return` LOCATION_NOT_FOUND).get(any())
94+
(serviceImpl `will return` LOCATION_NOT_FOUND).get(any())
7495

75-
val geographicCoordinates: GeographicCoordinates? = geoLocationServiceImpl.fromAddress(GOOGLE_ADDRESS_MONO)
96+
val geographicCoordinates: GeographicCoordinates? = serviceImpl.fromAddress(GOOGLE_ADDRESS_MONO)
7697
.onErrorResume {
7798
it `should be instance of` GeoLocationNotFoundException::class
7899
Mono.empty()
79100
}
80101
.block()
81102
geographicCoordinates `should be` null
82103

83-
geoLocationServiceImpl reset `mock responses`
104+
serviceImpl reset `mock responses`
84105
}
85106

86107
@Test
87108
fun fromAddressEmptyTest() {
88-
(geoLocationServiceImpl `will return` LOCATION_EMPTY).get(any())
109+
(serviceImpl `will return` LOCATION_EMPTY).get(any())
89110

90-
val geographicCoordinates: GeographicCoordinates? = geoLocationServiceImpl.fromAddress(GOOGLE_ADDRESS_MONO)
111+
val geographicCoordinates: GeographicCoordinates? = serviceImpl.fromAddress(GOOGLE_ADDRESS_MONO)
91112
.onErrorResume {
92113
it `should be instance of` GetGeoLocationException::class
93114
Mono.empty()
94115
}
95116
.block()
96117
geographicCoordinates `should be` null
97118

98-
geoLocationServiceImpl reset `mock responses`
119+
serviceImpl reset `mock responses`
99120
}
100121

101122

102123
@Test
103124
fun fromAddressWrongStatusTest() {
104-
(geoLocationServiceImpl `will return` LOCATION_WRONG_STATUS).get(any())
125+
(serviceImpl `will return` LOCATION_WRONG_STATUS).get(any())
105126

106-
val geographicCoordinates: GeographicCoordinates? = geoLocationServiceImpl.fromAddress(GOOGLE_ADDRESS_MONO)
127+
val geographicCoordinates: GeographicCoordinates? = serviceImpl.fromAddress(GOOGLE_ADDRESS_MONO)
107128
.onErrorResume {
108129
it `should be instance of` GetGeoLocationException::class
109130
Mono.empty()
110131
}
111132
.block()
112133
geographicCoordinates `should be` null
113134

114-
geoLocationServiceImpl reset `mock responses`
135+
serviceImpl reset `mock responses`
115136
}
116137

117138
@Test
118139
fun fromAddressExceptionTest() {
119-
(geoLocationServiceImpl `will return` LOCATION_EXCEPTION).get(any())
140+
(serviceImpl `will return` LOCATION_EXCEPTION).get(any())
120141

121-
val geographicCoordinates: GeographicCoordinates? = geoLocationServiceImpl.fromAddress(GOOGLE_ADDRESS_MONO)
142+
val geographicCoordinates: GeographicCoordinates? = serviceImpl.fromAddress(GOOGLE_ADDRESS_MONO)
122143
.onErrorResume {
123144
it `should be instance of` GetGeoLocationException::class
124145
Mono.empty()
125146
}
126147
.block()
127148
geographicCoordinates `should be` null
128149

129-
geoLocationServiceImpl reset `mock responses`
150+
serviceImpl reset `mock responses`
130151
}
131152

132153
@Test
133154
fun fromAddressBigExceptionTest() {
134-
(geoLocationServiceImpl `will return` BIG_EXCEPTION).get(any())
155+
(serviceImpl `will return` BIG_EXCEPTION).get(any())
135156

136-
val geographicCoordinates: GeographicCoordinates? = geoLocationServiceImpl.fromAddress(GOOGLE_ADDRESS_MONO)
157+
val geographicCoordinates: GeographicCoordinates? = serviceImpl.fromAddress(GOOGLE_ADDRESS_MONO)
137158
.onErrorResume {
138159
it `should be instance of` GetGeoLocationException::class
139160
Mono.empty()
140161
}
141162
.block()
142163
geographicCoordinates `should be` null
143164

144-
geoLocationServiceImpl reset `mock responses`
165+
serviceImpl reset `mock responses`
145166
}
146167

147168

148169
@Test
149170
fun buildUrlTest() {
150-
val url = GOOGLE_ADDRESS_MONO.transform(geoLocationServiceImpl::buildUrl).block()
151-
url `should equal` geoLocationServiceImpl.endPoint + GOOGLE_ADDRESS_IN_PARAMS
171+
val url = GOOGLE_ADDRESS_MONO.transform(serviceImpl::buildUrl).block()
172+
url `should equal` serviceImpl.endPoint + GOOGLE_ADDRESS_IN_PARAMS
152173
}
153174

154175
@Test
155176
fun buildUrlEmptyAddressTest() {
156-
val url = "".toMono().transform(geoLocationServiceImpl::buildUrl).onErrorResume {
177+
val url = "".toMono().transform(serviceImpl::buildUrl).onErrorResume {
157178
it `should be instance of` InvalidParametersException::class
158179
Mono.empty()
159180
}.block()

0 commit comments

Comments
 (0)