Skip to content

Commit 997a009

Browse files
authored
Validate actual presence of uuid query param value (#164)
1 parent 5d67f2e commit 997a009

8 files changed

Lines changed: 104 additions & 56 deletions

File tree

src/main/java/org/prebid/cache/handlers/ErrorHandler.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
public class ErrorHandler extends MetricsHandler {
1717
private static final String RESOURCE_NOT_FOUND_BAD_URL = "Resource Not Found - Bad URL.";
1818
private static final String RESOURCE_NOT_FOUND = "Resource Not Found: uuid %s";
19-
private static final String INVALID_PARAMETERS = "Invalid Parameter(s): uuid not found.";
19+
private static final String INVALID_PARAMETERS = "Invalid Parameter(s): uuid not found or is empty.";
2020
private static final String NO_ELEMENTS_FOUND = "No Elements Found.";
2121

2222
@Autowired

src/main/java/org/prebid/cache/handlers/cache/GetCacheHandler.java

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -77,14 +77,16 @@ private static Map<String, WebClient> createClientsCache(final int ttl, final in
7777
}
7878

7979
public Mono<ServerResponse> fetch(ServerRequest request) {
80-
// metrics
81-
metricsRecorder.markMeterForTag(this.metricTagPrefix, MeasurementTag.REQUEST);
82-
final var timerContext = metricsRecorder.createRequestTimerForServiceType(this.type);
83-
84-
return request.queryParam(ID_KEY).map(id -> fetch(request, id, timerContext)).orElseGet(() -> {
85-
final var responseMono = ErrorHandler.createInvalidParameters();
86-
return finalizeResult(responseMono, request, timerContext);
87-
});
80+
metricsRecorder.markMeterForTag(metricTagPrefix, MeasurementTag.REQUEST);
81+
final var timerContext = metricsRecorder.createRequestTimerForServiceType(type);
82+
83+
return request.queryParam(ID_KEY)
84+
.filter(StringUtils::isNotBlank)
85+
.map(id -> fetch(request, id, timerContext))
86+
.orElseGet(() -> {
87+
final var responseMono = ErrorHandler.createInvalidParameters();
88+
return finalizeResult(responseMono, request, timerContext);
89+
});
8890
}
8991

9092
private Mono<ServerResponse> fetch(final ServerRequest request,

src/test/java/org/prebid/cache/handlers/CacheHandlerTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package org.prebid.cache.handlers;
22

3-
import org.prebid.cache.exceptions.RequestParsingException;
43
import org.prebid.cache.exceptions.RepositoryException;
4+
import org.prebid.cache.exceptions.RequestParsingException;
55
import org.prebid.cache.handlers.cache.CacheHandler;
66
import org.prebid.cache.model.Payload;
77
import org.prebid.cache.model.PayloadTransfer;

src/test/java/org/prebid/cache/handlers/GetCacheHandlerTests.java

Lines changed: 69 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -47,14 +47,14 @@
4747

4848
@ExtendWith(SpringExtension.class)
4949
@ContextConfiguration(classes = {
50-
GetCacheHandler.class,
51-
PrebidServerResponseBuilder.class,
52-
CacheConfig.class,
53-
CacheConfig.class,
54-
MetricsRecorderTest.class,
55-
MetricsRecorder.class,
56-
ApiConfig.class,
57-
CircuitBreakerPropertyConfiguration.class
50+
GetCacheHandler.class,
51+
PrebidServerResponseBuilder.class,
52+
CacheConfig.class,
53+
CacheConfig.class,
54+
MetricsRecorderTest.class,
55+
MetricsRecorder.class,
56+
ApiConfig.class,
57+
CircuitBreakerPropertyConfiguration.class
5858
})
5959
@EnableConfigurationProperties
6060
@SpringBootTest
@@ -110,18 +110,14 @@ void testVerifyError() {
110110
verifyRepositoryError(handler);
111111
}
112112

113-
private static Consumer<ServerResponse> assertNotFoundStatusCode() {
114-
return response -> assertEquals(response.statusCode().value(), 404);
115-
}
116-
117113
@Test
118114
void testVerifyFetch() {
119115
given(repository.findById("prebid_a8db2208-d085-444c-9721-c1161d7f09ce")).willReturn(Mono.just(PAYLOAD_WRAPPER));
120116

121117
final var requestMono = MockServerRequest.builder()
122-
.method(HttpMethod.GET)
123-
.queryParam("uuid", "a8db2208-d085-444c-9721-c1161d7f09ce")
124-
.build();
118+
.method(HttpMethod.GET)
119+
.queryParam("uuid", "a8db2208-d085-444c-9721-c1161d7f09ce")
120+
.build();
125121

126122
final var responseMono = handler.fetch(requestMono);
127123

@@ -142,18 +138,18 @@ void testVerifyFetchWithCacheHostParam() {
142138
final var requestMono = MockServerRequest.builder()
143139
.method(HttpMethod.GET)
144140
.header(CONTENT_TYPE, MediaType.APPLICATION_JSON_UTF8_VALUE)
145-
.queryParam("uuid", "a8db2208-d085-444c-9721-c1161d7f09ce")
146-
.queryParam("ch", "localhost:8080")
147-
.build();
141+
.queryParam("uuid", "a8db2208-d085-444c-9721-c1161d7f09ce")
142+
.queryParam("ch", "localhost:8080")
143+
.build();
148144

149145
final var responseMono = handler.fetch(requestMono);
150146
responseMono.doOnEach(assertSignalStatusCode(200)).subscribe();
151147

152148
StepVerifier.create(responseMono)
153-
.expectSubscription()
154-
.expectNextMatches(t -> true)
155-
.expectComplete()
156-
.verify();
149+
.expectSubscription()
150+
.expectNextMatches(t -> true)
151+
.expectComplete()
152+
.verify();
157153

158154
verify(getRequestedFor(urlPathEqualTo("/cache"))
159155
.withQueryParam("uuid", equalTo("a8db2208-d085-444c-9721-c1161d7f09ce"))
@@ -164,34 +160,34 @@ void testVerifyFetchWithCacheHostParam() {
164160
@Test
165161
void testVerifyFailForNotFoundResourceWithCacheHostParam() {
166162
final var requestMono = MockServerRequest.builder()
167-
.method(HttpMethod.GET)
168-
.queryParam("uuid", "a8db2208-d085-444c-9721-c1161d7f09ce")
169-
.queryParam("ch", "localhost:8080")
170-
.build();
163+
.method(HttpMethod.GET)
164+
.queryParam("uuid", "a8db2208-d085-444c-9721-c1161d7f09ce")
165+
.queryParam("ch", "localhost:8080")
166+
.build();
171167

172168
final var responseMono = handler.fetch(requestMono);
173169

174170
responseMono.doOnEach(assertSignalStatusCode(404)).subscribe();
175171
StepVerifier.create(responseMono)
176172
.consumeNextWith(assertNotFoundStatusCode())
177-
.expectComplete()
178-
.verify();
173+
.expectComplete()
174+
.verify();
179175
}
180176

181177
@Test
182178
void testVerifyFetchReturnsBadRequestWhenResponseStatusIsNotOk() {
183179

184180
serverMock.stubFor(get(urlPathEqualTo("/cache"))
185-
.willReturn(aResponse().withHeader(HttpHeaders.CONTENT_TYPE, "application/json;charset=utf-8")
186-
.withStatus(201)
187-
.withBody("{\"uuid\":\"2be04ba5-8f9b-4a1e-8100-d573c40312f8\"}")));
181+
.willReturn(aResponse().withHeader(HttpHeaders.CONTENT_TYPE, "application/json;charset=utf-8")
182+
.withStatus(201)
183+
.withBody("{\"uuid\":\"2be04ba5-8f9b-4a1e-8100-d573c40312f8\"}")));
188184

189185
final var requestMono = MockServerRequest.builder()
190186
.method(HttpMethod.GET)
191187
.header(CONTENT_TYPE, MediaType.APPLICATION_JSON_UTF8_VALUE)
192-
.queryParam("uuid", "a8db2208-d085-444c-9721-c1161d7f09ce")
193-
.queryParam("ch", "localhost:8080")
194-
.build();
188+
.queryParam("uuid", "a8db2208-d085-444c-9721-c1161d7f09ce")
189+
.queryParam("ch", "localhost:8080")
190+
.build();
195191

196192
final var responseMono = handler.fetch(requestMono);
197193

@@ -208,10 +204,49 @@ void testVerifyFetchReturnsBadRequestWhenResponseStatusIsNotOk() {
208204
);
209205
}
210206

207+
@Test
208+
void testVerifyFetchReturnsBadRequestWhenNoUuid() {
209+
final var requestMono = MockServerRequest.builder()
210+
.method(HttpMethod.GET)
211+
.header(CONTENT_TYPE, MediaType.APPLICATION_JSON_UTF8_VALUE)
212+
.build();
213+
214+
final var responseMono = handler.fetch(requestMono);
215+
216+
StepVerifier.create(responseMono)
217+
.consumeNextWith(assertBadRequestStatusCode())
218+
.expectComplete()
219+
.verify();
220+
}
221+
222+
@Test
223+
void testVerifyFetchReturnsBadRequestWhenUuidIsEmpty() {
224+
final var requestMono = MockServerRequest.builder()
225+
.method(HttpMethod.GET)
226+
.header(CONTENT_TYPE, MediaType.APPLICATION_JSON_UTF8_VALUE)
227+
.queryParam("uuid", "")
228+
.build();
229+
230+
final var responseMono = handler.fetch(requestMono);
231+
232+
StepVerifier.create(responseMono)
233+
.consumeNextWith(assertBadRequestStatusCode())
234+
.expectComplete()
235+
.verify();
236+
}
237+
211238
private static Consumer<Signal<ServerResponse>> assertSignalStatusCode(int statusCode) {
212239
return signal -> {
213240
assertTrue(signal.isOnComplete());
214241
assertEquals(signal.get().statusCode().value(), statusCode);
215242
};
216243
}
244+
245+
private static Consumer<ServerResponse> assertNotFoundStatusCode() {
246+
return response -> assertEquals(response.statusCode().value(), 404);
247+
}
248+
249+
private static Consumer<ServerResponse> assertBadRequestStatusCode() {
250+
return response -> assertEquals(response.statusCode().value(), 400);
251+
}
217252
}

src/test/java/org/prebid/cache/handlers/PostCacheHandlerTests.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -51,13 +51,13 @@
5151

5252
@ExtendWith(SpringExtension.class)
5353
@ContextConfiguration(classes = {
54-
PostCacheHandler.class,
55-
PrebidServerResponseBuilder.class,
56-
CacheConfig.class,
57-
MetricsRecorderTest.class,
58-
MetricsRecorder.class,
59-
ApiConfig.class,
60-
CircuitBreakerPropertyConfiguration.class
54+
PostCacheHandler.class,
55+
PrebidServerResponseBuilder.class,
56+
CacheConfig.class,
57+
MetricsRecorderTest.class,
58+
MetricsRecorder.class,
59+
ApiConfig.class,
60+
CircuitBreakerPropertyConfiguration.class
6161
})
6262
@EnableConfigurationProperties
6363
@SpringBootTest

src/test/java/org/prebid/cache/handlers/PostStorageHandlerTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@
99
import org.prebid.cache.builders.PrebidServerResponseBuilder;
1010
import org.prebid.cache.config.StorageConfig;
1111
import org.prebid.cache.handlers.storage.PostStorageHandler;
12-
import org.prebid.cache.model.StoragePayload;
1312
import org.prebid.cache.model.Payload;
1413
import org.prebid.cache.model.PayloadWrapper;
14+
import org.prebid.cache.model.StoragePayload;
1515
import org.prebid.cache.repository.redis.module.storage.ModuleCompositeRepository;
1616
import org.prebid.cache.routers.ApiConfig;
1717
import org.springframework.beans.factory.annotation.Autowired;

src/test/java/org/prebid/cache/metrics/MetricsRecorderTest.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
package org.prebid.cache.metrics;
22

3-
import org.springframework.context.annotation.Bean;
4-
import org.springframework.context.annotation.Primary;
53
import io.micrometer.core.instrument.MeterRegistry;
4+
import io.micrometer.core.instrument.MockClock;
65
import io.micrometer.core.instrument.simple.SimpleConfig;
76
import io.micrometer.core.instrument.simple.SimpleMeterRegistry;
8-
import io.micrometer.core.instrument.MockClock;
7+
import org.springframework.context.annotation.Bean;
8+
import org.springframework.context.annotation.Primary;
99

1010
public class MetricsRecorderTest {
1111

src/test/kotlin/org/prebid/cache/functional/GeneralCacheSpec.kt

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,18 @@ class GeneralCacheSpec : ShouldSpec({
2929
// then: Bad Request exception is thrown
3030
assertSoftly {
3131
exception.statusCode shouldBe BAD_REQUEST.value()
32-
exception.responseBody shouldContain "\"message\":\"Invalid Parameter(s): uuid not found.\""
32+
exception.responseBody shouldContain "\"message\":\"Invalid Parameter(s): uuid not found or is empty.\""
33+
}
34+
}
35+
36+
should("throw an exception when 'uuid' query parameter is empty") {
37+
// when: GET cache endpoint is called with empty 'uuid' query parameter
38+
val exception = shouldThrowExactly<ApiException> { BaseSpec.getPrebidCacheApi().getCache("") }
39+
40+
// then: Bad Request exception is thrown
41+
assertSoftly {
42+
exception.statusCode shouldBe BAD_REQUEST.value()
43+
exception.responseBody shouldContain "\"message\":\"Invalid Parameter(s): uuid not found or is empty.\""
3344
}
3445
}
3546

0 commit comments

Comments
 (0)