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();
}
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;
});
}
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());
}
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));
}
}
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));
}
Aggregations