Search in sources :

Example 1 with BufferAllocator

use of io.servicetalk.buffer.api.BufferAllocator in project servicetalk by apple.

the class HelloWorldJaxRsResource method randomHello.

/**
 * Resource that only relies on {@link Single}/{@link Publisher} for consuming and producing data,
 * and returns a JAX-RS {@link Response} in order to set its status.
 * No OIO adaptation is involved when requests are dispatched to it,
 * allowing it to fully benefit from ReactiveStream's features like flow control.
 * Behind the scene, ServiceTalk's aggregation mechanism is used to provide the resource with a
 * {@link Single Single<Buffer>} that contains the whole request entity as a {@link Buffer}.
 * Note that the {@link ConnectionContext} could also be injected into a class-level {@code @Context} field.
 * <p>
 * Test with:
 * <pre>
 * curl -i -H 'content-type: text/plain' -d 'kitty' http://localhost:8080/greetings/random-hello
 * </pre>
 *
 * @param who the recipient of the greetings.
 * @param ctx the {@link ConnectionContext}.
 * @return greetings as a JAX-RS {@link Response}.
 */
@POST
@Path("random-hello")
@Consumes(TEXT_PLAIN)
@Produces(TEXT_PLAIN)
public Response randomHello(final Single<Buffer> who, @Context final ConnectionContext ctx) {
    if (random() < .5) {
        return accepted("greetings accepted, call again for a response").build();
    }
    final BufferAllocator allocator = ctx.executionContext().bufferAllocator();
    final Publisher<Buffer> payload = from(allocator.fromAscii("hello ")).concat(who);
    // Wrap content Publisher to capture its generic type (i.e. Buffer) so it is handled correctly
    final GenericEntity<Publisher<Buffer>> entity = new GenericEntity<Publisher<Buffer>>(payload) {
    };
    return ok(entity).build();
}
Also used : CompositeBuffer(io.servicetalk.buffer.api.CompositeBuffer) Buffer(io.servicetalk.buffer.api.Buffer) GenericEntity(javax.ws.rs.core.GenericEntity) Publisher(io.servicetalk.concurrent.api.Publisher) BufferAllocator(io.servicetalk.buffer.api.BufferAllocator) Path(javax.ws.rs.Path) POST(javax.ws.rs.POST) Consumes(javax.ws.rs.Consumes) Produces(javax.ws.rs.Produces)

Example 2 with BufferAllocator

use of io.servicetalk.buffer.api.BufferAllocator in project servicetalk by apple.

the class HttpDataSourceTransformations method aggregatePayloadAndTrailers.

