Skip to content

InstrumentServerContext annotation #214

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

Merged
merged 1 commit into from
Apr 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion http-api/src/main/java/io/avaje/http/api/Controller.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@
/** Specify the path mapping request to the controller. */
String value() default "";

/** Specify if the http request context should be instrumented via RequestContextResolver */
/**
* Specify if the http request context should be instrumented via RequestContextResolver
*
* @deprecated use InstrumentServerContext annotation instead
*/
@Deprecated
boolean instrumentRequestContext() default false;
}
22 changes: 13 additions & 9 deletions http-api/src/main/java/io/avaje/http/api/Delete.java
Original file line number Diff line number Diff line change
@@ -1,21 +1,20 @@
package io.avaje.http.api;

import java.lang.annotation.Retention;
import java.lang.annotation.Target;

import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

import java.lang.annotation.Retention;
import java.lang.annotation.Target;

/**
* Marks a method that handles HTTP DELETE requests.
*
* <pre>{@code
* @Delete("{id}")
* void delete(long id) {
*
* @Delete("{id}")
* void delete(long id) {
*
* ...
* }
* ...
* }
*
* }</pre>
*/
Expand All @@ -26,6 +25,11 @@

/** Specify the path. */
String value() default "";

/**
* Specify if the http request context should be instrumented via RequestContextResolver
*
* @deprecated use InstrumentServerContext annotation instead
*/
@Deprecated
boolean instrumentRequestContext() default false;
}
52 changes: 27 additions & 25 deletions http-api/src/main/java/io/avaje/http/api/Get.java
Original file line number Diff line number Diff line change
@@ -1,51 +1,47 @@
package io.avaje.http.api;

import java.lang.annotation.Retention;
import java.lang.annotation.Target;

import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

import java.lang.annotation.Retention;
import java.lang.annotation.Target;

/**
* Marks a method that handles HTTP GET requests.
*
* <pre>{@code
* @Get("{id}")
* Customer get(long id) {
*
* @Get("{id}")
* Customer get(long id) {
*
* ...
* }
* ...
* }
*
* }</pre>
*
* <h4>Example</h4>
* <p>
* Path parameters are matched by name - "status" in the example below.
* </p>
* <p>
* Method parameters that do not match a path parameter default to being
* a query parameter - "since" is a query parameter in the example below.
* </p>
*
* <pre>{@code
* <p>Path parameters are matched by name - "status" in the example below.
*
* <p>Method parameters that do not match a path parameter default to being a query parameter -
* "since" is a query parameter in the example below.
*
* @Get("/status/{status}")
* List<Customer> getByStatus(String status, LocalDate since) {
* <pre>{@code
* @Get("/status/{status}")
* List<Customer> getByStatus(String status, LocalDate since) {
*
* ...
* }
* ...
* }
*
* }</pre>
*
* <h4>Example - Multiple path parameters</h4>
* <pre>{@code
*
* @Get("/status/{status}/{parentId}")
* List<Customer> getByStatus(String status, long parentId, LocalDate since) {
* <pre>{@code
* @Get("/status/{status}/{parentId}")
* List<Customer> getByStatus(String status, long parentId, LocalDate since) {
*
* ...
* }
* ...
* }
*
* }</pre>
*/
Expand All @@ -57,5 +53,11 @@
/** Specify the path. */
String value() default "";

/**
* Specify if the http request context should be instrumented via RequestContextResolver
*
* @deprecated use InstrumentServerContext annotation instead
*/
@Deprecated
boolean instrumentRequestContext() default false;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package io.avaje.http.api;

import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.SOURCE;

import java.lang.annotation.Retention;
import java.lang.annotation.Target;

/**
* Marks a controller method to be instrumented with <code>RequestContextResolver</code>.
*
* <p>When instrumented,<code>resolver.currentRequest()</code> can be used to retrieve the current request during a handler method execution
*
* <pre>{@code
* RequestContextResolver resolver = ...
*
* @Get
* @InstrumentServerContext
* void helloWorld(long id) {
* Server resolver.currentRequest()
* ...
* }
*
* }</pre>
*/
@Retention(SOURCE)
@Target({TYPE, METHOD})
public @interface InstrumentServerContext {}
7 changes: 6 additions & 1 deletion http-api/src/main/java/io/avaje/http/api/Patch.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@

/** Specify the path. */
String value() default "";

/**
* Specify if the http request context should be instrumented via RequestContextResolver
*
* @deprecated use InstrumentServerContext annotation instead
*/
@Deprecated
boolean instrumentRequestContext() default false;
}
12 changes: 9 additions & 3 deletions http-api/src/main/java/io/avaje/http/api/Post.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package io.avaje.http.api;

import java.lang.annotation.Retention;
import java.lang.annotation.Target;

import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

import java.lang.annotation.Retention;
import java.lang.annotation.Target;

/**
* Marks a method that handles HTTP POST requests.
*
Expand All @@ -24,5 +24,11 @@
/** Specify the path. */
String value() default "";

