Skip to content

Commit

Permalink
Simplifies gRPC API annotations by using value() instead of name() wh…
Browse files Browse the repository at this point in the history
…enever possible. A few other minor changes to follow our coding rules.
  • Loading branch information
spericas committed Jul 17, 2024
1 parent 615a4c2 commit 4c819ed
Show file tree
Hide file tree
Showing 16 changed files with 96 additions and 82 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
*/
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@GrpcMethod(type = MethodType.BIDI_STREAMING)
@GrpcMethod(MethodType.BIDI_STREAMING)
@Documented
@Inherited
public @interface Bidirectional {
Expand All @@ -42,5 +42,5 @@
*
* @return name of the method
*/
String name() default "";
String value() default "";
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
*/
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@GrpcMethod(type = MethodType.CLIENT_STREAMING)
@GrpcMethod(MethodType.CLIENT_STREAMING)
@Documented
@Inherited
public @interface ClientStreaming {
Expand All @@ -41,5 +41,5 @@
*
* @return name of the method
*/
String name() default "";
String value() default "";
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
*
* @return the service name
*/
String name() default "";
String value() default "";

/**
* Obtain the service version.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,5 +48,5 @@
*
* @return the gRPC method type
*/
MethodType type();
MethodType value();
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
*/
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@GrpcMethod(type = MethodType.SERVER_STREAMING)
@GrpcMethod(MethodType.SERVER_STREAMING)
@Documented
@Inherited
public @interface ServerStreaming {
Expand All @@ -41,5 +41,5 @@
*
* @return name of the method
*/
String name() default "";
String value() default "";
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
*/
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@GrpcMethod(type = MethodType.UNARY)
@GrpcMethod(MethodType.UNARY)
@Documented
@Inherited
public @interface Unary {
Expand All @@ -41,5 +41,5 @@
*
* @return name of the method
*/
String name() default "";
String value() default "";
}
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ boolean isRequiredMethodType(AnnotatedMethod method) {
}

GrpcMethod annotation = method.firstAnnotationOrMetaAnnotation(GrpcMethod.class);
return annotation != null && methodType.equals(annotation.type());
return annotation != null && methodType.equals(annotation.value());
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,32 @@ public boolean isAnnotatedService() {
return annotatedServiceClass.isAnnotationPresent(Grpc.class);
}

/**
* Determine the name to use from the method.
* <p>
* If the method is annotated with {@link GrpcMethod} or an annotation that is annotated with
* {@link GrpcMethod}, then attempt to determine the method name from the annotation. If unable,
* use the actual method name.
*
* @param method the annotated method
* @param annotation the method type annotation
* @return the value to use for the method name
*/
public static String determineMethodName(AnnotatedMethod method, GrpcMethod annotation) {
Annotation actualAnnotation = method.annotationsWithMetaAnnotation(GrpcMethod.class)
.findFirst()
.orElse(annotation);

String name = nameFromMember(actualAnnotation, "value"); // @GrpcMethod is meta annotation
if (name == null || name.trim().isEmpty()) {
name = nameFromMember(actualAnnotation, "name"); // @GrpcMethod is actual annotation
}
if (name == null || name.trim().isEmpty()) {
name = method.method().getName();
}
return name;
}

/**
* Obtain the service class.
* @return the service class
Expand Down Expand Up @@ -177,7 +203,7 @@ protected String determineServiceName(Class<?> annotatedClass) {
String name = null;

if (serviceAnnotation != null) {
name = serviceAnnotation.name().trim();
name = serviceAnnotation.value().trim();
}

if (name == null || name.trim().isEmpty()) {
Expand All @@ -188,38 +214,22 @@ protected String determineServiceName(Class<?> annotatedClass) {
}

/**
* Determine the name to use from the method.
* <p>
* If the method is annotated with {@link GrpcMethod} then use the value of {@link GrpcMethod#name()}
* unless {@link GrpcMethod#name()} returns empty string, in which case use the actual method name.
* <p>
* If the method is annotated with an annotation that has the meta-annotation {@link GrpcMethod} then use
* the value of that annotation's {@code name()} method. If that annotation does not have a {@code name()}
* method or the {@code name()} method return empty string then use the actual method name.
* Get method from annotation member if present and of type {@link String}.
*
* @param method the annotated method
* @param annotation the method type annotation
* @return the value to use for the method name
* @param annotation the annotation
* @param member the annotation method to call
* @return method name or {@code null}
*/
public static String determineMethodName(AnnotatedMethod method, GrpcMethod annotation) {
Annotation actualAnnotation = method.annotationsWithMetaAnnotation(GrpcMethod.class)
.findFirst()
.orElse(annotation);

String name = null;
private static String nameFromMember(Annotation annotation, String member) {
try {
Method m = actualAnnotation.annotationType().getMethod("name");
name = (String) m.invoke(actualAnnotation);
Method m = annotation.annotationType().getMethod(member);
Object value = m.invoke(annotation);
return value instanceof String s ? s : null;
} catch (NoSuchMethodException e) {
LOGGER.log(Level.WARNING, () -> String.format("Annotation %s has no name() method", actualAnnotation));
LOGGER.log(Level.WARNING, () -> String.format("Annotation %s has no name() method", annotation));
} catch (IllegalAccessException | InvocationTargetException e) {
LOGGER.log(Level.WARNING, () -> String.format("Error calling name() method on annotation %s", actualAnnotation), e);
LOGGER.log(Level.WARNING, () -> String.format("Error calling name() method on annotation %s", annotation), e);
}

if (name == null || name.trim().isEmpty()) {
name = method.method().getName();
}

return name;
return null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import io.helidon.microprofile.grpc.api.GrpcMethod;
import io.helidon.microprofile.grpc.api.ServerStreaming;
import io.helidon.microprofile.grpc.api.Unary;

/**
* A model of an annotated gRPC method.
*/
Expand Down Expand Up @@ -110,9 +111,9 @@ private AnnotatedMethod(Method method) {
* @throws java.lang.NullPointerException if the method parameter is null
* @return an {@link AnnotatedMethod} instance representing the Java method
*/
public static AnnotatedMethod create(Method method) {
return new AnnotatedMethod(Objects.requireNonNull(method));
}
public static AnnotatedMethod create(Method method) {
return new AnnotatedMethod(Objects.requireNonNull(method));
}

/**
* Get the underlying Java method.
Expand Down Expand Up @@ -214,8 +215,8 @@ public Class<?> returnType() {
*/
public <T extends Annotation> Stream<T> metaMethodAnnotations(Class<T> annotation) {
return Arrays.stream(methodAnnotations)
.map(ann -> ann.annotationType().getAnnotation(annotation))
.filter(Objects::nonNull);
.map(ann -> ann.annotationType().getAnnotation(annotation))
.filter(Objects::nonNull);
}

/**
Expand Down Expand Up @@ -246,8 +247,8 @@ public <T extends Annotation> T firstAnnotationOrMetaAnnotation(Class<T> type) {
*/
public <T extends Annotation> Stream<T> annotationOrMetaAnnotation(Class<T> type) {
return Arrays.stream(methodAnnotations)
.map(ann -> annotationOrMetaAnnotation(type, ann))
.filter(Objects::nonNull);
.map(ann -> annotationOrMetaAnnotation(type, ann))
.filter(Objects::nonNull);
}

/**
Expand All @@ -259,7 +260,7 @@ public <T extends Annotation> Stream<T> annotationOrMetaAnnotation(Class<T> type
*/
public Stream<Annotation> annotationsWithMetaAnnotation(Class<? extends Annotation> type) {
return Arrays.stream(methodAnnotations)
.filter(ann -> ann.annotationType().isAnnotationPresent(type));
.filter(ann -> ann.annotationType().isAnnotationPresent(type));
}

@SuppressWarnings("unchecked")
Expand Down Expand Up @@ -303,7 +304,7 @@ public String toString() {
*
* @param declaredMethod the declared method
* @param actualMethod the method that the declared method overrides
* @return an array of merged annotations
* @return an array of merged annotations
*/
private static Annotation[] mergeMethodAnnotations(Method declaredMethod, Method actualMethod) {
List<Annotation> list = new ArrayList<>(Arrays.asList(declaredMethod.getAnnotations()));
Expand All @@ -323,7 +324,7 @@ private static Annotation[] mergeMethodAnnotations(Method declaredMethod, Method
*
* @param declaredMethod the declared method
* @param actualMethod the method that the declared method overrides
* @return an array of merged annotations
* @return an array of merged annotations
*/
private static Annotation[][] mergeParameterAnnotations(Method declaredMethod, Method actualMethod) {
Annotation[][] methodParamAnnotations = declaredMethod.getParameterAnnotations();
Expand Down Expand Up @@ -368,7 +369,7 @@ private static boolean annotationNotInList(Class<? extends Annotation> type, Lis
* class hierarchy before searching the implemented interfaces.
*
* @param declaredMethod the declared method
* @return the actual annotated gRPC method or the declared method if no
* @return the actual annotated gRPC method or the declared method if no
* method in the class hierarchy is annotated
*/
private static Method findAnnotatedMethod(Method declaredMethod) {
Expand All @@ -391,7 +392,7 @@ private static Method findAnnotatedMethod(Method declaredMethod) {
*
* @param declaringClass the Class declaring the method
* @param declaredMethod the declared method
* @return the actual annotated gRPC method or the declared method if no
* @return the actual annotated gRPC method or the declared method if no
* method in the class hierarchy is annotated
*/
private static Method findAnnotatedMethod(Class<?> declaringClass, Method declaredMethod) {
Expand Down Expand Up @@ -464,7 +465,7 @@ private static boolean hasMetaMethodAnnotations(Method method) {
*/
private static boolean hasMetaAnnotation(Method method, Class<? extends Annotation> type) {
return Arrays.stream(method.getAnnotations())
.anyMatch(a -> a.annotationType().isAnnotationPresent(type));
.anyMatch(a -> a.annotationType().isAnnotationPresent(type));
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -179,15 +179,15 @@ public void shouldMergeAnnotations() throws Exception {
@Grpc
public static class GrandParent {

@GrpcMethod(type = MethodDescriptor.MethodType.UNARY)
@GrpcMethod(MethodDescriptor.MethodType.UNARY)
@Inject
public void one() {
}

public void two() {
}

@GrpcMethod(type = MethodDescriptor.MethodType.UNARY)
@GrpcMethod(MethodDescriptor.MethodType.UNARY)
public void three() {
}
}
Expand All @@ -205,12 +205,12 @@ public void one() {
public void two() {
}

@GrpcMethod(type = MethodDescriptor.MethodType.UNARY)
@GrpcMethod(MethodDescriptor.MethodType.UNARY)
@Override
public void three() {
}

@GrpcMethod(type = MethodDescriptor.MethodType.UNARY)
@GrpcMethod(MethodDescriptor.MethodType.UNARY)
public void four() {
}

Expand Down Expand Up @@ -242,26 +242,26 @@ public void seven() {
}

public interface InterfaceOne {
@GrpcMethod(type = MethodDescriptor.MethodType.UNARY)
@GrpcMethod(MethodDescriptor.MethodType.UNARY)
void three();

@GrpcMethod(type = MethodDescriptor.MethodType.UNARY)
@GrpcMethod(MethodDescriptor.MethodType.UNARY)
void six();
}

public interface InterfaceTwo {
@GrpcMethod(type = MethodDescriptor.MethodType.UNARY)
@GrpcMethod(MethodDescriptor.MethodType.UNARY)
void three();
}

public interface InterfaceThree
extends InterfaceOne {
@GrpcMethod(type = MethodDescriptor.MethodType.UNARY)
@GrpcMethod(MethodDescriptor.MethodType.UNARY)
void six();
}

public interface InterfaceFour {
@GrpcMethod(type = MethodDescriptor.MethodType.UNARY)
@GrpcMethod(MethodDescriptor.MethodType.UNARY)
void seven();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ private void addServiceMethod(GrpcServiceDescriptor.Builder builder, AnnotatedMe
responseType,
interceptors);

switch (annotation.type()) {
switch (annotation.value()) {
case UNARY:
builder.unary(name, handler, configurer);
break;
Expand All @@ -218,7 +218,7 @@ private void addServiceMethod(GrpcServiceDescriptor.Builder builder, AnnotatedMe
break;
case UNKNOWN:
default:
LOGGER.log(Level.ERROR, () -> "Unrecognized method type " + annotation.type());
LOGGER.log(Level.ERROR, () -> "Unrecognized method type " + annotation.value());
}
}

Expand Down
Loading

0 comments on commit 4c819ed

Please sign in to comment.