static Single<PayloadAndTrailers> aggregatePayloadAndTrailers(final DefaultPayloadInfo payloadInfo, final Publisher<?> payloadAndTrailers, final BufferAllocator allocator) {
    if (payloadAndTrailers == empty()) {
        payloadInfo.setEmpty(true).setMayHaveTrailersAndGenericTypeBuffer(false);
        return succeeded(EMPTY_PAYLOAD_AND_TRAILERS);
    }
    return payloadAndTrailers.collect(PayloadAndTrailers::new, (pair, nextItem) -> {
        if (nextItem instanceof Buffer) {
            try {
                Buffer buffer = (Buffer) nextItem;
                if (isAlwaysEmpty(pair.payload)) {
                    pair.payload = buffer;
                } else if (pair.payload instanceof CompositeBuffer) {
                    ((CompositeBuffer) pair.payload).addBuffer(buffer);
                } else {
                    Buffer oldBuffer = pair.payload;
                    pair.payload = allocator.newCompositeBuffer(MAX_VALUE).addBuffer(oldBuffer).addBuffer(buffer);
                }
            } catch (IllegalArgumentException cause) {
                BufferOverflowException ex = new BufferOverflowException();
                ex.initCause(cause);
                throw ex;
            }
        } else if (nextItem instanceof HttpHeaders) {
            pair.trailers = (HttpHeaders) nextItem;
        } else {
            throw new UnsupportedHttpChunkException(nextItem);
        }
        return pair;
    }).map(pair -> {
        if (isAlwaysEmpty(pair.payload)) {
            payloadInfo.setEmpty(true);
        }
        if (pair.trailers == null) {
            payloadInfo.setMayHaveTrailersAndGenericTypeBuffer(false);
        }
        return pair;
    });
}
Also used : AtomicIntegerFieldUpdater(java.util.concurrent.atomic.AtomicIntegerFieldUpdater) Publisher(io.servicetalk.concurrent.api.Publisher) BufferOverflowException(java.nio.BufferOverflowException) NANOSECONDS(java.util.concurrent.TimeUnit.NANOSECONDS) MAX_VALUE(java.lang.Integer.MAX_VALUE) TimeoutException(java.util.concurrent.TimeoutException) ConcurrentSubscription(io.servicetalk.concurrent.internal.ConcurrentSubscription) Publisher.empty(io.servicetalk.concurrent.api.Publisher.empty) Subscriber(io.servicetalk.concurrent.PublisherSource.Subscriber) EMPTY_BUFFER(io.servicetalk.buffer.api.EmptyBuffer.EMPTY_BUFFER) SubscriberUtils.checkDuplicateSubscription(io.servicetalk.concurrent.internal.SubscriberUtils.checkDuplicateSubscription) Single.succeeded(io.servicetalk.concurrent.api.Single.succeeded) Objects.requireNonNull(java.util.Objects.requireNonNull) DelayedSubscription(io.servicetalk.concurrent.internal.DelayedSubscription) NoSuchElementException(java.util.NoSuchElementException) AtomicIntegerFieldUpdater.newUpdater(java.util.concurrent.atomic.AtomicIntegerFieldUpdater.newUpdater) Nullable(javax.annotation.Nullable) Single(io.servicetalk.concurrent.api.Single) PublisherOperator(io.servicetalk.concurrent.api.PublisherOperator) Subscription(io.servicetalk.concurrent.PublisherSource.Subscription) SourceAdapters.toSource(io.servicetalk.concurrent.api.SourceAdapters.toSource) CompositeBuffer(io.servicetalk.buffer.api.CompositeBuffer) System.nanoTime(java.lang.System.nanoTime) BlockingIterable(io.servicetalk.concurrent.BlockingIterable) TimeUnit(java.util.concurrent.TimeUnit) Buffer(io.servicetalk.buffer.api.Buffer) BufferAllocator(io.servicetalk.buffer.api.BufferAllocator) BlockingIterator(io.servicetalk.concurrent.BlockingIterator) CompositeBuffer(io.servicetalk.buffer.api.CompositeBuffer) Buffer(io.servicetalk.buffer.api.Buffer) CompositeBuffer(io.servicetalk.buffer.api.CompositeBuffer) BufferOverflowException(java.nio.BufferOverflowException)

Example 3 with BufferAllocator

use of io.servicetalk.buffer.api.BufferAllocator in project servicetalk by apple.

the class JacksonSerializerMessageBodyReaderWriter method writeTo.

@SuppressWarnings({ "rawtypes", "unchecked" })
@Override
public void writeTo(final Object o, final Class<?> type, final Type genericType, final Annotation[] annotations, final MediaType mediaType, final MultivaluedMap<String, Object> httpHeaders, final OutputStream entityStream) throws WebApplicationException {
    final boolean oldJacksonProviderPresent = providers.getContextResolver(JacksonSerializationProvider.class, mediaType) != null;
    if (oldJacksonProviderPresent) {
        // FIXME 0.43 - Remove deprecation
        writeToOld(o, type, genericType, annotations, mediaType, httpHeaders, entityStream);
        return;
    }
    final BufferAllocator allocator = ctxRefProvider.get().get().executionContext().bufferAllocator();
    final Publisher<Buffer> bufferPublisher;
    if (o instanceof Single) {
        final Class<?> clazz = genericType instanceof Class ? (Class) genericType : getSourceClass(genericType);
        Serializer serializer = getJacksonSerializerFactory(mediaType).serializerDeserializer(clazz);
        bufferPublisher = ((Single) o).map(t -> serializer.serialize(t, allocator)).toPublisher();
    } else if (o instanceof Publisher) {
        final Class<?> clazz = genericType instanceof Class ? (Class) genericType : getSourceClass(genericType);
        StreamingSerializer serializer = getJacksonSerializerFactory(mediaType).streamingSerializerDeserializer(clazz);
        bufferPublisher = serializer.serialize((Publisher) o, allocator);
    } else {
        Serializer serializer = getJacksonSerializerFactory(mediaType).serializerDeserializer(o.getClass());
        bufferPublisher = Publisher.from(serializer.serialize(o, allocator));
    }
    setResponseBufferPublisher(bufferPublisher, requestCtxProvider.get());
}
Also used : Buffer(io.servicetalk.buffer.api.Buffer) Single(io.servicetalk.concurrent.api.Single) JacksonSerializationProvider(io.servicetalk.data.jackson.JacksonSerializationProvider) Publisher(io.servicetalk.concurrent.api.Publisher) RequestProperties.setResponseBufferPublisher(io.servicetalk.http.router.jersey.internal.RequestProperties.setResponseBufferPublisher) StreamingSerializer(io.servicetalk.serializer.api.StreamingSerializer) BufferAllocator(io.servicetalk.buffer.api.BufferAllocator) Serializer(io.servicetalk.serializer.api.Serializer) StreamingSerializer(io.servicetalk.serializer.api.StreamingSerializer) DefaultSerializer(io.servicetalk.serialization.api.DefaultSerializer)

