forked from quarkusio/quarkus
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Properly populate metrics uri in presence of auth failures
We now are able for RESTEasy Reactive to determine the URI template even when auth failures occur Fixes: quarkusio#24938
- Loading branch information
Showing
5 changed files
with
193 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
128 changes: 128 additions & 0 deletions
128
...rkus/resteasy/reactive/server/runtime/observability/ObservabilityIntegrationRecorder.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
package io.quarkus.resteasy.reactive.server.runtime.observability; | ||
|
||
import static io.quarkus.resteasy.reactive.server.runtime.observability.ObservabilityUtil.*; | ||
|
||
import jakarta.ws.rs.HttpMethod; | ||
|
||
import org.jboss.logging.Logger; | ||
import org.jboss.resteasy.reactive.server.core.Deployment; | ||
import org.jboss.resteasy.reactive.server.handlers.ClassRoutingHandler; | ||
import org.jboss.resteasy.reactive.server.mapping.RequestMapper; | ||
|
||
import io.quarkus.runtime.RuntimeValue; | ||
import io.quarkus.runtime.annotations.Recorder; | ||
import io.quarkus.security.AuthenticationException; | ||
import io.quarkus.security.ForbiddenException; | ||
import io.quarkus.security.UnauthorizedException; | ||
import io.vertx.core.Handler; | ||
import io.vertx.ext.web.RoutingContext; | ||
|
||
@Recorder | ||
public class ObservabilityIntegrationRecorder { | ||
|
||
private static final Logger log = Logger.getLogger(ObservabilityIntegrationRecorder.class); | ||
|
||
/** | ||
* Returns a handler that sets the special property URI Template path needed by various observability integrations | ||
*/ | ||
public Handler<RoutingContext> preAuthFailureHandler(RuntimeValue<Deployment> deploymentRV) { | ||
return new Handler<RoutingContext>() { | ||
@Override | ||
public void handle(RoutingContext event) { | ||
if (shouldHandle(event)) { | ||
try { | ||
setTemplatePath(event, deploymentRV.getValue()); | ||
} catch (Exception e) { | ||
log.debug("Unable to set template path for observability", e); | ||
} | ||
} | ||
event.next(); | ||
} | ||
|
||
private boolean shouldHandle(RoutingContext event) { | ||
if (!event.failed()) { | ||
return false; | ||
} | ||
return event.failure() instanceof AuthenticationException | ||
|| event.failure() instanceof ForbiddenException | ||
|| event.failure() instanceof UnauthorizedException; | ||
} | ||
|
||
private void setTemplatePath(RoutingContext rc, Deployment deployment) { | ||
// do what RestInitialHandler does | ||
var initMappers = new RequestMapper<>(deployment.getClassMappers()); | ||
var requestMatch = initMappers.map(getPathWithoutPrefix(rc, deployment)); | ||
var remaining = requestMatch.remaining.isEmpty() ? "/" : requestMatch.remaining; | ||
|
||
var serverRestHandlers = requestMatch.value.handlers; | ||
if (serverRestHandlers == null || serverRestHandlers.length < 1) { | ||
// nothing we can do | ||
return; | ||
} | ||
var firstHandler = serverRestHandlers[0]; | ||
if (!(firstHandler instanceof ClassRoutingHandler)) { | ||
// nothing we can do | ||
return; | ||
} | ||
|
||
var classRoutingHandler = (ClassRoutingHandler) firstHandler; | ||
var mappers = classRoutingHandler.getMappers(); | ||
|
||
var requestMethod = rc.request().method().name(); | ||
|
||
// do what ClassRoutingHandler does | ||
var mapper = mappers.get(requestMethod); | ||
if (mapper == null) { | ||
if (requestMethod.equals(HttpMethod.HEAD) || requestMethod.equals(HttpMethod.OPTIONS)) { | ||
mapper = mappers.get(HttpMethod.GET); | ||
} | ||
if (mapper == null) { | ||
mapper = mappers.get(null); | ||
} | ||
if (mapper == null) { | ||
// can't match the path | ||
return; | ||
} | ||
} | ||
var target = mapper.map(remaining); | ||
if (target == null) { | ||
if (requestMethod.equals(HttpMethod.HEAD)) { | ||
mapper = mappers.get(HttpMethod.GET); | ||
if (mapper != null) { | ||
target = mapper.map(remaining); | ||
} | ||
} | ||
|
||
if (target == null) { | ||
// can't match the path | ||
return; | ||
} | ||
} | ||
|
||
var templatePath = requestMatch.template.template + target.template.template; | ||
if (templatePath.endsWith("/")) { | ||
templatePath = templatePath.substring(0, templatePath.length() - 1); | ||
} | ||
|
||
setUrlPathTemplate(rc, templatePath); | ||
} | ||
|
||
public String getPath(RoutingContext rc) { | ||
return rc.normalizedPath(); | ||
} | ||
|
||
public String getPathWithoutPrefix(RoutingContext rc, Deployment deployment) { | ||
String path = getPath(rc); | ||
if (path != null) { | ||
String prefix = deployment.getPrefix(); | ||
if (!prefix.isEmpty()) { | ||
if (path.startsWith(prefix)) { | ||
return path.substring(prefix.length()); | ||
} | ||
} | ||
} | ||
return path; | ||
} | ||
}; | ||
} | ||
} |
15 changes: 15 additions & 0 deletions
15
...ain/java/io/quarkus/resteasy/reactive/server/runtime/observability/ObservabilityUtil.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package io.quarkus.resteasy.reactive.server.runtime.observability; | ||
|
||
import io.vertx.core.http.impl.HttpServerRequestInternal; | ||
import io.vertx.ext.web.RoutingContext; | ||
|
||
final class ObservabilityUtil { | ||
|
||
private ObservabilityUtil() { | ||
} | ||
|
||
static void setUrlPathTemplate(RoutingContext routingContext, String templatePath) { | ||
((HttpServerRequestInternal) (routingContext.request())).context() | ||
.putLocal("UrlPathTemplate", templatePath); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters