Skip to content

Commit 13e42b8

Browse files
authored
InstrumentServerContext annotation (#214)
1 parent 1496846 commit 13e42b8

File tree

12 files changed

+144
-71
lines changed

12 files changed

+144
-71
lines changed

http-api/src/main/java/io/avaje/http/api/Controller.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@
2424
/** Specify the path mapping request to the controller. */
2525
String value() default "";
2626

27-
/** Specify if the http request context should be instrumented via RequestContextResolver */
27+
/**
28+
* Specify if the http request context should be instrumented via RequestContextResolver
29+
*
30+
* @deprecated use InstrumentServerContext annotation instead
31+
*/
32+
@Deprecated
2833
boolean instrumentRequestContext() default false;
2934
}
Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,20 @@
11
package io.avaje.http.api;
22

3-
import java.lang.annotation.Retention;
4-
import java.lang.annotation.Target;
5-
63
import static java.lang.annotation.ElementType.METHOD;
74
import static java.lang.annotation.RetentionPolicy.RUNTIME;
85

6+
import java.lang.annotation.Retention;
7+
import java.lang.annotation.Target;
8+
99
/**
1010
* Marks a method that handles HTTP DELETE requests.
1111
*
1212
* <pre>{@code
13+
* @Delete("{id}")
14+
* void delete(long id) {
1315
*
14-
* @Delete("{id}")
15-
* void delete(long id) {
16-
*
17-
* ...
18-
* }
16+
* ...
17+
* }
1918
*
2019
* }</pre>
2120
*/
@@ -26,6 +25,11 @@
2625

2726
/** Specify the path. */
2827
String value() default "";
29-
28+
/**
29+
* Specify if the http request context should be instrumented via RequestContextResolver
30+
*
31+
* @deprecated use InstrumentServerContext annotation instead
32+
*/
33+
@Deprecated
3034
boolean instrumentRequestContext() default false;
3135
}
Lines changed: 27 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,47 @@
11
package io.avaje.http.api;
22

3-
import java.lang.annotation.Retention;
4-
import java.lang.annotation.Target;
5-
63
import static java.lang.annotation.ElementType.METHOD;
74
import static java.lang.annotation.RetentionPolicy.RUNTIME;
85

6+
import java.lang.annotation.Retention;
7+
import java.lang.annotation.Target;
8+
99
/**
1010
* Marks a method that handles HTTP GET requests.
1111
*
1212
* <pre>{@code
13+
* @Get("{id}")
14+
* Customer get(long id) {
1315
*
14-
* @Get("{id}")
15-
* Customer get(long id) {
16-
*
17-
* ...
18-
* }
16+
* ...
17+
* }
1918
*
2019
* }</pre>
2120
*
2221
* <h4>Example</h4>
23-
* <p>
24-
* Path parameters are matched by name - "status" in the example below.
25-
* </p>
26-
* <p>
27-
* Method parameters that do not match a path parameter default to being
28-
* a query parameter - "since" is a query parameter in the example below.
29-
* </p>
3022
*
31-
* <pre>{@code
23+
* <p>Path parameters are matched by name - "status" in the example below.
24+
*
25+
* <p>Method parameters that do not match a path parameter default to being a query parameter -
26+
* "since" is a query parameter in the example below.
3227
*
33-
* @Get("/status/{status}")
34-
* List<Customer> getByStatus(String status, LocalDate since) {
28+
* <pre>{@code
29+
* @Get("/status/{status}")
30+
* List<Customer> getByStatus(String status, LocalDate since) {
3531
*
36-
* ...
37-
* }
32+
* ...
33+
* }
3834
*
3935
* }</pre>
4036
*
4137
* <h4>Example - Multiple path parameters</h4>
42-
* <pre>{@code
4338
*
44-
* @Get("/status/{status}/{parentId}")
45-
* List<Customer> getByStatus(String status, long parentId, LocalDate since) {
39+
* <pre>{@code
40+
* @Get("/status/{status}/{parentId}")
41+
* List<Customer> getByStatus(String status, long parentId, LocalDate since) {
4642
*
47-
* ...
48-
* }
43+
* ...
44+
* }
4945
*
5046
* }</pre>
5147
*/
@@ -57,5 +53,11 @@
5753
/** Specify the path. */
5854
String value() default "";
5955