Example 4 with BufferAllocator

use of io.servicetalk.buffer.api.BufferAllocator in project servicetalk by apple.

the class JacksonSerializerMessageBodyReaderWriter method readFrom.

@Override
public Object readFrom(final Class<Object> type, final Type genericType, final Annotation[] annotations, final MediaType mediaType, final MultivaluedMap<String, String> httpHeaders, final InputStream entityStream) throws WebApplicationException {
    final boolean oldJacksonProviderPresent = providers.getContextResolver(JacksonSerializationProvider.class, mediaType) != null;
    // FIXME 0.43 - Remove this branch when deprecation go away.
    if (oldJacksonProviderPresent) {
        return readFromOld(type, genericType, annotations, mediaType, httpHeaders, entityStream);
    } else {
        final JacksonSerializerFactory serializerFactory = getJacksonSerializerFactory(mediaType);
        final ExecutionContext<?> executionContext = ctxRefProvider.get().get().executionContext();
        final BufferAllocator allocator = executionContext.bufferAllocator();
        final int contentLength = requestCtxProvider.get().getLength();
        if (Single.class.isAssignableFrom(type)) {
            return handleEntityStream(entityStream, allocator, (p, a) -> deserialize(p, serializerFactory.serializerDeserializer(getSourceClass(genericType)), contentLength, a), (is, a) -> new SingleSource<>(deserialize(toBufferPublisher(is, a), serializerFactory.serializerDeserializer(getSourceClass(genericType)), contentLength, a)));
        } else if (Publisher.class.isAssignableFrom(type)) {
            return handleEntityStream(entityStream, allocator, (p, a) -> serializerFactory.streamingSerializerDeserializer(getSourceClass(genericType)).deserialize(p, a), (is, a) -> new PublisherSource<>(serializerFactory.streamingSerializerDeserializer(getSourceClass(genericType)).deserialize(toBufferPublisher(is, a), a)));
        }
        return handleEntityStream(entityStream, allocator, (p, a) -> deserializeObject(p, serializerFactory.serializerDeserializer(type), contentLength, a), (is, a) -> deserializeObject(toBufferPublisher(is, a), serializerFactory.serializerDeserializer(type), contentLength, a));
    }
}
Also used : ENTITY_CODER(javax.ws.rs.Priorities.ENTITY_CODER) SingleSource(io.servicetalk.http.router.jersey.internal.SourceWrappers.SingleSource) Provider(javax.inject.Provider) Produces(javax.ws.rs.Produces) Publisher(io.servicetalk.concurrent.api.Publisher) Deserializer(io.servicetalk.serializer.api.Deserializer) SerializationException(io.servicetalk.serializer.api.SerializationException) MessageBodyWriter(javax.ws.rs.ext.MessageBodyWriter) RequestProperties.setResponseBufferPublisher(io.servicetalk.http.router.jersey.internal.RequestProperties.setResponseBufferPublisher) WILDCARD(javax.ws.rs.core.MediaType.WILDCARD) ContainerRequestContext(javax.ws.rs.container.ContainerRequestContext) ResourceMethod(org.glassfish.jersey.server.model.ResourceMethod) ContextResolver(javax.ws.rs.ext.ContextResolver) MediaType(javax.ws.rs.core.MediaType) Ref(org.glassfish.jersey.internal.util.collection.Ref) Consumes(javax.ws.rs.Consumes) BadRequestException(javax.ws.rs.BadRequestException) NoSuchElementException(java.util.NoSuchElementException) ExtendedUriInfo(org.glassfish.jersey.server.ExtendedUriInfo) BufferPublisherInputStream.handleEntityStream(io.servicetalk.http.router.jersey.internal.BufferPublisherInputStream.handleEntityStream) ConnectionContext(io.servicetalk.transport.api.ConnectionContext) OutputStream(java.io.OutputStream) Serializer(io.servicetalk.serializer.api.Serializer) StreamingSerializer(io.servicetalk.serializer.api.StreamingSerializer) Context(javax.ws.rs.core.Context) Providers(javax.ws.rs.ext.Providers) Single(io.servicetalk.concurrent.api.Single) DefaultSerializer(io.servicetalk.serialization.api.DefaultSerializer) FutureUtils.awaitResult(io.servicetalk.concurrent.internal.FutureUtils.awaitResult) JacksonSerializerFactory(io.servicetalk.data.jackson.JacksonSerializerFactory) MultivaluedMap(javax.ws.rs.core.MultivaluedMap) Priority(javax.annotation.Priority) Buffer(io.servicetalk.buffer.api.Buffer) JacksonSerializationProvider(io.servicetalk.data.jackson.JacksonSerializationProvider) HttpHeaders(javax.ws.rs.core.HttpHeaders) ParameterizedType(java.lang.reflect.ParameterizedType) ExecutionContext(io.servicetalk.transport.api.ExecutionContext) Type(java.lang.reflect.Type) BufferAllocator(io.servicetalk.buffer.api.BufferAllocator) Annotation(java.lang.annotation.Annotation) WebApplicationException(javax.ws.rs.WebApplicationException) APPLICATION_JSON_TYPE(javax.ws.rs.core.MediaType.APPLICATION_JSON_TYPE) Publisher.fromInputStream(io.servicetalk.concurrent.api.Publisher.fromInputStream) PublisherSource(io.servicetalk.http.router.jersey.internal.SourceWrappers.PublisherSource) InputStream(java.io.InputStream) MessageBodyReader(javax.ws.rs.ext.MessageBodyReader) JacksonSerializerFactory(io.servicetalk.data.jackson.JacksonSerializerFactory) PublisherSource(io.servicetalk.http.router.jersey.internal.SourceWrappers.PublisherSource) JacksonSerializationProvider(io.servicetalk.data.jackson.JacksonSerializationProvider) Publisher(io.servicetalk.concurrent.api.Publisher) RequestProperties.setResponseBufferPublisher(io.servicetalk.http.router.jersey.internal.RequestProperties.setResponseBufferPublisher) BufferAllocator(io.servicetalk.buffer.api.BufferAllocator)

