use of org.springframework.core.io.buffer.DataBuffer in project spring-integration by spring-projects.
the class WebFluxRequestExecutingMessageHandler method exchange.
@Override
protected Object exchange(Supplier<URI> uriSupplier, HttpMethod httpMethod, HttpEntity<?> httpRequest, Object expectedResponseType, Message<?> requestMessage) {
WebClient.RequestBodySpec requestSpec = this.webClient.method(httpMethod).uri(b -> uriSupplier.get()).headers(headers -> headers.putAll(httpRequest.getHeaders()));
if (httpRequest.hasBody()) {
requestSpec.body(BodyInserters.fromObject(httpRequest.getBody()));
}
Mono<ClientResponse> responseMono = requestSpec.exchange().flatMap(response -> {
HttpStatus httpStatus = response.statusCode();
if (httpStatus.isError()) {
return response.body(BodyExtractors.toDataBuffers()).reduce(DataBuffer::write).map(dataBuffer -> {
byte[] bytes = new byte[dataBuffer.readableByteCount()];
dataBuffer.read(bytes);
DataBufferUtils.release(dataBuffer);
return bytes;
}).defaultIfEmpty(new byte[0]).map(bodyBytes -> {
throw new WebClientResponseException("ClientResponse has erroneous status code: " + httpStatus.value() + " " + httpStatus.getReasonPhrase(), httpStatus.value(), httpStatus.getReasonPhrase(), response.headers().asHttpHeaders(), bodyBytes, response.headers().contentType().map(MimeType::getCharset).orElse(StandardCharsets.ISO_8859_1));
});
} else {
return Mono.just(response);
}
});
if (isExpectReply()) {
return responseMono.flatMap(response -> {
ResponseEntity.BodyBuilder httpEntityBuilder = ResponseEntity.status(response.statusCode()).headers(response.headers().asHttpHeaders());
Mono<?> bodyMono;
if (expectedResponseType != null) {
if (this.replyPayloadToFlux) {
BodyExtractor<? extends Flux<?>, ReactiveHttpInputMessage> extractor;
if (expectedResponseType instanceof ParameterizedTypeReference<?>) {
extractor = BodyExtractors.toFlux((ParameterizedTypeReference<?>) expectedResponseType);
} else {
extractor = BodyExtractors.toFlux((Class<?>) expectedResponseType);
}
Flux<?> flux = response.body(extractor);
bodyMono = Mono.just(flux);
} else {
BodyExtractor<? extends Mono<?>, ReactiveHttpInputMessage> extractor;
if (expectedResponseType instanceof ParameterizedTypeReference<?>) {
extractor = BodyExtractors.toMono((ParameterizedTypeReference<?>) expectedResponseType);
} else {
extractor = BodyExtractors.toMono((Class<?>) expectedResponseType);
}
bodyMono = response.body(extractor);
}
} else if (this.bodyExtractor != null) {
Object body = response.body(this.bodyExtractor);
if (body instanceof Mono) {
bodyMono = (Mono<?>) body;
} else {
bodyMono = Mono.just(body);
}
} else {
bodyMono = Mono.empty();
}
return bodyMono.map(httpEntityBuilder::body).defaultIfEmpty(httpEntityBuilder.build());
}).map(this::getReply);
} else {
responseMono.subscribe(v -> {
}, ex -> sendErrorMessage(requestMessage, ex));
return null;
}
}
use of org.springframework.core.io.buffer.DataBuffer in project spring-integration by spring-projects.
the class WebFluxRequestExecutingMessageHandlerTests method testFluxReply.
@Test
@SuppressWarnings("unchecked")
public void testFluxReply() {
ClientHttpConnector httpConnector = new HttpHandlerConnector((request, response) -> {
response.setStatusCode(HttpStatus.OK);
response.getHeaders().setContentType(MediaType.TEXT_PLAIN);
DataBufferFactory bufferFactory = response.bufferFactory();
Mono<DataBuffer> data = Mono.just(bufferFactory.wrap("foo\nbar\nbaz".getBytes()));
return response.writeWith(data).then(Mono.defer(response::setComplete));
});
WebClient webClient = WebClient.builder().clientConnector(httpConnector).build();
String destinationUri = "http://www.springsource.org/spring-integration";
WebFluxRequestExecutingMessageHandler reactiveHandler = new WebFluxRequestExecutingMessageHandler(destinationUri, webClient);
QueueChannel replyChannel = new QueueChannel();
reactiveHandler.setOutputChannel(replyChannel);
reactiveHandler.setExpectedResponseType(String.class);
reactiveHandler.setReplyPayloadToFlux(true);
reactiveHandler.handleMessage(MessageBuilder.withPayload("hello, world").build());
Message<?> receive = replyChannel.receive(10_000);
assertNotNull(receive);
assertThat(receive.getPayload(), instanceOf(Flux.class));
Flux<String> flux = (Flux<String>) receive.getPayload();
StepVerifier.create(flux).expectNext("foo", "bar", "baz").verifyComplete();
}
use of org.springframework.core.io.buffer.DataBuffer in project spring-integration by spring-projects.
the class WebFluxRequestExecutingMessageHandlerTests method testClientHttpResponseAsReply.
@Test
public void testClientHttpResponseAsReply() {
ClientHttpConnector httpConnector = new HttpHandlerConnector((request, response) -> {
response.setStatusCode(HttpStatus.OK);
response.getHeaders().setContentType(MediaType.TEXT_PLAIN);
DataBufferFactory bufferFactory = response.bufferFactory();
Flux<DataBuffer> data = Flux.just(bufferFactory.wrap("foo".getBytes()), bufferFactory.wrap("bar".getBytes()), bufferFactory.wrap("baz".getBytes()));
return response.writeWith(data).then(Mono.defer(response::setComplete));
});
WebClient webClient = WebClient.builder().clientConnector(httpConnector).build();
String destinationUri = "http://www.springsource.org/spring-integration";
WebFluxRequestExecutingMessageHandler reactiveHandler = new WebFluxRequestExecutingMessageHandler(destinationUri, webClient);
QueueChannel replyChannel = new QueueChannel();
reactiveHandler.setOutputChannel(replyChannel);
reactiveHandler.setBodyExtractor(new ClientHttpResponseBodyExtractor());
reactiveHandler.handleMessage(MessageBuilder.withPayload("hello, world").build());
Message<?> receive = replyChannel.receive(10_000);
assertNotNull(receive);
assertThat(receive.getPayload(), instanceOf(ClientHttpResponse.class));
ClientHttpResponse response = (ClientHttpResponse) receive.getPayload();
assertEquals(HttpStatus.OK, response.getStatusCode());
assertEquals(MediaType.TEXT_PLAIN, response.getHeaders().getContentType());
StepVerifier.create(response.getBody().map(dataBuffer -> new String(dataBuffer.asByteBuffer().array()))).expectNext("foo", "bar", "baz").verifyComplete();
}
use of org.springframework.core.io.buffer.DataBuffer in project spring-boot-admin by codecentric.
the class InstancesProxyController method endpointProxy.
@ResponseBody
@RequestMapping(path = APPLICATION_MAPPED_PATH, method = { RequestMethod.GET, RequestMethod.HEAD, RequestMethod.POST, RequestMethod.PUT, RequestMethod.PATCH, RequestMethod.DELETE, RequestMethod.OPTIONS })
public Flux<InstanceWebProxy.InstanceResponse> endpointProxy(@PathVariable("applicationName") String applicationName, HttpServletRequest servletRequest) {
ServletServerHttpRequest request = new ServletServerHttpRequest(servletRequest);
Flux<DataBuffer> cachedBody = DataBufferUtils.readInputStream(request::getBody, this.bufferFactory, 4096).cache();
InstanceWebProxy.ForwardRequest fwdRequest = createForwardRequest(request, cachedBody, this.adminContextPath + APPLICATION_MAPPED_PATH);
return this.instanceWebProxy.forward(this.registry.getInstances(applicationName), fwdRequest);
}
use of org.springframework.core.io.buffer.DataBuffer in project spring-boot-admin by codecentric.
the class InstancesProxyController method endpointProxy.
@ResponseBody
@RequestMapping(path = INSTANCE_MAPPED_PATH, method = { RequestMethod.GET, RequestMethod.HEAD, RequestMethod.POST, RequestMethod.PUT, RequestMethod.PATCH, RequestMethod.DELETE, RequestMethod.OPTIONS })
public void endpointProxy(@PathVariable("instanceId") String instanceId, HttpServletRequest servletRequest, HttpServletResponse servletResponse) {
ServletServerHttpRequest request = new ServletServerHttpRequest(servletRequest);
Flux<DataBuffer> requestBody = DataBufferUtils.readInputStream(request::getBody, this.bufferFactory, 4096);
InstanceWebProxy.ForwardRequest fwdRequest = createForwardRequest(request, requestBody, this.adminContextPath + INSTANCE_MAPPED_PATH);
this.instanceWebProxy.forward(this.registry.getInstance(InstanceId.of(instanceId)), fwdRequest, (clientResponse) -> {
ServerHttpResponse response = new ServletServerHttpResponse(servletResponse);
response.setStatusCode(clientResponse.statusCode());
response.getHeaders().addAll(this.httpHeadersFilter.filterHeaders(clientResponse.headers().asHttpHeaders()));
try {
OutputStream responseBody = response.getBody();
response.flush();
return clientResponse.body(BodyExtractors.toDataBuffers()).window(1).concatMap((body) -> writeAndFlush(body, responseBody)).then();
} catch (IOException ex) {
return Mono.error(ex);
}
}).block();
}
Aggregations