/**
* Specify if the http request context should be instrumented via RequestContextResolver
*
* @deprecated use InstrumentServerContext annotation instead
*/
@Deprecated
boolean instrumentRequestContext() default false;
}
13 changes: 9 additions & 4 deletions http-api/src/main/java/io/avaje/http/api/Put.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package io.avaje.http.api;

import java.lang.annotation.Retention;
import java.lang.annotation.Target;

import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

import java.lang.annotation.Retention;
import java.lang.annotation.Target;

/**
* Marks a method that handles HTTP PUT requests.
*/
Expand All @@ -16,6 +16,11 @@

/** Specify the path. */
String value() default "";

/**
* Specify if the http request context should be instrumented via RequestContextResolver
*
* @deprecated use InstrumentServerContext annotation instead
*/
@Deprecated
boolean instrumentRequestContext() default false;
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
package io.avaje.http.generator.core;

import static io.avaje.http.generator.core.ProcessingContext.*;
import static io.avaje.http.generator.core.ProcessingContext.asElement;
import static io.avaje.http.generator.core.ProcessingContext.asMemberOf;
import static io.avaje.http.generator.core.ProcessingContext.instrumentAllWebMethods;
import static io.avaje.http.generator.core.ProcessingContext.isOpenApiAvailable;
import static io.avaje.http.generator.core.ProcessingContext.platform;
import static io.avaje.http.generator.core.ProcessingContext.useComponent;
import static io.avaje.http.generator.core.ProcessingContext.useJavax;
import static java.util.function.Predicate.not;

import java.util.ArrayList;
Expand Down Expand Up @@ -61,6 +67,9 @@ public ControllerReader(TypeElement beanType) {
instrumentAllWebMethods()
|| findAnnotation(ControllerPrism::getOptionalOn)
.map(ControllerPrism::instrumentRequestContext)
.or(
() ->
findAnnotation(InstrumentServerContextPrism::getOptionalOn).map(x -> true))
.orElse(false);
}

Expand Down Expand Up @@ -107,8 +116,8 @@ void addImports(boolean withSingleton) {
}

private List<Element> initInterfaces() {
List<Element> interfaces = new ArrayList<>();
for (TypeMirror anInterface : beanType.getInterfaces()) {
final List<Element> interfaces = new ArrayList<>();
for (final TypeMirror anInterface : beanType.getInterfaces()) {
final Element ifaceElement = asElement(anInterface);
final var controller = ControllerPrism.getInstanceOn(ifaceElement);
if (controller != null && !controller.value().isBlank()
Expand All @@ -120,8 +129,8 @@ private List<Element> initInterfaces() {
}

private List<ExecutableElement> initInterfaceMethods() {
List<ExecutableElement> ifaceMethods = new ArrayList<>();
for (Element anInterface : interfaces) {
final List<ExecutableElement> ifaceMethods = new ArrayList<>();
for (final Element anInterface : interfaces) {
ifaceMethods.addAll(ElementFilter.methodsIn(anInterface.getEnclosedElements()));
}
return ifaceMethods;
Expand Down Expand Up @@ -204,7 +213,7 @@ public void read(boolean withSingleton) {
if (!roles.isEmpty()) {
platform().controllerRoles(roles, this);
}
for (Element element : beanType.getEnclosedElements()) {
for (final Element element : beanType.getEnclosedElements()) {
if (element.getKind() == ElementKind.METHOD) {
readMethod((ExecutableElement) element);
} else if (element.getKind() == ElementKind.FIELD) {
Expand All @@ -221,7 +230,7 @@ private void deriveIncludeValidation() {
}

private boolean methodHasValid() {
for (MethodReader method : methods) {
for (final MethodReader method : methods) {
if (method.hasValid()) {
return true;
}
Expand All @@ -240,12 +249,12 @@ private void readField(Element element) {
* Read methods from superclasses taking into account generics.
*/
private void readSuper(TypeElement beanType) {
TypeMirror superclass = beanType.getSuperclass();
final TypeMirror superclass = beanType.getSuperclass();
if (superclass.getKind() != TypeKind.NONE) {
DeclaredType declaredType = (DeclaredType) superclass;
final DeclaredType declaredType = (DeclaredType) superclass;
final Element superElement = asElement(superclass);
if (!"java.lang.Object".equals(superElement.toString())) {
for (Element element : superElement.getEnclosedElements()) {
for (final Element element : superElement.getEnclosedElements()) {
if (element.getKind() == ElementKind.METHOD) {
readMethod((ExecutableElement) element, declaredType);
} else if (element.getKind() == ElementKind.FIELD) {
Expand All @@ -269,7 +278,7 @@ private void readMethod(ExecutableElement method, DeclaredType declaredType) {
// actual taking into account generics
actualExecutable = (ExecutableType) asMemberOf(declaredType, method);
}
MethodReader methodReader = new MethodReader(this, method, actualExecutable);
final MethodReader methodReader = new MethodReader(this, method, actualExecutable);
if (methodReader.isWebMethod()) {
methodReader.read();
methods.add(methodReader);
Expand Down
Loading