Example 5 with BufferAllocator

use of io.servicetalk.buffer.api.BufferAllocator in project servicetalk by apple.

the class JacksonSerializerMessageBodyReaderWriter method readFromOld.

// FIXME 0.43 - Remove this branch when deprecation go away.
@Deprecated
private Object readFromOld(final Class<Object> type, final Type genericType, final Annotation[] annotations, final MediaType mediaType, final MultivaluedMap<String, String> httpHeaders, final InputStream entityStream) throws WebApplicationException {
    final io.servicetalk.serialization.api.Serializer serializer = getSerializer(mediaType);
    final ExecutionContext<?> executionContext = ctxRefProvider.get().get().executionContext();
    final BufferAllocator allocator = executionContext.bufferAllocator();
    final int contentLength = requestCtxProvider.get().getLength();
    if (Single.class.isAssignableFrom(type)) {
        return handleEntityStream(entityStream, allocator, (p, a) -> deserializeOld(p, serializer, getSourceClass(genericType), contentLength, a), (is, a) -> new SingleSource<>(deserializeOld(toBufferPublisher(is, a), serializer, getSourceClass(genericType), contentLength, a)));
    } else if (Publisher.class.isAssignableFrom(type)) {
        return handleEntityStream(entityStream, allocator, (p, a) -> serializer.deserialize(p, getSourceClass(genericType)), (is, a) -> new PublisherSource<>(serializer.deserialize(toBufferPublisher(is, a), getSourceClass(genericType))));
    }
    return handleEntityStream(entityStream, allocator, (p, a) -> deserializeObjectOld(p, serializer, type, contentLength, a), (is, a) -> deserializeObjectOld(toBufferPublisher(is, a), serializer, type, contentLength, a));
}
Also used : ENTITY_CODER(javax.ws.rs.Priorities.ENTITY_CODER) SingleSource(io.servicetalk.http.router.jersey.internal.SourceWrappers.SingleSource) Provider(javax.inject.Provider) Produces(javax.ws.rs.Produces) Publisher(io.servicetalk.concurrent.api.Publisher) Deserializer(io.servicetalk.serializer.api.Deserializer) SerializationException(io.servicetalk.serializer.api.SerializationException) MessageBodyWriter(javax.ws.rs.ext.MessageBodyWriter) RequestProperties.setResponseBufferPublisher(io.servicetalk.http.router.jersey.internal.RequestProperties.setResponseBufferPublisher) WILDCARD(javax.ws.rs.core.MediaType.WILDCARD) ContainerRequestContext(javax.ws.rs.container.ContainerRequestContext) ResourceMethod(org.glassfish.jersey.server.model.ResourceMethod) ContextResolver(javax.ws.rs.ext.ContextResolver) MediaType(javax.ws.rs.core.MediaType) Ref(org.glassfish.jersey.internal.util.collection.Ref) Consumes(javax.ws.rs.Consumes) BadRequestException(javax.ws.rs.BadRequestException) NoSuchElementException(java.util.NoSuchElementException) ExtendedUriInfo(org.glassfish.jersey.server.ExtendedUriInfo) BufferPublisherInputStream.handleEntityStream(io.servicetalk.http.router.jersey.internal.BufferPublisherInputStream.handleEntityStream) ConnectionContext(io.servicetalk.transport.api.ConnectionContext) OutputStream(java.io.OutputStream) Serializer(io.servicetalk.serializer.api.Serializer) StreamingSerializer(io.servicetalk.serializer.api.StreamingSerializer) Context(javax.ws.rs.core.Context) Providers(javax.ws.rs.ext.Providers) Single(io.servicetalk.concurrent.api.Single) DefaultSerializer(io.servicetalk.serialization.api.DefaultSerializer) FutureUtils.awaitResult(io.servicetalk.concurrent.internal.FutureUtils.awaitResult) JacksonSerializerFactory(io.servicetalk.data.jackson.JacksonSerializerFactory) MultivaluedMap(javax.ws.rs.core.MultivaluedMap) Priority(javax.annotation.Priority) Buffer(io.servicetalk.buffer.api.Buffer) JacksonSerializationProvider(io.servicetalk.data.jackson.JacksonSerializationProvider) HttpHeaders(javax.ws.rs.core.HttpHeaders) ParameterizedType(java.lang.reflect.ParameterizedType) ExecutionContext(io.servicetalk.transport.api.ExecutionContext) Type(java.lang.reflect.Type) BufferAllocator(io.servicetalk.buffer.api.BufferAllocator) Annotation(java.lang.annotation.Annotation) WebApplicationException(javax.ws.rs.WebApplicationException) APPLICATION_JSON_TYPE(javax.ws.rs.core.MediaType.APPLICATION_JSON_TYPE) Publisher.fromInputStream(io.servicetalk.concurrent.api.Publisher.fromInputStream) PublisherSource(io.servicetalk.http.router.jersey.internal.SourceWrappers.PublisherSource) InputStream(java.io.InputStream) MessageBodyReader(javax.ws.rs.ext.MessageBodyReader) PublisherSource(io.servicetalk.http.router.jersey.internal.SourceWrappers.PublisherSource) Publisher(io.servicetalk.concurrent.api.Publisher) RequestProperties.setResponseBufferPublisher(io.servicetalk.http.router.jersey.internal.RequestProperties.setResponseBufferPublisher) BufferAllocator(io.servicetalk.buffer.api.BufferAllocator)