56+
/**
57+
* Specify if the http request context should be instrumented via RequestContextResolver
58+
*
59+
* @deprecated use InstrumentServerContext annotation instead
60+
*/
61+
@Deprecated
6062
boolean instrumentRequestContext() default false;
6163
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package io.avaje.http.api;
2+
3+
import static java.lang.annotation.ElementType.METHOD;
4+
import static java.lang.annotation.ElementType.TYPE;
5+
import static java.lang.annotation.RetentionPolicy.SOURCE;
6+
7+
import java.lang.annotation.Retention;
8+
import java.lang.annotation.Target;
9+
10+
/**
11+
* Marks a controller method to be instrumented with <code>RequestContextResolver</code>.
12+
*
13+
* <p>When instrumented,<code>resolver.currentRequest()</code> can be used to retrieve the current request during a handler method execution
14+
*
15+
* <pre>{@code
16+
* RequestContextResolver resolver = ...
17+
*
18+
* @Get
19+
* @InstrumentServerContext
20+
* void helloWorld(long id) {
21+
* Server resolver.currentRequest()
22+
* ...
23+
* }
24+
*
25+
* }</pre>
26+
*/
27+
@Retention(SOURCE)
28+
@Target({TYPE, METHOD})
29+
public @interface InstrumentServerContext {}

http-api/src/main/java/io/avaje/http/api/Patch.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,11 @@
1414

1515
/** Specify the path. */
1616
String value() default "";
17-
17+
/**
18+
* Specify if the http request context should be instrumented via RequestContextResolver
19+
*
20+
* @deprecated use InstrumentServerContext annotation instead
21+
*/
22+
@Deprecated
1823
boolean instrumentRequestContext() default false;
1924
}

http-api/src/main/java/io/avaje/http/api/Post.java

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
package io.avaje.http.api;
22

3-
import java.lang.annotation.Retention;
4-
import java.lang.annotation.Target;
5-
63
import static java.lang.annotation.ElementType.METHOD;
74
import static java.lang.annotation.RetentionPolicy.RUNTIME;
85

6+
import java.lang.annotation.Retention;
7+
import java.lang.annotation.Target;
8+
99
/**
1010
* Marks a method that handles HTTP POST requests.
1111
*
@@ -24,5 +24,11 @@
2424
/** Specify the path. */
2525
String value() default "";
2626

27+
/**
28+
* Specify if the http request context should be instrumented via RequestContextResolver
29+
*
30+
* @deprecated use InstrumentServerContext annotation instead
31+
*/
32+
@Deprecated
2733
boolean instrumentRequestContext() default false;
2834
}
Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
package io.avaje.http.api;
22

3-
import java.lang.annotation.Retention;
4-
import java.lang.annotation.Target;
5-
63
import static java.lang.annotation.ElementType.METHOD;
74
import static java.lang.annotation.RetentionPolicy.RUNTIME;
85

6+
import java.lang.annotation.Retention;
7+
import java.lang.annotation.Target;
8+
99
/**
1010
* Marks a method that handles HTTP PUT requests.
1111
*/
@@ -16,6 +16,11 @@
1616

1717
/** Specify the path. */
1818
String value() default "";
19-
19+
/**
20+
* Specify if the http request context should be instrumented via RequestContextResolver
21+
*
22+
* @deprecated use InstrumentServerContext annotation instead
23+
*/
24+
@Deprecated
2025
boolean instrumentRequestContext() default false;
2126
}

http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
package io.avaje.http.generator.core;
22

3-
import static io.avaje.http.generator.core.ProcessingContext.*;
3+
import static io.avaje.http.generator.core.ProcessingContext.asElement;
4+
import static io.avaje.http.generator.core.ProcessingContext.asMemberOf;
5+
import static io.avaje.http.generator.core.ProcessingContext.instrumentAllWebMethods;
6+
import static io.avaje.http.generator.core.ProcessingContext.isOpenApiAvailable;
7+
import static io.avaje.http.generator.core.ProcessingContext.platform;
8+
import static io.avaje.http.generator.core.ProcessingContext.useComponent;
9+
import static io.avaje.http.generator.core.ProcessingContext.useJavax;
410
import static java.util.function.Predicate.not;
511

