/** * Convert to a {@link String} inbound {@link Flux} using the default {@link Charset}. * * @return a {@link String} inbound {@link Flux} */ public final Flux<String> asString() { return asString(Charset.defaultCharset()); }
/** * Disable auto memory release on each buffer published, retaining in order to prevent * premature recycling when buffers are accumulated downstream (async). * * @return {@link ByteBufFlux} of retained {@link ByteBuf} */ public ByteBufFlux retain() { return new ByteBufFlux(doOnNext(ByteBuf::retain), alloc); }
/** * Decorate as {@link ByteBufFlux} * * @param source publisher to decorate * * @return a {@link ByteBufFlux} */ public static ByteBufFlux fromInbound(Publisher<?> source) { return fromInbound(source, ByteBufAllocator.DEFAULT); }
@Test public void hoverflyProxy() { Mono<HttpClientResponse> remote = HttpClient.create(o -> o.httpProxy(ops -> ops .address(new InetSocketAddress("localhost", hoverflyRule.getProxyPort())) )) .get("http://www.my-test.com/api/bookings/1", HttpClientRequest::sendHeaders); Mono<String> page = remote .flatMapMany(r -> r.receive() .retain() .asString() .limitRate(1)) .reduce(String::concat); StepVerifier.create(page) .expectNextMatches(s -> s.contains("bookingId")) .expectComplete() .verify(Duration.ofSeconds(30)); } }
/** * Open a {@link java.nio.channels.FileChannel} from a path and stream * {@link ByteBuf} chunks with a default maximum size of 500K into * the returned {@link ByteBufFlux} * * @param path the path to the resource to stream * * @return a {@link ByteBufFlux} */ public static ByteBufFlux fromPath(Path path) { return fromPath(path, MAX_CHUNK_SIZE); }
/** * Convert to a {@literal byte[]} inbound {@link Flux} * * @return a {@literal byte[]} inbound {@link Flux} */ public final Flux<byte[]> asByteArray() { return handle((bb, sink) -> { try { byte[] bytes = new byte[bb.readableBytes()]; bb.readBytes(bytes); sink.next(bytes); } catch (IllegalReferenceCountException e) { sink.complete(); } }); }
/** * Decorate as {@link ByteBufFlux} * * @param source publisher to decorate * @param allocator the channel {@link ByteBufAllocator} * * @return a {@link ByteBufFlux} */ public static ByteBufFlux fromInbound(Publisher<?> source, ByteBufAllocator allocator) { Objects.requireNonNull(allocator, "allocator"); return new ByteBufFlux(Flux.from(source) .map(bytebufExtractor), allocator); }
private static Function<Integer, Mono<InputStream>> zipkinServerStream(String zipkinUrl, Mono<HttpClient> client) { return lookbackSeconds -> client .flatMap(c -> c .get(zipkinQuery(zipkinUrl, lookbackSeconds)) .flatMap(resp -> resp.receive() .aggregate() .asInputStream())); }
/** * Aggregate subsequent byte buffers into a single buffer. * * @return {@link ByteBufMono} of aggregated {@link ByteBuf} */ public ByteBufMono aggregate() { return Mono.using(alloc::compositeBuffer, b -> this.reduce(b, (prev, next) -> prev.addComponent(next.retain())) .doOnNext(cbb -> cbb.writerIndex(cbb.capacity())) .filter(ByteBuf::isReadable), ByteBuf::release).as(ByteBufMono::new); }
/** * Open a {@link java.nio.channels.FileChannel} from a path and stream * {@link ByteBuf} chunks with a given maximum size into the returned {@link ByteBufFlux} * * @param path the path to the resource to stream * @param maxChunkSize the maximum per-item ByteBuf size * * @return a {@link ByteBufFlux} */ public static ByteBufFlux fromPath(Path path, int maxChunkSize) { return fromPath(path, maxChunkSize, ByteBufAllocator.DEFAULT); }
/** * Convert to a {@link String} inbound {@link Flux} using the provided {@link Charset}. * * @param charset the decoding charset * * @return a {@link String} inbound {@link Flux} */ public final Flux<String> asString(Charset charset) { return handle((bb, sink) -> { try { sink.next(bb.toString(charset)); } catch (IllegalReferenceCountException e) { sink.complete(); } }); }
throw new IllegalArgumentException("chunk size must be strictly positive, " + "was: " + maxChunkSize); return new ByteBufFlux(Flux.generate(() -> FileChannel.open(path), (fc, sink) -> { ByteBuf buf = allocator.buffer(); try {
/** * Open a {@link java.nio.channels.FileChannel} from a path and stream * {@link ByteBuf} chunks with a default maximum size of 500K into the returned * {@link ByteBufFlux}, using the provided {@link ByteBufAllocator}. * * @param path the path to the resource to stream * @param allocator the channel {@link ByteBufAllocator} * * @return a {@link ByteBufFlux} */ public static ByteBufFlux fromPath(Path path, ByteBufAllocator allocator) { return fromPath(path, MAX_CHUNK_SIZE, allocator); }
/** * Convert to a {@link ByteBuffer} inbound {@link Flux} * * @return a {@link ByteBuffer} inbound {@link Flux} */ public final Flux<ByteBuffer> asByteBuffer() { return handle((bb, sink) -> { try { sink.next(bb.nioBuffer()); } catch (IllegalReferenceCountException e) { sink.complete(); } }); }
/** * A {@link Flux} extension that allows for extra decoding operators * @return a new {@link ByteBufFlux} */ default ByteBufFlux receive() { return ByteBufFlux.fromInbound(receiveObject(), context().channel() .alloc()); }
/** * Listen for HTTP GET on the passed path to be used as a routing condition. The * file on the provided {@link Path} is served. * <p> * Additional regex matching is available e.g. * "/test/{param}". Params are resolved using {@link HttpServerRequest#param(CharSequence)} * * @param uri The {@link HttpPredicate} to use to trigger the route, pattern matching * and capture are supported * @param path the Path to the file to serve * @param interceptor a channel pre-intercepting handler e.g. for content type header * * @return this {@link HttpServerRoutes} */ default HttpServerRoutes file(Predicate<HttpServerRequest> uri, Path path, Function<HttpServerResponse, HttpServerResponse> interceptor) { Objects.requireNonNull(path, "path"); return route(uri, (req, resp) -> { if (!Files.isReadable(path)) { return resp.send(ByteBufFlux.fromPath(path)); } if (interceptor != null) { return interceptor.apply(resp) .sendFile(path); } return resp.sendFile(path); }); }
/** * Convert to a {@link InputStream} inbound {@link Flux} * * @return a {@link InputStream} inbound {@link Flux} */ public Flux<InputStream> asInputStream() { return handle((bb, sink) -> { try { sink.next(new ByteBufMono.ReleasingInputStream(bb)); } catch (IllegalReferenceCountException e) { sink.complete(); } }); }