-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
Properly populate metrics uri in presence of auth failures
- Loading branch information
Showing
13 changed files
with
326 additions
and
15 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
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
15 changes: 15 additions & 0 deletions
15
...rometer-prometheus/src/main/java/io/quarkus/it/micrometer/prometheus/SecuredResource.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.it.micrometer.prometheus; | ||
|
||
import jakarta.ws.rs.GET; | ||
import jakarta.ws.rs.Path; | ||
import jakarta.ws.rs.PathParam; | ||
|
||
@Path("/secured") | ||
public class SecuredResource { | ||
|
||
@GET | ||
@Path("item/{id}") | ||
public String item(@PathParam("id") String id) { | ||
return "return message with id " + id; | ||
} | ||
} |
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
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
15 changes: 15 additions & 0 deletions
15
...elemetry-reactive/src/main/java/io/quarkus/it/opentelemetry/reactive/SecuredResource.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.it.opentelemetry.reactive; | ||
|
||
import jakarta.ws.rs.GET; | ||
import jakarta.ws.rs.Path; | ||
|
||
import org.jboss.resteasy.reactive.RestPath; | ||
|
||
@Path("secured") | ||
public class SecuredResource { | ||
@GET | ||
@Path("item/{value}") | ||
public String get(@RestPath String value) { | ||
return "Received: " + value; | ||
} | ||
} |
Oops, something went wrong.