Refactor HttpRequestSpec to HttpRequestValues

HttpRequestValues is immutable and exposes a builder.

See gh-28386
This commit is contained in:
rstoyanchev
2022-04-27 09:25:23 +01:00
parent 564f8ba7a0
commit d7ab5b4132
12 changed files with 484 additions and 348 deletions

View File

@@ -21,7 +21,6 @@ import org.junit.jupiter.api.Test;
import org.springframework.http.HttpMethod;
import org.springframework.lang.Nullable;
import org.springframework.web.service.annotation.GetExchange;
import org.springframework.web.service.annotation.HttpExchange;
import static org.assertj.core.api.Assertions.assertThat;
@@ -47,7 +46,7 @@ public class HttpMethodArgumentResolverTests {
@Test
void shouldIgnoreArgumentsNotMatchingType() {
this.service.execute("test");
assertThat(getActualMethod()).isNull();
assertThat(getActualMethod()).isEqualTo(HttpMethod.GET);
}
@Test
@@ -59,30 +58,29 @@ public class HttpMethodArgumentResolverTests {
@Test
void shouldIgnoreNullValue() {
this.service.executeForNull(null);
assertThat(getActualMethod()).isNull();
assertThat(getActualMethod()).isEqualTo(HttpMethod.GET);
}
@Nullable
private HttpMethod getActualMethod() {
return this.clientAdapter.getRequestSpec().getHttpMethod();
return this.clientAdapter.getRequestValues().getHttpMethod();
}
private interface Service {
@HttpExchange
@GetExchange
void execute(HttpMethod method);
@GetExchange
void executeGet(HttpMethod method);
@HttpExchange
@GetExchange
void execute(String test);
@HttpExchange
@GetExchange
void execute(HttpMethod firstMethod, HttpMethod secondMethod);
@HttpExchange
@GetExchange
void executeForNull(@Nullable HttpMethod method);
}

View File

@@ -141,45 +141,45 @@ public class HttpServiceMethodTests {
@Test
void methodAnnotatedService() {
MethodAnnotatedService service = this.clientAdapter.createService(MethodAnnotatedService.class);
MethodLevelAnnotatedService service = this.clientAdapter.createService(MethodLevelAnnotatedService.class);
service.performGet();
HttpRequestSpec request = this.clientAdapter.getRequestSpec();
assertThat(request.getHttpMethod()).isEqualTo(HttpMethod.GET);
assertThat(request.getUriTemplate()).isNull();
assertThat(request.getHeaders().getContentType()).isNull();
assertThat(request.getHeaders().getAccept()).isEmpty();
HttpRequestValues requestValues = this.clientAdapter.getRequestValues();
assertThat(requestValues.getHttpMethod()).isEqualTo(HttpMethod.GET);
assertThat(requestValues.getUriTemplate()).isEqualTo("");
assertThat(requestValues.getHeaders().getContentType()).isNull();
assertThat(requestValues.getHeaders().getAccept()).isEmpty();
service.performPost();
request = this.clientAdapter.getRequestSpec();
assertThat(request.getHttpMethod()).isEqualTo(HttpMethod.POST);
assertThat(request.getUriTemplate()).isEqualTo("/url");
assertThat(request.getHeaders().getContentType()).isEqualTo(MediaType.APPLICATION_JSON);
assertThat(request.getHeaders().getAccept()).containsExactly(MediaType.APPLICATION_JSON);
requestValues = this.clientAdapter.getRequestValues();
assertThat(requestValues.getHttpMethod()).isEqualTo(HttpMethod.POST);
assertThat(requestValues.getUriTemplate()).isEqualTo("/url");
assertThat(requestValues.getHeaders().getContentType()).isEqualTo(MediaType.APPLICATION_JSON);
assertThat(requestValues.getHeaders().getAccept()).containsExactly(MediaType.APPLICATION_JSON);
}
@Test
void typeAndMethodAnnotatedService() {
MethodAnnotatedService service = this.clientAdapter.createService(TypeAndMethodAnnotatedService.class);
MethodLevelAnnotatedService service = this.clientAdapter.createService(TypeAndMethodLevelAnnotatedService.class);
service.performGet();
HttpRequestSpec request = this.clientAdapter.getRequestSpec();
assertThat(request.getHttpMethod()).isEqualTo(HttpMethod.GET);
assertThat(request.getUriTemplate()).isEqualTo("/base");
assertThat(request.getHeaders().getContentType()).isEqualTo(MediaType.APPLICATION_CBOR);
assertThat(request.getHeaders().getAccept()).containsExactly(MediaType.APPLICATION_CBOR);
HttpRequestValues requestValues = this.clientAdapter.getRequestValues();
assertThat(requestValues.getHttpMethod()).isEqualTo(HttpMethod.GET);
assertThat(requestValues.getUriTemplate()).isEqualTo("/base");
assertThat(requestValues.getHeaders().getContentType()).isEqualTo(MediaType.APPLICATION_CBOR);
assertThat(requestValues.getHeaders().getAccept()).containsExactly(MediaType.APPLICATION_CBOR);
service.performPost();
request = this.clientAdapter.getRequestSpec();
assertThat(request.getHttpMethod()).isEqualTo(HttpMethod.POST);
assertThat(request.getUriTemplate()).isEqualTo("/base/url");
assertThat(request.getHeaders().getContentType()).isEqualTo(MediaType.APPLICATION_JSON);
assertThat(request.getHeaders().getAccept()).containsExactly(MediaType.APPLICATION_JSON);
requestValues = this.clientAdapter.getRequestValues();
assertThat(requestValues.getHttpMethod()).isEqualTo(HttpMethod.POST);
assertThat(requestValues.getUriTemplate()).isEqualTo("/base/url");
assertThat(requestValues.getHeaders().getContentType()).isEqualTo(MediaType.APPLICATION_JSON);
assertThat(requestValues.getHeaders().getAccept()).containsExactly(MediaType.APPLICATION_JSON);
}
private void verifyClientInvocation(String methodName, @Nullable ParameterizedTypeReference<?> expectedBodyType) {
@@ -191,7 +191,7 @@ public class HttpServiceMethodTests {
@SuppressWarnings("unused")
private interface ReactorService {
@HttpExchange
@GetExchange
Mono<Void> execute();
@GetExchange
@@ -217,7 +217,7 @@ public class HttpServiceMethodTests {
@SuppressWarnings("unused")
private interface RxJavaService {
@HttpExchange
@GetExchange
Completable execute();
@GetExchange
@@ -243,7 +243,7 @@ public class HttpServiceMethodTests {
@SuppressWarnings("unused")
private interface BlockingService {
@HttpExchange
@GetExchange
void execute();
@GetExchange
@@ -261,7 +261,7 @@ public class HttpServiceMethodTests {
@SuppressWarnings("unused")
private interface MethodAnnotatedService {
private interface MethodLevelAnnotatedService {
@GetExchange
void performGet();
@@ -274,7 +274,7 @@ public class HttpServiceMethodTests {
@SuppressWarnings("unused")
@HttpExchange(url = "/base", contentType = APPLICATION_CBOR_VALUE, accept = APPLICATION_CBOR_VALUE)
private interface TypeAndMethodAnnotatedService extends MethodAnnotatedService {
private interface TypeAndMethodLevelAnnotatedService extends MethodLevelAnnotatedService {
}
}

View File

@@ -24,7 +24,7 @@ import org.junit.jupiter.api.Test;
import org.springframework.core.convert.support.DefaultConversionService;
import org.springframework.lang.Nullable;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.service.annotation.HttpExchange;
import org.springframework.web.service.annotation.GetExchange;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
@@ -143,44 +143,44 @@ class PathVariableArgumentResolverTests {
}
private Map<String, String> getActualUriVariables() {
return this.clientAdapter.getRequestSpec().getUriVariables();
return this.clientAdapter.getRequestValues().getUriVariables();
}
@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
private interface Service {
@HttpExchange
@GetExchange
void execute(@PathVariable String id);
@HttpExchange
@GetExchange
void executeNotRequired(@Nullable @PathVariable(required = false) String id);
@HttpExchange
@GetExchange
void executeOptional(@PathVariable Optional<Boolean> id);
@HttpExchange
@GetExchange
void executeOptionalNotRequired(@PathVariable(required = false) Optional<String> id);
@HttpExchange
@GetExchange
void executeNamedWithValue(@Nullable @PathVariable(name = "test", value = "id") String employeeId);
@HttpExchange
@GetExchange
void executeNamed(@PathVariable(name = "id") String employeeId);
@HttpExchange
@GetExchange
void executeValueNamed(@PathVariable("id") String employeeId);
@HttpExchange
@GetExchange
void execute(@PathVariable Object id);
@HttpExchange
@GetExchange
void execute(@PathVariable Boolean id);
@HttpExchange
@GetExchange
void executeValueMap(@Nullable @PathVariable Map<String, String> map);
@HttpExchange
@GetExchange
void executeOptionalValueMap(@PathVariable Map<String, Optional<String>> map);
}

View File

@@ -44,7 +44,7 @@ class TestHttpClientAdapter implements HttpClientAdapter {
private String invokedMethodName;
@Nullable
private HttpRequestSpec requestSpec;
private HttpRequestValues requestValues;
@Nullable
private ParameterizedTypeReference<?> bodyType;
@@ -67,9 +67,9 @@ class TestHttpClientAdapter implements HttpClientAdapter {
return this.invokedMethodName;
}
public HttpRequestSpec getRequestSpec() {
assertThat(this.requestSpec).isNotNull();
return this.requestSpec;
public HttpRequestValues getRequestValues() {
assertThat(this.requestValues).isNotNull();
return this.requestValues;
}
@Nullable
@@ -81,56 +81,56 @@ class TestHttpClientAdapter implements HttpClientAdapter {
// HttpClientAdapter implementation
@Override
public Mono<Void> requestToVoid(HttpRequestSpec requestSpec) {
saveInput("requestToVoid", requestSpec, null);
public Mono<Void> requestToVoid(HttpRequestValues requestValues) {
saveInput("requestToVoid", requestValues, null);
return Mono.empty();
}
@Override
public Mono<HttpHeaders> requestToHeaders(HttpRequestSpec requestSpec) {
saveInput("requestToHeaders", requestSpec, null);
public Mono<HttpHeaders> requestToHeaders(HttpRequestValues requestValues) {
saveInput("requestToHeaders", requestValues, null);
return Mono.just(new HttpHeaders());
}
@Override
public <T> Mono<T> requestToBody(HttpRequestSpec requestSpec, ParameterizedTypeReference<T> bodyType) {
saveInput("requestToBody", requestSpec, bodyType);
public <T> Mono<T> requestToBody(HttpRequestValues requestValues, ParameterizedTypeReference<T> bodyType) {
saveInput("requestToBody", requestValues, bodyType);
return (Mono<T>) Mono.just(getInvokedMethodName());
}
@Override
public <T> Flux<T> requestToBodyFlux(HttpRequestSpec requestSpec, ParameterizedTypeReference<T> bodyType) {
saveInput("requestToBodyFlux", requestSpec, bodyType);
public <T> Flux<T> requestToBodyFlux(HttpRequestValues requestValues, ParameterizedTypeReference<T> bodyType) {
saveInput("requestToBodyFlux", requestValues, bodyType);
return (Flux<T>) Flux.just("request", "To", "Body", "Flux");
}
@Override
public Mono<ResponseEntity<Void>> requestToBodilessEntity(HttpRequestSpec requestSpec) {
saveInput("requestToBodilessEntity", requestSpec, null);
public Mono<ResponseEntity<Void>> requestToBodilessEntity(HttpRequestValues requestValues) {
saveInput("requestToBodilessEntity", requestValues, null);
return Mono.just(ResponseEntity.ok().build());
}
@Override
public <T> Mono<ResponseEntity<T>> requestToEntity(
HttpRequestSpec requestSpec, ParameterizedTypeReference<T> type) {
HttpRequestValues requestValues, ParameterizedTypeReference<T> type) {
saveInput("requestToEntity", requestSpec, type);
saveInput("requestToEntity", requestValues, type);
return Mono.just((ResponseEntity<T>) ResponseEntity.ok("requestToEntity"));
}
@Override
public <T> Mono<ResponseEntity<Flux<T>>> requestToEntityFlux(
HttpRequestSpec requestSpec, ParameterizedTypeReference<T> bodyType) {
HttpRequestValues requestValues, ParameterizedTypeReference<T> bodyType) {
saveInput("requestToEntityFlux", requestSpec, bodyType);
saveInput("requestToEntityFlux", requestValues, bodyType);
return Mono.just(ResponseEntity.ok((Flux<T>) Flux.just("request", "To", "Entity", "Flux")));
}
private <T> void saveInput(
String methodName, HttpRequestSpec requestSpec, @Nullable ParameterizedTypeReference<T> bodyType) {
String methodName, HttpRequestValues requestValues, @Nullable ParameterizedTypeReference<T> bodyType) {
this.invokedMethodName = methodName;
this.requestSpec = requestSpec;
this.requestValues = requestValues;
this.bodyType = bodyType;
}