use of io.micronaut.json.codec.MapperMediaTypeCodec in project micronaut-core by micronaut-projects.
the class DefaultHttpClient method buildJsonStreamPublisher.
/**
* @param parentRequest The parent request
* @param request The request
* @param type The type
* @param errorType The error type
* @param <I> The input type
* @param <O> The output type
* @return A {@link Function}
*/
protected <I, O> Function<URI, Publisher<O>> buildJsonStreamPublisher(io.micronaut.http.HttpRequest<?> parentRequest, io.micronaut.http.HttpRequest<I> request, io.micronaut.core.type.Argument<O> type, io.micronaut.core.type.Argument<?> errorType) {
return requestURI -> {
Flux<io.micronaut.http.HttpResponse<Object>> streamResponsePublisher = Flux.from(buildStreamExchange(parentRequest, request, requestURI, errorType));
return streamResponsePublisher.switchMap(response -> {
if (!(response instanceof NettyStreamedHttpResponse)) {
throw new IllegalStateException("Response has been wrapped in non streaming type. Do not wrap the response in client filters for stream requests");
}
MapperMediaTypeCodec mediaTypeCodec = (MapperMediaTypeCodec) mediaTypeCodecRegistry.findCodec(MediaType.APPLICATION_JSON_TYPE).orElseThrow(() -> new IllegalStateException("No JSON codec found"));
StreamedHttpResponse streamResponse = NettyHttpResponseBuilder.toStreamResponse(response);
Flux<HttpContent> httpContentReactiveSequence = Flux.from(streamResponse);
boolean isJsonStream = response.getContentType().map(mediaType -> mediaType.equals(MediaType.APPLICATION_JSON_STREAM_TYPE)).orElse(false);
boolean streamArray = !Iterable.class.isAssignableFrom(type.getType()) && !isJsonStream;
Processor<byte[], JsonNode> jsonProcessor = mediaTypeCodec.getJsonMapper().createReactiveParser(p -> {
httpContentReactiveSequence.map(content -> {
ByteBuf chunk = content.content();
if (log.isTraceEnabled()) {
log.trace("HTTP Client Streaming Response Received Chunk (length: {}) for Request: {} {}", chunk.readableBytes(), request.getMethodName(), request.getUri());
traceBody("Chunk", chunk);
}
try {
return ByteBufUtil.getBytes(chunk);
} finally {
chunk.release();
}
}).subscribe(p);
}, streamArray);
return Flux.from(jsonProcessor).map(jsonNode -> mediaTypeCodec.decode(type, jsonNode));
}).doOnTerminate(() -> {
final Object o = request.getAttribute(NettyClientHttpRequest.CHANNEL).orElse(null);
if (o instanceof Channel) {
final Channel c = (Channel) o;
if (c.isOpen()) {
c.close();
}
}
});
};
}
use of io.micronaut.json.codec.MapperMediaTypeCodec in project micronaut-core by micronaut-projects.
the class DefaultNettyHttpClientRegistry method getClient.
private DefaultHttpClient getClient(ClientKey key, BeanContext beanContext, AnnotationMetadata annotationMetadata) {
return clients.computeIfAbsent(key, clientKey -> {
DefaultHttpClient clientBean = null;
final String clientId = clientKey.clientId;
final Class<?> configurationClass = clientKey.configurationClass;
if (clientId != null) {
clientBean = (DefaultHttpClient) this.beanContext.findBean(HttpClient.class, Qualifiers.byName(clientId)).orElse(null);
}
if (configurationClass != null && !HttpClientConfiguration.class.isAssignableFrom(configurationClass)) {
throw new IllegalStateException("Referenced HTTP client configuration class must be an instance of HttpClientConfiguration for injection point: " + configurationClass);
}
final List<String> filterAnnotations = clientKey.filterAnnotations;
final String path = clientKey.path;
if (clientBean != null && path == null && configurationClass == null && filterAnnotations.isEmpty()) {
return clientBean;
}
LoadBalancer loadBalancer = null;
List<String> clientIdentifiers = null;
final HttpClientConfiguration configuration;
if (configurationClass != null) {
configuration = (HttpClientConfiguration) this.beanContext.getBean(configurationClass);
} else if (clientId != null) {
configuration = this.beanContext.findBean(HttpClientConfiguration.class, Qualifiers.byName(clientId)).orElse(defaultHttpClientConfiguration);
} else {
configuration = defaultHttpClientConfiguration;
}
if (clientId != null) {
loadBalancer = loadBalancerResolver.resolve(clientId).orElseThrow(() -> new HttpClientException("Invalid service reference [" + clientId + "] specified to @Client"));
clientIdentifiers = Collections.singletonList(clientId);
}
String contextPath = null;
if (StringUtils.isNotEmpty(path)) {
contextPath = path;
} else if (StringUtils.isNotEmpty(clientId) && clientId.startsWith("/")) {
contextPath = clientId;
} else {
if (loadBalancer != null) {
contextPath = loadBalancer.getContextPath().orElse(null);
}
}
final DefaultHttpClient client = buildClient(loadBalancer, clientKey.httpVersion, configuration, clientIdentifiers, contextPath, beanContext, annotationMetadata);
final JsonFeatures jsonFeatures = clientKey.jsonFeatures;
if (jsonFeatures != null) {
List<MediaTypeCodec> codecs = new ArrayList<>(2);
MediaTypeCodecRegistry codecRegistry = client.getMediaTypeCodecRegistry();
for (MediaTypeCodec codec : codecRegistry.getCodecs()) {
if (codec instanceof MapperMediaTypeCodec) {
codecs.add(((MapperMediaTypeCodec) codec).cloneWithFeatures(jsonFeatures));
} else {
codecs.add(codec);
}
}
if (!codecRegistry.findCodec(MediaType.APPLICATION_JSON_TYPE).isPresent()) {
codecs.add(createNewJsonCodec(this.beanContext, jsonFeatures));
}
client.setMediaTypeCodecRegistry(MediaTypeCodecRegistry.of(codecs));
}
return client;
});
}
Aggregations