Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace HttpAttributes with accessors #11324

Merged
merged 12 commits into from
Jan 24, 2025
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package io.micronaut.http.client;

import io.micronaut.aop.MethodInvocationContext;
import io.micronaut.core.annotation.NonNull;
import io.micronaut.http.HttpAttributes;
import io.micronaut.http.HttpRequest;

import java.util.Optional;

/**
* Client-related attribute accessors.
*
* @author Jonas Konrad
* @since 4.8.0
*/
@SuppressWarnings("removal")
public final class ClientAttributes {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this regarded public API?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes

private ClientAttributes() {
}

/**
* Set the client service ID.
*
* @param request The request
* @param serviceId The client service ID
* @see io.micronaut.http.BasicHttpAttributes#getServiceId(HttpRequest)
*/
public static void setServiceId(@NonNull HttpRequest<?> request, @NonNull String serviceId) {
request.setAttribute(HttpAttributes.SERVICE_ID, serviceId);
}

/**
* Get the invocation context.
*
* @param request The request
* @return The invocation context, if present
*/
@SuppressWarnings({"unchecked", "rawtypes"})
@NonNull
public static Optional<MethodInvocationContext<?, ?>> getInvocationContext(@NonNull HttpRequest<?> request) {
return (Optional) request.getAttribute(HttpAttributes.INVOCATION_CONTEXT, MethodInvocationContext.class);
}

/**
* Set the invocation context.
*
* @param request The request
* @param invocationContext The invocation context
*/
public static void setInvocationContext(@NonNull HttpRequest<?> request, @NonNull MethodInvocationContext<?, ?> invocationContext) {
request.setAttribute(HttpAttributes.INVOCATION_CONTEXT, invocationContext);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
import io.micronaut.core.util.CollectionUtils;
import io.micronaut.core.util.StringUtils;
import io.micronaut.core.version.annotation.Version;
import io.micronaut.http.HttpAttributes;
import io.micronaut.http.BasicHttpAttributes;
import io.micronaut.http.HttpHeaders;
import io.micronaut.http.HttpMethod;
import io.micronaut.http.HttpRequest;
Expand All @@ -56,6 +56,7 @@
import io.micronaut.http.annotation.HttpMethodMapping;
import io.micronaut.http.annotation.Produces;
import io.micronaut.http.client.BlockingHttpClient;
import io.micronaut.http.client.ClientAttributes;
import io.micronaut.http.client.HttpClient;
import io.micronaut.http.client.HttpClientRegistry;
import io.micronaut.http.client.ReactiveClientResultTransformer;
Expand Down Expand Up @@ -423,9 +424,9 @@ private RequestBinderResult bindRequest(MethodInvocationContext<Object, Object>
}
}

request.setAttribute(HttpAttributes.INVOCATION_CONTEXT, context);
ClientAttributes.setInvocationContext(request, context);
// Set the URI template used to make the request for tracing purposes
request.setAttribute(HttpAttributes.URI_TEMPLATE, resolveTemplate(annotationMetadata, uriTemplate.toString()));
BasicHttpAttributes.setUriTemplate(request, resolveTemplate(annotationMetadata, uriTemplate.toString()));

return RequestBinderResult.withRequest(request);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import spock.lang.Specification
@Property(name = "micronaut.server.http-version", value = "HTTP_2_0")
@Property(name = "micronaut.server.ssl.build-self-signed", value = "true")
@Property(name = "micronaut.server.ssl.enabled", value = "true")
@Property(name = "micronaut.server.ssl.port", value = "0")
@Property(name = "micronaut.http.client.ssl.insecure-trust-all-certificates", value = "true")
@Property(name = "micronaut.server.max-request-size", value = "16384")
class Http2Spec extends Specification {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import io.micronaut.context.ApplicationContext
import io.micronaut.context.annotation.Requires
import io.micronaut.core.type.Argument
import io.micronaut.core.util.StringUtils
import io.micronaut.http.HttpAttributes
import io.micronaut.http.BasicHttpAttributes
import io.micronaut.http.HttpHeaders
import io.micronaut.http.HttpRequest
import io.micronaut.http.HttpResponse
Expand All @@ -18,9 +18,9 @@ import io.micronaut.http.client.exceptions.HttpClientResponseException
import io.micronaut.http.filter.HttpServerFilter
import io.micronaut.http.filter.ServerFilterChain
import io.micronaut.runtime.server.EmbeddedServer
import io.micronaut.web.router.RouteAttributes
import jakarta.inject.Singleton
import org.reactivestreams.Publisher
import org.spockframework.util.Assert
import spock.lang.Specification

class OptionsRequestAttributesSpec extends Specification {
Expand Down Expand Up @@ -98,9 +98,9 @@ class OptionsRequestAttributesSpec extends Specification {

@Override
Publisher<MutableHttpResponse<?>> doFilter(HttpRequest<?> request, ServerFilterChain chain) {
containsRouteMatch = request.getAttributes().contains(HttpAttributes.ROUTE_MATCH.toString())
containsRouteInfo = request.getAttributes().contains(HttpAttributes.ROUTE_INFO.toString())
containsUriTemplate = request.getAttributes().contains(HttpAttributes.URI_TEMPLATE.toString())
containsRouteMatch = RouteAttributes.getRouteMatch(request).isPresent()
containsRouteInfo = RouteAttributes.getRouteInfo(request).isPresent()
containsUriTemplate = BasicHttpAttributes.getUriTemplate(request).isPresent()
return chain.proceed(request)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
import io.micronaut.core.util.ObjectUtils;
import io.micronaut.core.util.StringUtils;
import io.micronaut.core.util.functional.ThrowingFunction;
import io.micronaut.http.HttpAttributes;
import io.micronaut.http.BasicHttpAttributes;
import io.micronaut.http.HttpResponse;
import io.micronaut.http.HttpResponseWrapper;
import io.micronaut.http.HttpStatus;
Expand All @@ -57,6 +57,7 @@
import io.micronaut.http.body.MessageBodyHandlerRegistry;
import io.micronaut.http.body.MessageBodyReader;
import io.micronaut.http.client.BlockingHttpClient;
import io.micronaut.http.client.ClientAttributes;
import io.micronaut.http.client.DefaultHttpClientConfiguration;
import io.micronaut.http.client.HttpClient;
import io.micronaut.http.client.HttpClientConfiguration;
Expand Down Expand Up @@ -1508,8 +1509,8 @@ private ExecutionFlow<HttpResponse<?>> sendRequestWithRedirects(
MutableHttpRequest<?> request,
BiFunction<MutableHttpRequest<?>, NettyClientByteBodyResponse, ? extends ExecutionFlow<? extends HttpResponse<?>>> readResponse
) {
if (informationalServiceId != null && request.getAttribute(HttpAttributes.SERVICE_ID).isEmpty()) {
request.setAttribute(HttpAttributes.SERVICE_ID, informationalServiceId);
if (informationalServiceId != null && BasicHttpAttributes.getServiceId(request).isEmpty()) {
ClientAttributes.setServiceId(request, informationalServiceId);
}

List<GenericHttpFilter> filters =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package io.micronaut.http.client

import io.micronaut.context.ApplicationContext
import io.micronaut.context.annotation.Requires
import io.micronaut.http.HttpAttributes
import io.micronaut.http.BasicHttpAttributes
import io.micronaut.http.HttpRequest
import io.micronaut.http.HttpResponse
import io.micronaut.http.HttpVersion
Expand Down Expand Up @@ -79,7 +79,7 @@ class ServiceIdSpec extends Specification {

@Override
Publisher<? extends HttpResponse<?>> doFilter(MutableHttpRequest<?> request, ClientFilterChain chain) {
serviceId = request.getAttribute(HttpAttributes.SERVICE_ID).orElse(null)
serviceId = BasicHttpAttributes.getServiceId(request).orElse(null)
return chain.proceed(request)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,12 @@ import io.micronaut.context.annotation.Property
import io.micronaut.context.annotation.Requires
import io.micronaut.http.HttpRequest
import io.micronaut.http.MediaType
import io.micronaut.http.annotation.*
import io.micronaut.http.annotation.Body
import io.micronaut.http.annotation.Consumes
import io.micronaut.http.annotation.Controller
import io.micronaut.http.annotation.Get
import io.micronaut.http.annotation.Post
import io.micronaut.http.annotation.Produces
import io.micronaut.http.client.HttpClient
import io.micronaut.http.client.HttpVersionSelection
import io.micronaut.http.client.annotation.Client
Expand All @@ -17,6 +22,7 @@ import spock.lang.Specification
@Property(name = "micronaut.server.http-version", value = "HTTP_2_0")
@Property(name = "micronaut.server.ssl.build-self-signed", value = "true")
@Property(name = "micronaut.server.ssl.enabled", value = "true")
@Property(name = "micronaut.server.ssl.port", value = "0")
@Property(name = "micronaut.http.client.ssl.insecure-trust-all-certificates", value = "true")
@Property(name = "micronaut.server.max-request-size", value = "16384")
class Http2Spec extends Specification {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
import io.micronaut.core.annotation.NonNull;
import io.micronaut.core.annotation.Nullable;
import io.micronaut.core.async.publisher.Publishers;
import io.micronaut.core.attr.AttributeHolder;
import io.micronaut.core.bind.ArgumentBinder;
import io.micronaut.core.convert.ArgumentConversionContext;
import io.micronaut.core.convert.ConversionService;
Expand Down Expand Up @@ -64,6 +63,7 @@
import io.micronaut.http.server.netty.handler.Http2ServerHandler;
import io.micronaut.http.server.netty.multipart.NettyCompletedFileUpload;
import io.micronaut.web.router.DefaultUriRouteMatch;
import io.micronaut.web.router.RouteAttributes;
import io.micronaut.web.router.RouteMatch;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
Expand Down Expand Up @@ -227,7 +227,7 @@ public final ExecutionFlow<?> getRouteWaitsFor() {
public final FormRouteCompleter formRouteCompleter() {
assert isFormOrMultipartData();
if (formRouteCompleter == null) {
formRouteCompleter = new FormRouteCompleter((RouteMatch<?>) getAttribute(HttpAttributes.ROUTE_MATCH).get(), getChannelHandlerContext().channel().eventLoop());
formRouteCompleter = new FormRouteCompleter(RouteAttributes.getRouteMatch(this).get(), getChannelHandlerContext().channel().eventLoop());
}
return formRouteCompleter;
}
Expand Down Expand Up @@ -386,7 +386,7 @@ public <T1> Optional<T1> getBody(ArgumentConversionContext<T1> conversionContext
*/
@Internal
public void release() {
Object routeMatchO = ((AttributeHolder) this).getAttribute(HttpAttributes.ROUTE_MATCH).orElse(null);
Object routeMatchO = RouteAttributes.getRouteMatch(this).orElse(null);
// usually this is a DefaultUriRouteMatch, avoid scalability issues here
RouteMatch<?> routeMatch = routeMatchO instanceof DefaultUriRouteMatch<?, ?> urm ? urm : (RouteMatch<?>) routeMatchO;
if (routeMatch != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@
import io.micronaut.core.type.MutableHeaders;
import io.micronaut.http.ByteBodyHttpResponse;
import io.micronaut.http.ByteBodyHttpResponseWrapper;
import io.micronaut.http.HttpAttributes;
import io.micronaut.http.HttpMethod;
import io.micronaut.http.HttpRequest;
import io.micronaut.http.HttpResponse;
Expand Down Expand Up @@ -63,6 +62,7 @@
import io.micronaut.http.server.netty.handler.OutboundAccess;
import io.micronaut.http.server.netty.handler.RequestHandler;
import io.micronaut.web.router.DefaultUrlRouteInfo;
import io.micronaut.web.router.RouteAttributes;
import io.micronaut.web.router.RouteInfo;
import io.micronaut.web.router.resource.StaticResourceResolver;
import io.netty.buffer.ByteBuf;
Expand Down Expand Up @@ -331,7 +331,7 @@ private ExecutionFlow<ByteBodyHttpResponse<?>> encodeHttpResponse(
Object body) {
MutableHttpResponse<?> response = httpResponse.toMutableResponse();
if (nettyRequest.getMethod() != HttpMethod.HEAD && body != null) {
Object routeInfoO = response.getAttribute(HttpAttributes.ROUTE_INFO).orElse(null);
Object routeInfoO = RouteAttributes.getRouteInfo(response).orElse(null);
// usually this is a UriRouteInfo, avoid scalability issues here
@SuppressWarnings("unchecked") final RouteInfo<Object> routeInfo = (RouteInfo<Object>) (routeInfoO instanceof DefaultUrlRouteInfo<?, ?> uri ? uri : (RouteInfo<?>) routeInfoO);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
import io.micronaut.core.io.buffer.ByteBuffer;
import io.micronaut.core.io.buffer.ReferenceCounted;
import io.micronaut.core.propagation.PropagatedContext;
import io.micronaut.http.HttpAttributes;
import io.micronaut.http.HttpHeaders;
import io.micronaut.http.HttpRequest;
import io.micronaut.http.MediaType;
Expand All @@ -39,13 +38,14 @@
import io.micronaut.http.body.MessageBodyReader;
import io.micronaut.http.codec.CodecException;
import io.micronaut.http.context.ServerHttpRequestContext;
import io.micronaut.http.netty.body.AvailableNettyByteBody;
import io.micronaut.http.server.netty.FormDataHttpContentProcessor;
import io.micronaut.http.server.netty.FormRouteCompleter;
import io.micronaut.http.server.netty.MicronautHttpData;
import io.micronaut.http.server.netty.NettyHttpRequest;
import io.micronaut.http.netty.body.AvailableNettyByteBody;
import io.micronaut.http.server.netty.configuration.NettyHttpServerConfiguration;
import io.micronaut.http.server.netty.converters.NettyConverters;
import io.micronaut.web.router.RouteAttributes;
import io.micronaut.web.router.RouteInfo;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufAllocator;
Expand Down Expand Up @@ -149,7 +149,7 @@ public List<ConversionError> getConversionErrors() {

Optional<T> transform(NettyHttpRequest<?> nhr, ArgumentConversionContext<T> context, AvailableByteBody imm) throws Throwable {
MessageBodyReader<T> reader = null;
final RouteInfo<?> routeInfo = nhr.getAttribute(HttpAttributes.ROUTE_INFO, RouteInfo.class).orElse(null);
final RouteInfo<?> routeInfo = RouteAttributes.getRouteInfo(nhr).orElse(null);
if (routeInfo != null) {
reader = (MessageBodyReader<T>) routeInfo.getMessageBodyReader();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
import io.micronaut.inject.MethodExecutionHandle;
import io.micronaut.scheduling.executor.ExecutorSelector;
import io.micronaut.scheduling.executor.ThreadSelection;
import io.micronaut.web.router.RouteAttributes;
import io.micronaut.web.router.UriRouteMatch;
import io.micronaut.websocket.CloseReason;
import io.micronaut.websocket.WebSocketPongMessage;
Expand Down Expand Up @@ -182,7 +183,7 @@ public class NettyServerWebSocketHandler extends AbstractNettyWebSocketHandler {

this.nettyEmbeddedServices = nettyEmbeddedServices;
this.coroutineHelper = coroutineHelper;
request.setAttribute(HttpAttributes.ROUTE_MATCH, routeMatch);
RouteAttributes.setRouteMatch(request, routeMatch);

Flux.from(callOpenMethod(ctx)).subscribe(v -> { }, t -> {
forwardErrorToUser(ctx, e -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
import io.micronaut.core.execution.ExecutionFlow;
import io.micronaut.core.propagation.PropagatedContext;
import io.micronaut.core.util.StringUtils;
import io.micronaut.http.HttpAttributes;
import io.micronaut.http.HttpMethod;
import io.micronaut.http.HttpRequest;
import io.micronaut.http.HttpResponse;
Expand All @@ -43,6 +42,7 @@
import io.micronaut.http.server.netty.configuration.NettyHttpServerConfiguration;
import io.micronaut.http.server.netty.handler.OutboundAccess;
import io.micronaut.http.server.netty.handler.RequestHandler;
import io.micronaut.web.router.RouteAttributes;
import io.micronaut.web.router.RouteMatch;
import io.micronaut.web.router.Router;
import io.micronaut.web.router.UriRouteMatch;
Expand Down Expand Up @@ -180,7 +180,8 @@ private void writeResponse(ChannelHandlerContext ctx,
}

if (shouldProceedNormally) {
UriRouteMatch<Object, Object> routeMatch = actualResponse.getAttribute(HttpAttributes.ROUTE_MATCH, UriRouteMatch.class)
UriRouteMatch<Object, Object> routeMatch = RouteAttributes.getRouteMatch(actualResponse)
.map(rm -> (UriRouteMatch<Object, Object>) rm)
.orElseThrow(() -> new IllegalStateException("Route match is required!"));
//Adding new handler to the existing pipeline to handle WebSocket Messages
WebSocketBean<?> webSocketBean = webSocketBeanRegistry.getWebSocket(routeMatch.getTarget().getClass());
Expand Down Expand Up @@ -306,10 +307,10 @@ ExecutionFlow<HttpResponse<?>> handle(HttpRequest<?> request) {
MutableHttpResponse<?> proceed = HttpResponse.ok();

if (route != null) {
request.setAttribute(HttpAttributes.ROUTE_MATCH, route);
request.setAttribute(HttpAttributes.ROUTE_INFO, route);
proceed.setAttribute(HttpAttributes.ROUTE_MATCH, route);
proceed.setAttribute(HttpAttributes.ROUTE_INFO, route);
RouteAttributes.setRouteMatch(request, route);
RouteAttributes.setRouteInfo(request, route.getRouteInfo());
RouteAttributes.setRouteMatch(proceed, route);
RouteAttributes.setRouteInfo(proceed, route.getRouteInfo());
}

ExecutionFlow<HttpResponse<?>> response;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import io.micronaut.context.ApplicationContext
import io.micronaut.context.annotation.Requires
import io.micronaut.core.type.Argument
import io.micronaut.core.util.StringUtils
import io.micronaut.http.HttpAttributes
import io.micronaut.http.BasicHttpAttributes
import io.micronaut.http.HttpHeaders
import io.micronaut.http.HttpRequest
import io.micronaut.http.HttpResponse
Expand All @@ -18,9 +18,9 @@ import io.micronaut.http.client.exceptions.HttpClientResponseException
import io.micronaut.http.filter.HttpServerFilter
import io.micronaut.http.filter.ServerFilterChain
import io.micronaut.runtime.server.EmbeddedServer
import io.micronaut.web.router.RouteAttributes
import jakarta.inject.Singleton
import org.reactivestreams.Publisher
import org.spockframework.util.Assert
import spock.lang.Specification

class OptionsRequestAttributesSpec extends Specification {
Expand Down Expand Up @@ -97,9 +97,9 @@ class OptionsRequestAttributesSpec extends Specification {

@Override
Publisher<MutableHttpResponse<?>> doFilter(HttpRequest<?> request, ServerFilterChain chain) {
containsRouteMatch = request.getAttributes().contains(HttpAttributes.ROUTE_MATCH.toString())
containsRouteInfo = request.getAttributes().contains(HttpAttributes.ROUTE_INFO.toString())
containsUriTemplate = request.getAttributes().contains(HttpAttributes.URI_TEMPLATE.toString())
containsRouteMatch = RouteAttributes.getRouteMatch(request).isPresent()
containsRouteInfo = RouteAttributes.getRouteInfo(request).isPresent()
containsUriTemplate = BasicHttpAttributes.getUriTemplate(request).isPresent()
return chain.proceed(request)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import io.micronaut.context.ApplicationContext
import io.micronaut.context.annotation.Requires
import io.micronaut.core.async.publisher.Publishers
import io.micronaut.core.util.StringUtils
import io.micronaut.http.HttpAttributes
import io.micronaut.http.HttpRequest
import io.micronaut.http.HttpResponse
import io.micronaut.http.HttpStatus
Expand All @@ -20,6 +19,7 @@ import io.micronaut.http.filter.HttpServerFilter
import io.micronaut.http.filter.ServerFilterChain
import io.micronaut.runtime.server.EmbeddedServer
import io.micronaut.web.router.MethodBasedRouteMatch
import io.micronaut.web.router.RouteAttributes
import io.micronaut.web.router.RouteMatch
import org.reactivestreams.Publisher
import reactor.core.publisher.Flux
Expand Down Expand Up @@ -291,7 +291,7 @@ class FilterErrorSpec extends Specification {
@Override
Publisher<MutableHttpResponse<?>> doFilter(HttpRequest<?> request, ServerFilterChain chain) {
return Publishers.then(chain.proceed(request), { resp ->
routeMatch.set(resp.getAttribute(HttpAttributes.ROUTE_MATCH, RouteMatch).get())
routeMatch.set(RouteAttributes.getRouteMatch(resp).get())
})
}

Expand Down
Loading
Loading