612
import java.util.ArrayList;
@@ -61,6 +67,9 @@ public ControllerReader(TypeElement beanType) {
6167
instrumentAllWebMethods()
6268
|| findAnnotation(ControllerPrism::getOptionalOn)
6369
.map(ControllerPrism::instrumentRequestContext)
70+
.or(
71+
() ->
72+
findAnnotation(InstrumentServerContextPrism::getOptionalOn).map(x -> true))
6473
.orElse(false);
6574
}
6675

@@ -107,8 +116,8 @@ void addImports(boolean withSingleton) {
107116
}
108117

109118
private List<Element> initInterfaces() {
110-
List<Element> interfaces = new ArrayList<>();
111-
for (TypeMirror anInterface : beanType.getInterfaces()) {
119+
final List<Element> interfaces = new ArrayList<>();
120+
for (final TypeMirror anInterface : beanType.getInterfaces()) {
112121
final Element ifaceElement = asElement(anInterface);
113122
final var controller = ControllerPrism.getInstanceOn(ifaceElement);
114123
if (controller != null && !controller.value().isBlank()
@@ -120,8 +129,8 @@ private List<Element> initInterfaces() {
120129
}
121130

122131
private List<ExecutableElement> initInterfaceMethods() {
123-
List<ExecutableElement> ifaceMethods = new ArrayList<>();
124-
for (Element anInterface : interfaces) {
132+
final List<ExecutableElement> ifaceMethods = new ArrayList<>();
133+
for (final Element anInterface : interfaces) {
125134
ifaceMethods.addAll(ElementFilter.methodsIn(anInterface.getEnclosedElements()));
126135
}
127136
return ifaceMethods;
@@ -204,7 +213,7 @@ public void read(boolean withSingleton) {
204213
if (!roles.isEmpty()) {
205214
platform().controllerRoles(roles, this);
206215
}
207-
for (Element element : beanType.getEnclosedElements()) {
216+
for (final Element element : beanType.getEnclosedElements()) {
208217
if (element.getKind() == ElementKind.METHOD) {
209218
readMethod((ExecutableElement) element);
210219
} else if (element.getKind() == ElementKind.FIELD) {
@@ -221,7 +230,7 @@ private void deriveIncludeValidation() {
221230
}
222231

223232
private boolean methodHasValid() {
224-
for (MethodReader method : methods) {
233+
for (final MethodReader method : methods) {
225234
if (method.hasValid()) {
226235
return true;
227236
}
@@ -240,12 +249,12 @@ private void readField(Element element) {
240249
* Read methods from superclasses taking into account generics.
241250
*/
242251
private void readSuper(TypeElement beanType) {
243-
TypeMirror superclass = beanType.getSuperclass();
252+
final TypeMirror superclass = beanType.getSuperclass();
244253
if (superclass.getKind() != TypeKind.NONE) {
245-
DeclaredType declaredType = (DeclaredType) superclass;
254+
final DeclaredType declaredType = (DeclaredType) superclass;
246255
final Element superElement = asElement(superclass);
247256
if (!"java.lang.Object".equals(superElement.toString())) {
248-
for (Element element : superElement.getEnclosedElements()) {
257+
for (final Element element : superElement.getEnclosedElements()) {
249258
if (element.getKind() == ElementKind.METHOD) {
250259
readMethod((ExecutableElement) element, declaredType);
251260
} else if (element.getKind() == ElementKind.FIELD) {
@@ -269,7 +278,7 @@ private void readMethod(ExecutableElement method, DeclaredType declaredType) {
269278
// actual taking into account generics
270279
actualExecutable = (ExecutableType) asMemberOf(declaredType, method);
271280
}
272-
MethodReader methodReader = new MethodReader(this, method, actualExecutable);
281+
final MethodReader methodReader = new MethodReader(this, method, actualExecutable);
273282
if (methodReader.isWebMethod()) {
274283
methodReader.read();
275284
methods.add(methodReader);

0 commit comments

Comments
 (0)