Aggregations

BufferAllocator (io.servicetalk.buffer.api.BufferAllocator)23 Buffer (io.servicetalk.buffer.api.Buffer)15 StreamingHttpClient (io.servicetalk.http.api.StreamingHttpClient)10 HttpServerContext (io.servicetalk.http.api.HttpServerContext)9 StreamingHttpConnection (io.servicetalk.http.api.StreamingHttpConnection)9 ParameterizedTest (org.junit.jupiter.params.ParameterizedTest)9 MethodSource (org.junit.jupiter.params.provider.MethodSource)9 Consumes (javax.ws.rs.Consumes)7 Produces (javax.ws.rs.Produces)7 CompositeBuffer (io.servicetalk.buffer.api.CompositeBuffer)6 Publisher (io.servicetalk.concurrent.api.Publisher)6 SingleAddressHttpClientBuilder (io.servicetalk.http.api.SingleAddressHttpClientBuilder)6 StreamingHttpResponse (io.servicetalk.http.api.StreamingHttpResponse)6 RedirectConfigBuilder (io.servicetalk.http.api.RedirectConfigBuilder)5 Single (io.servicetalk.concurrent.api.Single)4 JacksonSerializationProvider (io.servicetalk.data.jackson.JacksonSerializationProvider)3 HttpConnection (io.servicetalk.http.api.HttpConnection)3 HttpResponse (io.servicetalk.http.api.HttpResponse)3 RequestProperties.setResponseBufferPublisher (io.servicetalk.http.router.jersey.internal.RequestProperties.setResponseBufferPublisher)3 DefaultSerializer (io.servicetalk.serialization.api.DefaultSerializer)3